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

Terraform跨模块动态传参部署Azure虚拟网络网关报错排查

解决Terraform Azure虚拟网络网关模块参数传递不匹配问题

问题现象

执行Terraform计划时出现报错:

on main.tf line , in module "vnet_gw": each.value.ip_config is map of object with 2 elements This map does not have an element with the key "ip_name" similar for public address id and subnet_id

错误原因分析

  1. 变量类型不匹配:调用模块的ip_config变量定义为list(object),但.tfvar配置中ip_config是map(object)结构,类型冲突导致参数解析错误。
  2. 参数结构与键名不匹配:核心模块要求ip_config是包含name/address_id/subnet_id键的map(object),但调用模块传递时不仅键名不符(使用了ip_name/addr_id/s_id),还错误地将整个map当作单个object直接取值,未做结构转换。

修正后的代码实现

1. 修正调用模块的变量定义

将ip_config的类型改为map(object),与.tfvar中的结构对齐:

variable "vnet_gw" {
  type = map(object({
    name       = string
    rg         = string
    location   = string
    type       = string
    sku        = string
    ip_config  = map(object({
      ip_name = string
      addr_id = string
      s_id    = string
    }))
  }))
}

2. 修正调用核心模块的代码

传递ip_config时,将.tfvar中的结构转换为核心模块要求的键名和格式:

module "vnet_gw" {
  source = "./path/to/core-vnet-gw-module" # 替换为实际核心模块路径
  for_each = var.vnet_gw 

  name                = each.value.name
  location            = each.value.location
  rg                  = each.value.rg
  type                = each.value.type
  sku                 = each.value.sku

  # 转换ip_config结构,匹配核心模块要求
  ip_config = {
    for k, v in each.value.ip_config : k => {
      name       = v.ip_name
      address_id = v.addr_id
      subnet_id  = v.s_id
    }
  }
}

3. 核心模块代码保持不变

核心模块的资源和变量定义逻辑正确,无需修改:

# 核心模块资源定义
resource "azurerm_virtual_network_gateway" "this" {
  name                = var.name
  location            = var.location
  resource_group_name = var.rg
  type                = var.type
  sku                 = var.sku

  dynamic "ip_configuration" {
    for_each = var.ip_config
    content {
      name                          = ip_configuration.value.name
      public_ip_address_id          = ip_configuration.value.address_id
      subnet_id                     = ip_configuration.value.subnet_id
    }
  }
}

# 核心模块变量定义
variable "ip_config" {
  type = map(object({
    name       = string
    address_id = string
    subnet_id  = string
  }))
}

4. .tfvar配置保持不变

原有的.tfvar结构符合业务需求,无需调整:

vnet_gw = {
  "vnet1" = {
    name     = "vnet-gw-1"
    rg       = "rg-test"
    location = "eastus"
    type     = "Vpn"
    sku      = "VpnGw1"
    ip_config = {
      "ip_1" = {
        ip_name = "test1"
        addr_id = "/subscriptions/xxx/resourceGroups/rg-test/providers/Microsoft.Network/publicIPAddresses/pip-test1"
        s_id    = "/subscriptions/xxx/resourceGroups/rg-test/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/GatewaySubnet"
      },
      "ip_2" = {
        ip_name = "test2"
        addr_id = "/subscriptions/xxx/resourceGroups/rg-test/providers/Microsoft.Network/publicIPAddresses/pip-test2"
        s_id    = "/subscriptions/xxx/resourceGroups/rg-test/providers/Microsoft.Network/virtualNetworks/vnet1/subnets/GatewaySubnet"
      }
    }
  }
}

说明

修正后,调用模块会将.tfvar中每个虚拟网络网关的ip_config map,逐个转换为核心模块要求的键名结构,再传递给核心模块。核心模块的dynamic "ip_configuration"块会遍历这个map,动态生成对应的IP配置项,实现多IP配置的动态部署。

内容的提问来源于stack exchange,提问作者rravinda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 22:20:59