how to iterate list of map objects in terraform

113 Views Asked by At

I am trying write a for loop to get the disks map object for below terraform code. However I am getting "This object does not have an attribute named "disks" " error at the time of terraform plan.

locals {
  image = {
    nodes = {
      vm1 = {
        name = "vm1"
        vm_num = "1"
        networks = {
          nic1 = {
            name = "vm1-nic1"
            subnet = "subnet1"
          }
          nic2 = {
            name = "vm1-nic2"
            subnet = "subnet2"
          }
        }
      },
      vm2 = {
        name = "vm2"
        vm_num = "2"
        networks = {
          nic1 = {
            name = "vm2-nic1"
            subnet = "subnet2"

          }
          nic2 = {
            name = "vm2-nic2"
            subnet = "subnet2"

          }
        }
        disks ={
          disk1 = {
            "lun" = "0"
            "size" = "1024"
          },
          disk2 = {
            "lun" = "1"
            "size" = "1024"
          }
        }
      }
    }
  }
}

output "iterate-networks" {
  value = {
    for_each = { for vm in flatten([for vm_name, vm  in local.image.nodes : [for nic_name, nic in vm.networks : { vm_number = vm.vm_num, vm_name = vm_name, nic_name = nic_name, nic_value = nic.name, subnet_name = nic.subnet }]]) : "${vm.vm_name}-${vm.nic_name}" => vm }
  }
}


output "iterate-disks" {
  value = {
    for_each = { for vm in flatten([for vm_name, vm  in local.image.nodes : [for disk_name, disk in vm.disks : { vm_number = vm.vm_num, disk_name= disk_name, disk_lun = disk.lun, disk_size = disk.size }]]) : "${vm.vm_name}-${vm.num}" => vm }
  }
}

Error while terraform plan:

Error: Unsupported attribute
    │ 
    │   on provider.tf line 136, in output "iterate-disks":
    │  136:     for_each = { for vm in flatten([for vm_name, vm  in local.image.nodes : [for disk_name, disk in vm.disks : { vm_number = vm.vm_num, disk_name= disk_name, disk_lun = disk.lun, disk_size = disk.size }]]) : "${vm.vm_name}-${vm.nic_name}" => vm }
    │ 
    │ This object does not have an attribute named "disks".

can someone throw some light on the fix ? Thank You in advance.

1

There are 1 best solutions below

0
On BEST ANSWER

disks is only in vm2, not in vm1, so you have to check for the lack of disks in each iteration. You can do this using lookup as follows:

output "iterate-disks" {
  value = {
    for_each = { 
      for vm in flatten([
          for vm_name, vm  in local.image.nodes : [
              for disk_name, disk in lookup(vm, "discs", {}) : { 
                  vm_number = vm.vm_num
                  disk_name= disk_name
                  disk_lun = disk.lun
                  disk_size = disk.size 
              }
      ]
      ]
    ) : "${vm.vm_name}-${vm.nic_name}" => vm }
  }
}