Terraform中如何为多台虚拟机动态分配网络接口?
问题
我正尝试在Terraform中部署多组for_each逻辑,现有两个变量:
variable "VirtualNetworks":用于两个部署在不同区域的VLAN;variable "VirtualMachines":共6台虚拟机,每个VLAN下各3台。
变量类型定义如下:
variable "VirtualNetworks" { type = list(object({ VirtualNetworksName = string VirtualNetworksLocation = string SubnetName = string NGSName = string })) } variable "VirtualMachines" { type = list(object({ OS = string location = string hostname = string interfaceid = string size = string environment = string publisher = string offer = string sku = string version = string })) }
当前问题是不知道如何为这6个网络接口动态分配对应的子网,我已尝试如下配置:
resource "azurerm_network_interface" "tf_example_nic" { for_each = { for i, v in var.VirtualMachines : i => v } # for_each = { for j, w in var.VirtualNetworks : j => w } name = each.value.interfaceid location = each.value.location resource_group_name = azurerm_resource_group.tf_example_rg.name ip_configuration { name = "internal" subnet_id = each.key != "0||1||2" ? azurerm_subnet.tf_example_subnet[0].id : azurerm_subnet.tf_example_subnet[1].id # subnet_id = azurerm_subnet.tf_example_subnet[each.key].id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.tf_example_public_ip[each.key].id } }
请问是否有实现动态分配的可行方法?
解决方案
要实现网络接口与对应VLAN子网的动态绑定,核心是让虚拟机和虚拟网络建立明确的关联关系,避免依赖索引硬编码。推荐按以下步骤修改:
1. 调整虚拟机变量,增加虚拟网络关联标识
在VirtualMachines变量中新增vnet_key字段,用来指定该虚拟机所属的虚拟网络(建议直接用VirtualNetworks中的VirtualNetworksName作为标识):
variable "VirtualMachines" { type = list(object({ OS = string location = string hostname = string interfaceid = string size = string environment = string publisher = string offer = string sku = string version = string vnet_key = string # 新增:关联到VirtualNetworks的VirtualNetworksName })) }
2. 将虚拟网络列表转为映射(Map)
把var.VirtualNetworks转成以VirtualNetworksName为键的映射,方便快速通过虚拟机的vnet_key匹配对应虚拟网络:
locals { vnets_map = { for vnet in var.VirtualNetworks : vnet.VirtualNetworksName => vnet } }
3. 动态生成网络接口并绑定对应子网
修改网络接口资源配置,通过虚拟机的vnet_key关联到对应的子网。假设你的子网资源是用for_each基于var.VirtualNetworks创建的(键为vnet.VirtualNetworksName),配置如下:
resource "azurerm_network_interface" "tf_example_nic" { for_each = { for vm in var.VirtualMachines : vm.interfaceid => vm } name = each.value.interfaceid location = each.value.location resource_group_name = azurerm_resource_group.tf_example_rg.name ip_configuration { name = "internal" # 通过vnet_key直接匹配对应子网ID subnet_id = azurerm_subnet.tf_example_subnet[each.value.vnet_key].id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.tf_example_public_ip[each.value.interfaceid].id } }
补充:适配子网用count创建的场景
如果你的子网是用count创建的(列表形式),可以先把子网也转成映射:
locals { subnets_map = { for idx, subnet in azurerm_subnet.tf_example_subnet : local.vnets_map[idx].VirtualNetworksName => subnet } }
然后在网络接口中替换为:
subnet_id = local.subnets_map[each.value.vnet_key].id
内容的提问来源于stack exchange,提问作者Aun Zaidi
相关产品推荐
相关产品推荐

