Terraform outputs with count.index

I’m trying to output a resource that has been created conditionally using count.

The code is:

resource "aws_route53_zone" "private" {
  count = (terraform.workspace == "prod") ? 1 : 0
  name  = "prod.example-infra.com"

  vpc {
    vpc_id = var.vpc_id
  }

  lifecycle {
    ignore_changes = [vpc]
  }
}

output "route53_private_prod" {
  value = aws_route53_zone.private[count.index].zone_id
}

So that I can refer to that output in another module: module.route53.route53_private_prod.

However, when applying those changes I get the following error:

Error: Reference to "count" in non-counted context
│ 
│   on modules/route53/outputs.tf line 2, in output "route53_private_prod":
│    2:   value = aws_route53_zone.private[count.index].zone_id
│ 
│ The "count" object can only be used in "module", "resource", and "data" blocks, and only when the "count" argument is set.

I’ve been trying to find a workaround for this but haven’t had any luck. Would appreciate it if you guys could help me out.

Hi @lpossamai,

The expression aws_route53_zone.private refers to a list of zero or one items, so in order to return a single ID in this output value you need to decide what the value ought to be in the case where there are no instances of the resource.

A common choice is to make it be null in that case, and so Terraform has a built-in function one to help deal with that situation in a concise way:

output "route53_private_prod" {
  value = one(aws_route53_zone.private[*].zone_id)
}

The expression above first uses the splat operator to transform the list of objects into a list of just zone_id values, which will also have either zero or one elements depending on the resource count.

The one function then deals with the two cases:

  • If the list has only one value, it’ll return that value.
  • If the list has no values, it’ll return null to represent the absense of a value.
6 Likes

Thanks a lot, @apparentlymart . It worked! :slight_smile: