Terraform配置Azure VWAN VPN网关连接时vpn_link参数报错求助
问题:Azure VWAN VPN站点链路连接创建失败
场景概述
通过Terraform定义映射结构管理VWAN站点及链路,已成功创建站点和链路,但创建azurerm_vpn_gateway_connection时提示缺少vpn_site_link_id参数,尽管状态文件中已存在链路ID。
变量定义
virtual_wan_vpn_sites = { vwan_site_dc = { name = "site-shr-infra-dc" location_map_key = "primary" resource_group_key = "rg_vwan" vwan_key = "vwan" device_vendor = "Fortigate" device_model = "FGT60F" links = { link_1 = { name = "link-shr-infra-dc-1" bgp_asn = "64512" public_ip_address = "1.1.1.1" bgp_peering_ip = "10.10.100.1" } link_2 = { name = "link-shr-infra-dc-2" bgp_asn = "64513" public_ip_address = "2.2.2.2" bgp_peering_ip = "10.10.100.100" } } } }
模块调用及资源代码
# 创建VPN站点 module "virtualWanVpnSites" { source = "../../modules/networking/virtual_wan_vpn_site" for_each = var.virtual_wan_vpn_sites name = each.value.name location = var.location_map[each.value.location_map_key] resource_group_name = azurerm_resource_group.resource_group[each.value.resource_group_key].name virtual_wan_id = module.virtualWan[each.value.vwan_key].virtual_wan_id vwan_key = each.value.vwan_key vwan_sites = each.value.links device_vendor = each.value.device_vendor device_model = each.value.device_model vpn_gateways = values(module.virtualHubVpn)[*].virtual_hub_vpn_gateway_id tags = merge(lookup(each.value, "tags", {}), local.tags) } # 模块内的VPN站点资源 resource "azurerm_vpn_site" "vwan_vpn_site" { name = var.name location = var.location resource_group_name = var.resource_group_name virtual_wan_id = var.virtual_wan_id device_vendor = var.device_vendor device_model = var.device_model tags = local.tags dynamic "link" { for_each = try(var.vwan_sites, {}) content { name = link.value.name ip_address = link.value.public_ip_address bgp { asn = link.value.bgp_asn peering_address = link.value.bgp_peering_ip } } } } # 模块内的VPN网关连接资源 resource "azurerm_vpn_gateway_connection" "vhub_vpn_gateway_connection" { for_each = toset(var.vpn_gateways) name = "example" vpn_gateway_id = each.key remote_vpn_site_id = azurerm_vpn_site.vwan_vpn_site.id dynamic "vpn_link" { for_each = try(azurerm_vpn_site.vwan_vpn_site.link, []) content { name = vpn_link.value.name vpn_site_link_id = vpn_link.value.id bgp_enabled = true } } }
报错信息
Error: Missing required argument │ │ with module.virtualWanVpnSites["vwan_site_dc"].azurerm_vpn_gateway_connection.vhub_vpn_gateway_connection["/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Network/vpnGateways/vpn-shr-infra-usce"], │ on ../../modules/networking/virtual_wan_vpn_site/module.tf line 25, in resource "azurerm_vpn_gateway_connection" "vhub_vpn_gateway_connection": │ 25: resource "azurerm_vpn_gateway_connection" "vhub_vpn_gateway_connection" { │ │ The argument "vpn_link.1.vpn_site_link_id" is required, but no definition │ was found. ╵ ╷ │ Error: Missing required argument │ │ with module.virtualWanVpnSites["vwan_site_dc"].azurerm_vpn_gateway_connection.vhub_vpn_gateway_connection["/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Network/vpnGateways/vpn-shr-infra-use2"], │ on ../../modules/networking/virtual_wan_vpn_site/module.tf line 25, in resource "azurerm_vpn_gateway_connection" "vhub_vpn_gateway_connection": │ 25: resource "azurerm_vpn_gateway_connection" "vhub_vpn_gateway_connection" { │ │ The argument "vpn_link.1.vpn_site_link_id" is required, but no definition │ was found.
状态文件验证(链路ID已存在)
{ "module": "module.virtualWanVpnSites[\"vwan_site_dc\"]", "mode": "managed", "type": "azurerm_vpn_site", "name": "vwan_vpn_site", "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]", "instances": [ { "schema_version": 0, "attributes": { "address_cidrs": [], "device_model": "FGT60F", "device_vendor": "Fortigate", "id": "/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Network/vpnSites/site-shr-infra-dc", "link": [ { "bgp": [ { "asn": 64512, "peering_address": "10.10.100.1" } ], "fqdn": "", "id": "/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Network/vpnSites/site-shr-infra-dc/vpnSiteLinks/link-shr-infra-dc-1", "ip_address": "1.1.1.1", "name": "link-shr-infra-dc-1", "provider_name": "", "speed_in_mbps": 0 }, { "bgp": [ { "asn": 64513, "peering_address": "10.10.100.100" } ], "fqdn": "", "id": "/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.Network/vpnSites/site-shr-infra-dc/vpnSiteLinks/link-shr-infra-dc-2", "ip_address": "2.2.2.2", "name": "link-shr-infra-dc-2", "provider_name": "", "speed_in_mbps": 0 } ] } } ] }
解决思路及修正代码
问题根源
直接遍历azurerm_vpn_site.vwan_vpn_site.link列表时,Terraform可能无法正确解析列表元素的id属性传递到动态块中,导致部分vpn_link块缺失vpn_site_link_id参数。
修正方案
改用输入的var.vwan_sites(链路映射)作为动态块遍历源,通过链路名称从站点资源的link列表中匹配对应的ID,确保每个vpn_link块都能正确获取到必填参数。
修正后的azurerm_vpn_gateway_connection资源代码:
resource "azurerm_vpn_gateway_connection" "vhub_vpn_gateway_connection" { for_each = toset(var.vpn_gateways) # 生成唯一连接名称,避免重复 name = "${var.name}-conn-${regex("[^/]+$", each.key)}" vpn_gateway_id = each.key remote_vpn_site_id = azurerm_vpn_site.vwan_vpn_site.id dynamic "vpn_link" { # 遍历输入的链路映射,确保每个链路都被处理 for_each = var.vwan_sites content { name = vpn_link.value.name # 通过链路名称匹配站点资源中的链路ID vpn_site_link_id = one([for l in azurerm_vpn_site.vwan_vpn_site.link : l.id if l.name == vpn_link.value.name]) bgp_enabled = true } } }
说明
- 使用
var.vwan_sites(明确的链路映射)遍历,避免依赖资源列表的不确定性; - 通过列表推导式
[for l in ...]结合one()函数,精准匹配对应链路的ID,确保返回单个有效值; - 优化连接名称生成逻辑,避免固定名称导致的冲突问题。
内容的提问来源于stack exchange,提问作者Adonerok
相关产品推荐
相关产品推荐

