Fantastic! You Sir are a wizard. This gets me almost there. Thank you so much!!! I am going to have to read this multiple times to understand it better. I do now have a better idea on how inverting the variable with nested config helped us access the data for the VM’s. I ended up bringing more of the data to the top in the locals variable that way so I could avoid the duplication of data in the results. For example each ${wlk}:${vmk}
contained both VM’s with config in the “workload” attribute below.
This below is working for me well with only one issue left I am guessing.
locals {
workload_vms = merge([
for wlk, wl in var.workloads_test : tomap({
for vmk, vm in wl.vms : "${wlk}:${vmk}" => {
hostname = vm.hostname
ipaddress = vm.ipaddress
#workload = wl
workload-name = wl.name
workload-tags = wl.tags
workload-subnet-address-prefix = wl.subnet-address-prefix
}
})
]...)
}
When I need to grab the subnet prefixes per workload I can continue to use the var.workload-test and when I need to use the VM information by workload I can use the local.workload_vms.
One issue I am running into is I have to use the same variable in the for_each of certain resources. For example when creating the NIC using the local.workload_vms which works great. However when I go to create a ASG I have to use var.workload-test or I end up with duplicate ASG based on there being multiple VM’s per workload.
So far that works however when I go to associate the ASG to the NIC it does not like the structure of how the ASG was created using the var.workloads-test.
Here is the error that I am getting:
Error: Invalid index
│
│ on ..\modules\compute-landing-zone\c8-virtual-machines-workload.tf line 42, in resource "azurerm_network_interface_application_security_group_association" "workload":
│ 42: application_security_group_id = azurerm_application_security_group.workload[each.key].id
│ ├────────────────
│ │ azurerm_application_security_group.workload is object with 2 attributes
│ │ each.key is "workload1:vm1"
│
│ The given key does not identify an element in this collection value.
╵
╷
│ Error: Invalid index
│
│ on ..\modules\compute-landing-zone\c8-virtual-machines-workload.tf line 42, in resource "azurerm_network_interface_application_security_group_association" "workload":
│ 42: application_security_group_id = azurerm_application_security_group.workload[each.key].id
│ ├────────────────
│ │ azurerm_application_security_group.workload is object with 2 attributes
│ │ each.key is "workload2:vm1"
│
│ The given key does not identify an element in this collection value.
╵
╷
│ Error: Invalid index
│
│ on ..\modules\compute-landing-zone\c8-virtual-machines-workload.tf line 42, in resource "azurerm_network_interface_application_security_group_association" "workload":
│ 42: application_security_group_id = azurerm_application_security_group.workload[each.key].id
│ ├────────────────
│ │ azurerm_application_security_group.workload is object with 2 attributes
│ │ each.key is "workload2:vm2"
│
│ The given key does not identify an element in this collection value.
╵
╷
│ Error: Invalid index
│
│ on ..\modules\compute-landing-zone\c8-virtual-machines-workload.tf line 42, in resource "azurerm_network_interface_application_security_group_association" "workload":
│ 42: application_security_group_id = azurerm_application_security_group.workload[each.key].id
│ ├────────────────
│ │ azurerm_application_security_group.workload is object with 2 attributes
│ │ each.key is "workload1:vm2"
│
│ The given key does not identify an element in this collection value.
Here is the code produces the error:
####-----[NIC]-----####
resource "azurerm_network_interface" "workload" {
provider = azurerm.Target-Subcription
for_each = local.workload_vms
name = "${each.value.hostname}-nic"
resource_group_name = one([for item in azurerm_resource_group.workload : item.name if can(regex("${each.value.workload-name}", item.name))])
location = one([for item in azurerm_resource_group.workload : item.location if can(regex("${each.value.workload-name}", item.name))])
enable_accelerated_networking = true
tags = merge(each.value.workload-tags, local.calculated-tags, local.function-vm-nic)
ip_configuration {
name = "internal"
#subnet_id = var.vm-subnet-id
subnet_id = one([for item in azurerm_subnet.workload : item.name if can(regex("${each.value.name}", item.id))])
private_ip_address_allocation = "Static"
private_ip_address = each.value.ipaddress
}
}
####-----[ASG]-----####
resource "azurerm_application_security_group" "workload" {
provider = azurerm.Target-Subcription
for_each = var.workloads-test
name = replace("${local.name-prefix-landing-zone}-asg", "${var.landing-zone}", "${each.value.workload-name}")
resource_group_name = one([for item in azurerm_resource_group.workload : item.name if can(regex("${each.value.workload-name}", item.name))])
location = one([for item in azurerm_resource_group.workload : item.location if can(regex("${each.value.workload-name}", item.name))])
tags = merge(each.value.workload-tags, local.calculated-tags, local.function-asg-nic)
}
####-----[ASG Associations]-----####
resource "azurerm_network_interface_application_security_group_association" "workload" {
provider = azurerm.Target-Subcription
for_each = local.workload_vms
network_interface_id = azurerm_network_interface.workload[each.key].id
application_security_group_id = azurerm_application_security_group.workload[each.key].id
}
Error when running plan:
is there a way to use var.workloads-test when creating the 1 ASG per workload and during the ASG Association drill down to the appropriate “application_security_group_id”
or
No error when running plan but duplicate ASG’s per Workload:
When I use local.workload_vms** in the for_each for the NIC’s, ASG’s and ASG associations the error goes away but I can see the ASG for each workload is being created multiple times (once for each VM). I am only running this in plan so I am guessing it would fail during apply.
When creating the ASG’s is there a way to scope the for_each to only 1 instance of each workload when looping through the VM’s in local.workload_vms so duplicate ASGs are not created per workload?
I am very grateful for your help and intend on paying it forward once I learn more. Do you know of any documentation out there that can help me learn the map structure for what the elements, keys and attributes are that we have been discussing when using a for_each? I have been looking but have not been able to find anything other than can break it down for me. For example the updated view I sent. Is Workload1 an element? workload is an attribute or a key? My some of these change based on type constraints. Either way the error at the moment is more important that my understanding of the structure. I am sure some of this will clear up as this is worked through.