skip to Main Content

I’m currently facing an issue in my Terraform configuration, specifically with the "Invalid for_each argument" error. I have a configuration that involves creating AWS Load Balancer target groups and attachments. I’m using a local.c variable with keys derived from resource attributes, and it seems that Terraform is unable to determine the full set of keys during the planning phase.

As I am a new to Terraform. Please help me with this problem. What will be the better solution?
This is my main.tf an variables.tf

resource "aws_lb_target_group" "tg" {
  # count    = length(var.target-port)
  # name     = "${var.targetgroup-name}-${var.target-port[count.index]}"
  # port     = var.target-port[count.index]
  for_each = toset(var.target-port)
  name     = "${var.targetgroup-name}-${each.value}"
  port     = each.value
  protocol = "HTTP"
  vpc_id   = "vpc-571f3830"
}
locals {
  a = {for anr in aws_lb_target_group.tg : anr.arn => anr}
  
}
locals {
  b = {for p in setproduct(var.target, var.target-port):
                "${p[0]}-${p[1]}" => p}
                
}

locals {
  c = {for c in setproduct(local.a, local.b):
                "${c[0]}-${c[1]}" => c}
                
}

resource "aws_lb_target_group_attachment" "tg-attach" { 
  for_each         = local.c
  target_group_arn = each.value[0]
  target_id        = each.value[1]
  port             = each.value[2]
  depends_on = [ aws_lb_target_group.tg]
}

variables.tf

variable "target-port" {
    type = set(string)
    default = [ "81" , "82" , "83" , "84" , "85" ]
  
}

variable "listenerport" {
    type = set(string)
    default = [ "81" , "82" , "83" , "84" , "85" ]
}

variable "target" {
      type = set(string)
      default = ["i-08990bdd2df0" , "i-0d3b9802d7ac"]
}

variable "targetgroup-name" {
    default = "terraform-alb-tg"
}

The error I faced was

Error: Invalid for_each argument
│
│   on main.tf line 47, in resource "aws_lb_target_group_attachment" "tg-attach":
│   47:   for_each         = local.c
│     ├────────────────
│     │ local.c will be known only after apply
│
│ The "for_each" map includes keys derived from resource attributes that cannot be determined until apply, and so     
│ Terraform cannot determine the full set of keys that will identify the instances of this resource.
│
│ When working with unknown values in for_each, it's better to define the map keys statically in your configuration   
│ and place apply-time results only in the map values.
│
│ Alternatively, you could use the -target planning option to first apply only the resources that the for_each value  
│ depends on, and then apply a second time to fully converge.

The result I need is simple. I want to create Targetgroups with these ports and attachment will be these 2 ec2 instances id.

2

Answers


  1. The error is clear, local.c will be known after apply, which is forbidden in TF when creating resources using for_each or count. You must ensure that all your local variables are known at plan time.

    You have to deploy your resources in two stages., First the resources that are used for local.c, and then everything else then depends on those resource.

    Login or Signup to reply.
  2. The error message has more details giving clues on how to solve the problem too..

    • -target option helps you create independent resources in the first go & followed by dependent resources. Doesn’t scale well with CI/CD as you can’t expect all the resources you are going to create with two-pronged approaches.
    • Another approach as said in the error message is When working with unknown values in for_each, it's better to define the map keys statically in your configuration │ and place apply-time results only in the map values.

    The 2nd approach is what I use heavily. But you have to redesign your tf configuration files accordingly with deterministic names (not using random ones).

    In your case, rather relying directly on aws_lb_target_group.tg output you predict the output would be something like a static arn:aws:elasticloadbalancing:us-west-2:187416307283:targetgroup/app-front-end/20cfe21448b66314. With this, you could construct your local variables
    & use in dependent resources with depends_on meta-argument (it is a must otherwise you hit race conditions).

    If you would like to know more about this constraint, read this comment.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search