Terraform:如何将for_each数据源的键传递给Azure资源配置?
问题诊断与解决方案
核心问题
你遇到的索引无效错误,根源在于**azurerm_resource_group数据源的for_each键(资源组名称,如platform)与azurerm_virtual_network资源的for_each键(VNET名称,如hub_vnet)不匹配**,导致用VNET的键去索引数据源时,找不到对应的资源组条目。
你的核心思路(通过动态添加资源组名称来扩缩VNET部署)是可行的,但需要调整for_each的关联逻辑,让VNET能正确关联到对应的资源组数据源。
解决方案1:资源组与VNET一一对应(单资源组单VNET)
如果每个资源组只需要部署一个VNET,可以将变量定义为资源组名称到VNET配置的映射,让数据源和VNET的for_each键统一为资源组名称。
步骤1:定义变量
variable "network_rgs_with_vnets" { type = map(object({ vnet_name = string address_space = list(string) })) default = { platform = { vnet_name = "hub_vnet" address_space = ["10.0.0.0/16"] } workload = { vnet_name = "spoke_vnet" address_space = ["10.1.0.0/16"] } } }
步骤2:数据源配置
data "azurerm_resource_group" "network_rg" { for_each = var.network_rgs_with_vnets name = each.key }
步骤3:VNET资源配置
resource "azurerm_virtual_network" "vnet" { for_each = var.network_rgs_with_vnets name = each.value.vnet_name address_space = each.value.address_space location = data.azurerm_resource_group.network_rg[each.key].location resource_group_name = data.azurerm_resource_group.network_rg[each.key].name }
扩缩容方式:只需在var.network_rgs_with_vnets中添加新的资源组键值对即可。
解决方案2:单资源组多VNET
如果需要在同一个资源组中部署多个VNET,需在VNET配置中明确指定对应的资源组名称,让数据源遍历所有用到的资源组,VNET通过资源组名称关联数据源。
步骤1:定义变量
variable "vnets" { type = map(object({ resource_group_name = string address_space = list(string) })) default = { hub_vnet = { resource_group_name = "platform" address_space = ["10.0.0.0/16"] } spoke_vnet_1 = { resource_group_name = "workload" address_space = ["10.1.0.0/16"] } spoke_vnet_2 = { resource_group_name = "workload" address_space = ["10.2.0.0/16"] } } }
步骤2:数据源配置
data "azurerm_resource_group" "network_rg" { # 提取所有VNET用到的资源组名称,去重后遍历 for_each = toset([for vnet in var.vnets : vnet.resource_group_name]) name = each.value }
步骤3:VNET资源配置
resource "azurerm_virtual_network" "vnet" { for_each = var.vnets name = each.key address_space = each.value.address_space location = data.azurerm_resource_group.network_rg[each.value.resource_group_name].location resource_group_name = each.value.resource_group_name }
扩缩容方式:添加VNET时,在var.vnets中新增条目并指定对应的资源组名称即可;添加资源组时,直接在新VNET条目中引用该资源组名称,数据源会自动遍历获取其属性。
实现思路确认
你的核心需求(动态添加资源组即可部署对应VNET)是完全可行的,关键在于保证VNET与资源组数据源的关联逻辑正确:要么让两者的for_each键统一,要么通过明确的字段(如资源组名称)建立映射,避免用不相关的键去索引数据源。
内容的提问来源于stack exchange,提问作者rb16
相关产品推荐
相关产品推荐

