13

I am using Terraform v0.12.26 and set up and aws_alb_target_group as:

resource "aws_alb_target_group" "my-group" {
  count = "${length(local.target_groups)}"
  name = "${var.namespace}-my-group-${
    element(local.target_groups, count.index)
  }"

  port     = 8081
  protocol = "HTTP"
  vpc_id   = var.vpc_id

  health_check {
    healthy_threshold   = var.health_check_healthy_threshold
    unhealthy_threshold = var.health_check_unhealthy_threshold
    timeout             = var.health_check_timeout
    interval            = var.health_check_interval
    path                = var.path
  }

  tags = {
    Name = var.namespace
  }

  lifecycle {
    create_before_destroy = true
  }
}

The locals look like:

locals {
  target_groups = [
    "green",
    "blue",
  ]
}

When I run terraform apply it returns the following error:

Error: Missing resource instance key

  on ../../modules/aws_alb/outputs.tf line 3, in output "target_groups_arn":
   3:     aws_alb_target_group.http.arn,

Because aws_alb_target_group.http has "count" set, its attributes must be
accessed on specific instances.

For example, to correlate with indices of a referring resource, use:
    aws_alb_target_group.http[count.index]

I followed this implementation

Any idea how to fix it?

Output

output "target_groups_arn" {
  value = [
    aws_alb_target_group.http.arn,
  ]
}
mrc
  • 2,845
  • 8
  • 39
  • 73
  • 1
    You haven't included the `output` code here which is the bit that's erroring. But it's telling you that you're referring to a resource with count as if it's singular. You need to either use a splat or an index. – ydaetskcoR Jun 17 '20 at 16:45
  • @ydaetskcoR I just added the output code. What do you mean with "you're referring to a resource with count as if it's singular. You need to either use a splat or an index." – mrc Jun 17 '20 at 20:52

1 Answers1

23

Since aws_alb_target_group.http is a counted resource you'll need to reference specific instances by index or all of them as a list with [*] (aka Splat Expressions) as follows:

output "target_groups_arn" {
  value = aws_alb_target_group.http[*].arn,
}

The target_groups_arn output will be a list of the TG ARNs.

Alain O'Dea
  • 21,033
  • 1
  • 58
  • 84
  • 1
    My pleasure, @Maik ! I am glad your problem is solved. – Alain O'Dea Jun 18 '20 at 10:14
  • 4
    If your count parameter only provisions one instance, you may want to use `[0]` instead of `[*]` as you are getting this error --> "arn is tuple with 1 element" – bongoSLAP Mar 14 '22 at 16:33
  • @bongoSLAP where do you see that error mentioning a tuple with 1 element? aws_alb_target_group.http is a counted resource with as many instances as there are target groups. There is nothing I can see to suggest that count is always 1 here. Your suggestion could lead to errors. – Alain O'Dea Mar 17 '22 at 00:49
  • 4
    I understand. Sometimes count is used with a ternary operator and a boolean variable to conditionally provision/destroy a single resource: `count = var.enable_resource ? 1 : 0` in this case your answer provided would give the error stated in my previous comment. – bongoSLAP Mar 17 '22 at 14:25
  • 2
    The situation you describe isn't in the question, so your comment is off-topic and creates confusion. – Alain O'Dea Mar 18 '22 at 20:31
  • 1
    I'm in the scenario bongoSLAP referred to and found this answer high up in a Google search. Using `0` instead of `*` saved me a bit of trouble. I found his comment here helpful. Thanks, @bongoSLAP. – O'Shaughnessy Evans Nov 10 '22 at 17:08
  • 1
    I disagree, it was useful to me and more context on usage of the count is always useful. Thanks @bongoSLAP – Twin322 Jul 26 '23 at 05:41