Azure上Terraform跨for_each资源引用报错求助
Terraform Azure VNet关联对应资源组的解决方案
问题核心
你遇到的Invalid index错误本质是虚拟网络的for_each键与资源组的for_each键不匹配:
- 资源组的键从
multiple_resource_groups生成,格式为<tenant>-rg-<rg_key>-<region_code>(例如cubem_rg-connectivity-ae) - 虚拟网络的键从
multiple_vnets生成,格式为<tenant>-rg-<vnet_key>-<region_code>(例如cubem_rg-vnetx-ae) - 用虚拟网络的
each.key直接索引资源组,自然找不到对应条目,导致索引失败。
方案一:固定关联指定资源组(当前场景适用)
如果所有虚拟网络都归属connectivity资源组,按以下步骤修正:
1. 修改local.multi_region_vnet配置
修正VNet名称格式(避免和资源组名称混淆),同时添加对应资源组名称字段:
locals { multi_region_vnet = flatten([ for vnet_key, vnet in var.multiple_vnets : [ for region_key, region in var.regions : { # 修正VNet命名规则,用vnet替代rg vnet_name = var.environment != "" ? format("%s-vnet-%s-%s-%s", var.tenant, vnet_key, var.environment, region.code) : format("%s-vnet-%s-%s", var.tenant, vnet_key, region.code) region_name = region.name virtual_network_address_space = vnet.address_space # 生成与资源组key完全匹配的名称 rg_name = var.environment != "" ? format("%s-rg-%s-%s-%s", var.tenant, "connectivity", var.environment, region.code) : format("%s-rg-%s-%s", var.tenant, "connectivity", region.code) } ] ]) }
2. 修正虚拟网络资源块引用
用each.value.rg_name索引对应的资源组:
resource "azurerm_virtual_network" "vnet" { for_each = { for k, v in local.multi_region_vnet : v.vnet_name => v } name = each.key location = each.value.region_name address_space = each.value.virtual_network_address_space # 通过匹配的rg_name索引资源组,获取其名称 resource_group_name = azurerm_resource_group.rg[each.value.rg_name].name }
方案二:支持多资源组关联(扩展性更强)
如果未来需要让不同VNet归属不同资源组,可调整变量结构实现动态关联:
1. 更新tfvars中的multiple_vnets配置
为每个VNet添加rg_key字段指定所属资源组:
multiple_vnets = { vnetx = { address_space = ["10.1.0.0/24"], rg_key = "connectivity" # 指定该VNet归属connectivity资源组 }, }
2. 修改local.multi_region_vnet配置
动态读取VNet的rg_key生成对应资源组名称:
locals { multi_region_vnet = flatten([ for vnet_key, vnet in var.multiple_vnets : [ for region_key, region in var.regions : { vnet_name = var.environment != "" ? format("%s-vnet-%s-%s-%s", var.tenant, vnet_key, var.environment, region.code) : format("%s-vnet-%s-%s", var.tenant, vnet_key, region.code) region_name = region.name virtual_network_address_space = vnet.address_space # 根据VNet指定的rg_key生成资源组名称 rg_name = var.environment != "" ? format("%s-rg-%s-%s-%s", var.tenant, vnet.rg_key, var.environment, region.code) : format("%s-rg-%s-%s", var.tenant, vnet.rg_key, region.code) } ] ]) }
3. 虚拟网络资源块引用方式同方案一
保持用each.value.rg_name索引资源组即可。
验证
执行terraform plan,虚拟网络会正确关联到对应区域的目标资源组,索引错误将被解决。
内容的提问来源于stack exchange,提问作者Chamambom
相关产品推荐
相关产品推荐

