This post explains how to output a resource in Terraform when its creation is controlled using the count parameter.
Introduction
In Terraform, the count parameter lets you control how many instances of a resource are created.
By using this, you can conditionally create resources based on external input—often by switching between 0 and 1.
resource "aws_ecr_repository" "this" { name = "example" count = var.create ? 1 : 0 }
However, when trying to output a resource controlled with count, it's not immediately obvious how to write it:
output "aws_ecr_repository" { value = aws_ecr_repository.this[0] ## ??? }
This post walks through the ways to handle this.
Note: This article was translated from my original post.
Outputting Resources Controlled by count
The source code used for this post is available here:
Method 1: Use the one Function
variable "create" { description = "Controls if ECR resources should be created" type = bool default = true } resource "aws_ecr_repository" "this" { name = "example" count = var.create ? 1 : 0 } output "aws_ecr_repository" { value = one(aws_ecr_repository.this[*]) }
The one function works with collections of either 0 or 1 element and returns the element if it exists.
This lets you output the resource only if it was created. If not, null will be returned.
See also: Understanding one() Function in Terraform - BioErrorLog Tech Blog (en)
Example behavior:
If the resource is created, the output will contain the full resource object:
Outputs: aws_ecr_repository = { "arn" = "arn:aws:ecr:ap-northeast-1:<account_id>:repository/create_example_ecr" "encryption_configuration" = tolist([ { "encryption_type" = "AES256" "kms_key" = "" }, ]) "force_delete" = tobool(null) "id" = "create_example_ecr" "image_scanning_configuration" = tolist([ { "scan_on_push" = false }, ]) "image_tag_mutability" = "MUTABLE" "name" = "create_example_ecr" "registry_id" = "<account_id>" "repository_url" = "<account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/create_example_ecr" "tags" = tomap(null) /* of string */ "tags_all" = tomap({}) "timeouts" = null /* object */ }
If the resource is not created, the output becomes null:
Changes to Outputs: - aws_ecr_repository = { - arn = "arn:aws:ecr:ap-northeast-1:<account_id>:repository/create_example_ecr" - encryption_configuration = [ - { - encryption_type = "AES256" - kms_key = "" }, ] - force_delete = null - id = "create_example_ecr" - image_scanning_configuration = [ - { - scan_on_push = false }, ] - image_tag_mutability = "MUTABLE" - name = "create_example_ecr" - registry_id = "<account_id>" - repository_url = "<account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/create_example_ecr" - tags = null - tags_all = {} - timeouts = null } -> null
Method 2: Use the try Function
variable "create" { description = "Controls if ECR resources should be created" type = bool default = true } resource "aws_ecr_repository" "this" { name = "example" count = var.create ? 1 : 0 } output "aws_ecr_repository" { value = try(aws_ecr_repository.this[0], {}) }
The try function returns the first argument if it's valid, otherwise returns the second one.
In this case, if the resource is created, it will be returned. If not (and accessing aws_ecr_repository.this[0] fails), it falls back to the second argument—an empty object {}.
Example behavior:
If the resource is created:
Outputs: aws_ecr_repository = { "arn" = "arn:aws:ecr:ap-northeast-1:<account_id>:repository/create_example_ecr" "encryption_configuration" = tolist([ { "encryption_type" = "AES256" "kms_key" = "" }, ]) "force_delete" = tobool(null) "id" = "create_example_ecr" "image_scanning_configuration" = tolist([ { "scan_on_push" = false }, ]) "image_tag_mutability" = "MUTABLE" "name" = "create_example_ecr" "registry_id" = "<account_id>" "repository_url" = "<account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/create_example_ecr" "tags" = tomap(null) /* of string */ "tags_all" = tomap({}) "timeouts" = null /* object */ }
If not created:
Outputs: aws_ecr_repository = {}
Conclusion
This post explained how to output resources that are conditionally created using count in Terraform.
By using functions like one and try, you can write cleaner and more reliable Terraform code.
Hope this helps someone out there.
[Related Articles]
References
- Terraform outputs with count.index - Terraform - HashiCorp Discuss
- https://developer.hashicorp.com/terraform/language/functions/one
- https://developer.hashicorp.com/terraform/language/functions/try
- GitHub - terraform-aws-modules/terraform-aws-eks: Terraform module to create Amazon Elastic Kubernetes (EKS) resources 🇺🇦
- Terraform outputs for resources with count - Stack Overflow