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
错误原因分析
- 变量类型不匹配:调用模块的
ip_config变量定义为list(object),但.tfvar配置中ip_config是map(object)结构,类型冲突导致参数解析错误。 - 参数结构与键名不匹配:核心模块要求
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
相关产品推荐
相关产品推荐

