Terraform创建Azure NIC与ASG关联时索引无效问题求助
Terraform Azure NIC与应用安全组(ASG)关联索引错误修复
问题说明
使用Terraform创建Azure网络接口(NIC)与应用安全组(ASG)关联时,现有代码中nic_asg_associations本地值未保留NIC的唯一标识键,且azurerm_network_interface_application_security_group_association资源的索引引用逻辑错误,导致执行时抛出无效索引错误,无法匹配到已创建的NIC资源。
错误根源
nic_asg_associations仅提取了nic_name和asg_id,丢失了NIC资源的唯一键(格式为${vm.vm_name}-${nic.nic_name},如app1_node1-nic1)- 关联资源的
for_each键构造错误,使用了nic_name|asg_id,与NIC资源的键不匹配 - 引用NIC资源时使用了错误的索引值,未对应到NIC资源的实际键
修正后的代码实现
修正nic_asg_associations本地值
保留NIC的唯一键,确保每个ASG关联项能关联到正确的NIC:
locals { all_nics = { for vm in flatten([ for vm_name, vm in var.virtual_machines: [ for nic_name, nic in vm.networks : { vm_number = vm.vm_num, vm_name = vm_name, nic_name = nic_name, subnet_value = nic.subnet, nic_name_value = nic.nic_name asg_ids = nic.asg_ids } ] ]) : "${vm.vm_name}-${vm.nic_name}" => vm } # 修正:保留NIC资源的唯一键,用于关联NIC资源 nic_asg_associations = flatten([ for nic_key, nic in local.all_nics : [ for asg_id in nic.asg_ids : { nic_key = nic_key, # 保留NIC资源的唯一键 asg_id = asg_id } ] ]) }
修正azurerm_network_interface_application_security_group_association资源
使用包含NIC唯一键的nic_asg_associations构造for_each,并正确引用NIC资源:
resource "azurerm_network_interface_application_security_group_association" "nic_asg_association" { # 用nic_key和asg_id组合成唯一键,避免重复 for_each = { for assoc in local.nic_asg_associations : "${assoc.nic_key}|${assoc.asg_id}" => assoc } # 通过nic_key正确引用NIC资源 network_interface_id = azurerm_network_interface.nic[each.value.nic_key].id application_security_group_id = each.value.asg_id }
完整修正后代码
variable "vm_prefix" { type = string default = "test" } variable "virtual_machines" { default = { app1_node1 = { "vm_name" = "app" "vm_num" = "1" networks = { nic1 = { "nic_name" = "app-1" "subnet" = "/subscriptions/**/resourceGroups/pluto/providers/Microsoft.Network/virtualNetworks/pluto-infra/subnets/app-subnet" "asg_ids" = ["/subscriptions/**/resourceGroups/pluto/providers/Microsoft.Network/applicationSecurityGroups/app-asg", "/subscriptions/**/resourceGroups/pluto/providers/Microsoft.Network/applicationSecurityGroups/db-asg"] }, } }, } } variable "resource_group" { type = string default = "test" } data "azurerm_resource_group" "rg" { name = var.resource_group } locals { all_nics = { for vm in flatten([ for vm_name, vm in var.virtual_machines: [ for nic_name, nic in vm.networks : { vm_number = vm.vm_num, vm_name = vm_name, nic_name = nic_name, subnet_value = nic.subnet, nic_name_value = nic.nic_name asg_ids = nic.asg_ids } ] ]) : "${vm.vm_name}-${vm.nic_name}" => vm } nic_asg_associations = flatten([ for nic_key, nic in local.all_nics : [ for asg_id in nic.asg_ids : { nic_key = nic_key, asg_id = asg_id } ] ]) } resource "azurerm_network_interface" "nic" { for_each = local.all_nics name = "${var.vm_prefix}-${each.value.nic_name}-nic" location = "eastus" resource_group_name = var.resource_group ip_configuration { name = "${var.vm_prefix}-${each.value.nic_name}-ipconfig" subnet_id = each.value.subnet_value private_ip_address_allocation = "Dynamic" } } resource "azurerm_linux_virtual_machine" "vm" { depends_on = [azurerm_network_interface.nic] for_each = var.virtual_machines name = "${var.vm_prefix}-${each.value.vm_name}-${each.value.vm_num}" admin_username = "testadmin" admin_password = "test@1234522" disable_password_authentication = false location = "eastus" resource_group_name = var.resource_group network_interface_ids = [for nic_key, nic in azurerm_network_interface.nic : nic.id if startswith(nic_key, "${each.key}-")] size = "Standard_B2ms" os_disk { name = "${var.vm_prefix}-${each.value.vm_name}-${each.value.vm_num}-OSdisk" caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "RedHat" offer = "RHEL" sku = "82gen2" version = "latest" } } resource "azurerm_network_interface_application_security_group_association" "nic_asg_association" { for_each = { for assoc in local.nic_asg_associations : "${assoc.nic_key}|${assoc.asg_id}" => assoc } network_interface_id = azurerm_network_interface.nic[each.value.nic_key].id application_security_group_id = each.value.asg_id }
验证说明
修正后,nic_asg_associations会为每个NIC的每个ASG生成包含NIC唯一键的关联项,for_each使用nic_key|asg_id作为唯一标识,确保每个关联资源实例唯一,同时通过nic_key正确匹配到azurerm_network_interface.nic中的资源,解决索引无效问题。
内容的提问来源于stack exchange,提问作者Madhumitha
相关产品推荐
相关产品推荐

