You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:05:13