Terraform vSphere动态生成虚拟机对应网卡问题求助
问题解决:为每个VM仅生成自身配置的网卡
当前Terraform配置会为所有虚拟机加载全部网卡(比如两台VM共3个网卡,每个VM都会被添加3个),需要调整为每个VM仅加载自身定义的网卡。
问题根源
- 全局的
local.networks是所有VM网卡的集合,动态块遍历这个集合会把所有网卡都附加到每个VM上。 - 数据源
vsphere_network.interfaces按所有接口实例生成,会重复获取同一网络(比如"Contoso Lan"被重复获取两次)。
修正步骤
1. 优化数据源:按唯一网络名获取,避免重复
将数据源改为按唯一网络名称遍历,同一个网络只会被获取一次,消除冗余:
data "vsphere_network" "interfaces" { for_each = toset(flatten([ for vm in var.virtual_machines : [ for interface in vm.interfaces : interface.network ] ])) name = each.value datacenter_id = data.vsphere_datacenter.dc.id }
2. 修正虚拟机资源的网卡动态块
在vsphere_virtual_machine.vm资源中,直接遍历当前VM自身的interfaces,而非全局集合:
resource "vsphere_virtual_machine" "vm" { for_each = var.virtual_machines # 其余基础配置(名称、CPU、内存、磁盘等)保持不变 dynamic "network_interface" { # 遍历当前VM的interfaces,转为带键的map(满足Terraform for_each要求) for_each = { for idx, intf in each.value.interfaces : idx => intf } content { network_id = data.vsphere_network.interfaces[network_interface.value.network].id } } clone { template_uuid = data.vsphere_virtual_machine.template[each.key].id customize { linux_options { host_name = "${each.key}.${each.value.domain_name}" domain = each.value.domain_name } dynamic "network_interface" { # 同样遍历当前VM的interfaces,生成对应自定义配置 for_each = { for idx, intf in each.value.interfaces : idx => intf } content { ipv4_address = network_interface.value.ipv4_address ipv4_netmask = network_interface.value.ipv4_netmask } } ipv4_gateway = each.value.gateway } } }
3. 可选:移除冗余变量
由于不再需要全局的local.networks集合,可以直接删除该变量定义,简化配置结构。
效果验证
- 每个VM仅会生成自身
interfaces字段中定义的网卡数量(gw VM生成2个,lab VM生成1个)。 - 数据源
vsphere_network.interfaces仅会生成唯一的网络实例("VM Network"和"Contoso Lan"各1个)。
内容的提问来源于stack exchange,提问作者Roman Qwertoff
相关产品推荐
相关产品推荐

