Mahs
Mahs

Reputation: 33

Terraform Nested Loops 1.12

I am trying to implement nested for loops using Terraform 1.12 in order to loop through Azure users, each of which can have one or more values attached. The variable used to represent this list is of type map(list(string)) and looks something like this:

VirtualMachine = {
  app = {
    Size = "Standard_B4ms"
    Disks = {
      OS = {
        Cache = "ReadWrite"
        Size  = 128
        Type  = "Premium_LRS"
      }
      Data = {
        Cache = "ReadWrite"
        Size  = 64
        Type  = "Premium_LRS" 
      }
    }
    Image = {
      Publisher = "MicrosoftWindowsServer"
      Offer     = "WindowsServer"
      Sku       = "2022-datacenter-azure-edition"
      Version   = "latest"
    }
  }
}

I am attempting construct that list and store it in a local variable like so, where

  vmDisks = {
    for key, value in flatten([
      for vmKey, vm in var.VirtualMachine : [
        for diskKey, disk in vm.Disks.Data : {
          VmId   = vmKey
          DiskId = diskKey
          Cache  = disk.Cache
          Type   = disk.Type
          Size   = disk.Size
          Lun    = 1 + index(keys(vm.Disks.Data), diskKey)
      }
    ]
    if contains(keys(vm.Disks), "Data")
    ]) : "${value.VmId}.${value.DiskId}" => value
  }

However, I am getting errors when attempting to access the values in that nested list.

Error: Unsupported attribute │ │ on locals.tf line 48, in locals: │ 48: Cache = disk.Cache │ │ Can't access attributes on a primitive-typed value (string)

can you help me here?

I have tried to pass diskKey[0] with the reference local.association-list[count.index][0] and fails at terraform plan stage

Upvotes: 0

Views: 340

Answers (1)

Helder Sepulveda
Helder Sepulveda

Reputation: 17594

In your inner loop:
for diskKey, disk in vm.Disks.Data
The disk is not what you think, here is an example:

locals {
  vmDisks = {
    for key, value in flatten([
      for vmKey, vm in var.VirtualMachine : [
        for diskKey, disk in vm.Disks.Data : {
          VmId   = vmKey
          DiskId = diskKey
          disk  = disk
          Lun    = 1 + index(keys(vm.Disks.Data), diskKey)
        }
      ]
      if contains(keys(vm.Disks), "Data")
    ]) : "${value.VmId}.${value.DiskId}" => value
  }
}

output "test" {
    value = local.vmDisks
}

variable "VirtualMachine" {
  default = {
    app = {
      Size = "Standard_B4ms"
      Disks = {
        OS = {
          Cache = "ReadWrite"
          Size  = 128
          Type  = "Premium_LRS"
        }
        Data = {
          Cache = "ReadWrite"
          Size  = 64
          Type  = "Premium_LRS"
        }
      }
      Image = {
        Publisher = "MicrosoftWindowsServer"
        Offer     = "WindowsServer"
        Sku       = "2022-datacenter-azure-edition"
        Version   = "latest"
      }
    }
  }
}

the output of that is this:

  + test = {
      + app.Cache = {
          + DiskId = "Cache"
          + Lun    = 1
          + VmId   = "app"
          + disk   = "ReadWrite"
        }
      + app.Size  = {
          + DiskId = "Size"
          + Lun    = 2
          + VmId   = "app"
          + disk   = 64
        }
      + app.Type  = {
          + DiskId = "Type"
          + Lun    = 3
          + VmId   = "app"
          + disk   = "Premium_LRS"
        }
    }

As you can see the disk is just a value not an object

Upvotes: 2

Related Questions