Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Iterate through nested data with foreach in Terraform

I know – there was a topic with an explanation of how to solve this with flatten function. Help me understand how it works, please.

So, I’m setting up terraform with the vSphere provider. I want to achieve a goal when the network data source is configured dynamically from virtual machine’s settings.

I have the variable "virtual_machines" in vars.tf with VM setting:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

variable "virtual_machines" {
  type = map(object({
        template        = string
        host_name       = string
        domain_name     = string
        num_cpus        = number
        memory          = number
        dns_server_list = list(string)
        gateway         = string
        interfaces      = list(object({
          network = string
          ipv4_address = string
          ipv4_netmask = string
        }))
  }))
}

And there are its values in vm.auto.rfvars:

virtual_machines = {
  "gw" = {
    template = "cent7_template"
    host_name = "gw"
        domain_name = "contoso.com"
    dns_server_list = ["8.8.8.8", "8.8.4.4"]

    num_cpus = 2
    memory = 2048
    interfaces = [
          {
            ipv4_address = "192.168.5.240"
        ipv4_netmask = "24"
            network = "VM Network"
      },
      {
        ipv4_address = "192.168.4.241"
            ipv4_netmask = "24"
            network = "VM Network2"
      }
    ]

    gateway = "192.168.5.251"

  }
}

In my main file there are sphere interfaces:

data "vsphere_network" "interfaces" {
  for_each      = networks.local
  name          = each.value.network
  datacenter_id = data.vsphere_datacenter.dc.id
}

I have big trouble understanding how to make this local var to get "network" value from "interfaces" object list.

There is my try:

locals {
  networks = flatten([
    for vm_key, objects in var.virtual_machines : [
      for interface in objects.interfaces : {
          network           = interface.network
          ipv4_address = interface.ipv4_address
          ipv4_netmask  = interface.ipv4_netmask
      }

  ])
}

After running this code I got the error:

     │ local.networks is tuple with 2 elements
│
│ The given "for_each" argument value is unsuitable: the "for_each" argument must be a map, or set of
│ strings, and you have provided a value of type tuple.

Help please understand how to iterate to this value please. Big thanx!

>Solution :

Your local.networks is a list of maps. You can’t use such a data structure with for_each. But you can use a map of maps. The easiest way to convert it to a map of maps is:

data "vsphere_network" "interfaces" {
  for_each      = {for idx, val in local.networks: idx => val}
  name          = each.value.network
  datacenter_id = data.vsphere_datacenter.dc.id
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading