Trouble accessing elements of a list

I have a local value vm_ids defined as follows:
locals {
vm_ids = {
for idx, data in var.affinity_rules: idx=> [
for value in data.vm_names: value ]
}
}

After the local value is loaded with input variable values, it looks like this:

PS C:\RM_LocalRepos\terraform> terraform console

local.vm_ids
{
“ie1l-afr-01” = [
“ie1ladc001x”,
“ie1ladc002x”,
]
“us0l-afr-01” = [
“us0ladc001x”,
“us0ladc002x”,
]
“us6l-afr-01” = [
“us6ladc001x”,
“us6ladc002x”,
]
}

I have not figured out the syntax to access the elements (vm names) of the lists individually in a for_each or for loop.
My goal is to feed a data source block with the vm_names in order to extract vm_ids.

Any help would be appreciated.

Thanks

Hi @roy.madden,

I’m not sure I fully understand your goal, but I can at least directly answer the question of how to access the list elements, and then perhaps that will reveal another question we can talk about. :grinning:

The syntax for accessing one element from one of your lists would be like this:

local.vm_ids["ie1l-afr-01"][0]

The first set of brackets contains one of the keys from your map, while the second one contains one of the list indices.

However, I’m not sure how to relate that to your question about data sources, so I’m betting I probably haven’t actually answered your question. If you can share a larger example of what you tried and what happened when you tried it I might be able to give a more relevant answer. Thanks!

Hi @apparentlymart,

Thank you so much for reaching out. I realized after I posted the question that I should have given more information.

INPUT VARIABLE

variable rules {
  type = map(object({
    datacenter = string
    cluster    = string
    vm_names   = list(string)
  }))
  default = {
    rule001 = {
      datacenter = "DC1"
      cluster    = "DC1CLUSTER1" 
      vm_names   = [
                   "dc1vm01",
                   "dc1vm02"]
    }
    rule002 = {
      datacenter = "DC1"
      cluster    = "DC1CLUSTER2" 
      vm_names   = [
                   "dc1vm03",
                   "dc1vm04"]
    }
  }  
}

LOCAL VALUES

  vms_map = flatten([
    for rule_key, rule_value in var.rules : {
      for name_key, name_data in rule_value.vm_names : name_key =>{
          rule        = rule_key
          name        = name_data
          datacenter  = rule_value.datacenter
          cluster     = rule_value.cluster
      }
    }  
  ])

DATA RESOURCE BLOCK

data "vsphere_virtual_machine" "vms" {
    for_each = local.vms_map 
        name          = each.value.name
        datacenter_id = each.value.datacenter       
}

OBJECTIVE
Access resource information (specifically the vm_id) via the data resource block or all VMs in the input variable Rules.

ACTIVITY
At first I attempted to use for_each in the data block directly into the input variable and ran across nesting issues. Other posts suggested flattening the data in a local value, so I set up vms_map but I get an Invalid for_each argument error saying the argument must be a map or set of strings.

Next I changed the for_each = local.vms_map to for_each = toset(local.vms_map)
I get the same error.

Then I tried using a different local value:

  vm_names = {
    for idx, data in var.rules: idx=> [ 
      for value in data.vm_names: value
    ]
  }

and adjusted the data block:

data "vsphere_virtual_machine" "vms" {
    for_each = { for key, vmname in local.vm_names : key => vmname}
        name          = each.value.vmname
        datacenter_id = each.value.datacenter       
}

This results in an unsupported attribute error - each.value is a tuple and it doesn’t recognize vmname.

Ultimately I need to fetch the vm_ids and put them back into a list of string to use for input to a resource block. There needs to be one list per Rule.

I’m new to Terraform (2-3 months) and not making any progress on this.
Hope I haven’t bombarded you with excess information, but I sincerely appreciate your help.

Thanks