简体   繁体   中英

Unable to loop over list using for_each

I want to reserve an IP and then use it. If I create a separate google_compute_address block for each IP, it works well. But since I want to make the code as dry and optimized as possible, I am learning how to loop and use for_each

My main.tf looks like this

module "nat" {
  source  = "../../modules/nat"

  reserved_ips = [
    {
      name = "gke-frontend-prod-lb"
      ip = "10.238.232.10"
    },
    {
      name = "gke-frontend-test-lb"
      ip = "10.238.232.11"
    }
  ]
} 

As you can see, I would like to form a list of reserved IPs having name and IP.

Now lets look at my module

My variables.tf looks like

variable "reserved_ips" {
  type        = list(object({
    name = string
    ip = string
  }))
  description = <<EOF
Reserved IPs.
EOF
}

And the main.tf of my module looks like

locals {
  ips = {
    # for_each needs transform to map
    for ip in var.reserved_ips : "${ip.name}" => "${ip.ip}"
  }
}


resource "google_compute_address" "gke-frontend" {
  for_each = local.ips

  name         = "${each.value.name}"
  subnetwork   = "mysubnet"
  address_type = "INTERNAL"
  address      = "${each.value.ip}"
}

But running the code gives me

Error: Unsupported attribute

  on ../../modules/nat/main.tf line 11, in resource "google_compute_address" "gke-frontend":
  11:   name         = "${each.value.name}"
    |----------------
    | each.value is "10.238.232.10"

This value does not have any attributes.


Error: Unsupported attribute

  on ../../modules/nat/main.tf line 11, in resource "google_compute_address" "gke-frontend":
  11:   name         = "${each.value.name}"
    |----------------
    | each.value is "10.238.232.11"

This value does not have any attributes.


Error: Unsupported attribute

  on ../../modules/nat/main.tf line 14, in resource "google_compute_address" "gke-frontend":
  14:   address      = "${each.value.ip}"
    |----------------
    | each.value is "10.238.232.10"

This value does not have any attributes.


Error: Unsupported attribute

  on ../../modules/nat/main.tf line 14, in resource "google_compute_address" "gke-frontend":
  14:   address      = "${each.value.ip}"
    |----------------
    | each.value is "10.238.232.11"

This value does not have any attributes.

Im confused as to what am I missing here exactly.

The issue is that your ips local converts the list to a map(string) (ie a map with string values)

locals {
  ips = {
    # for_each needs transform to map
    for ip in var.reserved_ips : "${ip.name}" => "${ip.ip}"
  }
}

Notice that on the right-side of => you have "${ip.ip}" .

When for_each loops over a map it assigns each.key to each key (a string ) and each.value to each corresponding value in the map (in this case "${ip.ip} is also a string ).

So, I think what you want in this case is something like the following

  # ...
  name         = each.key
  # ...
  address      = each.value
  # ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM