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

Azure环境下Terraform NIC与VM映射变量拆分配置问题

正确的变量声明与配置方式

要解决索引无效和属性不支持的问题,核心是用**map(object(...))**类型定义变量,既满足for_each对可哈希键的要求,又能清晰约束每个实例的属性结构。

1. variables.tf(变量声明)

明确nics和vms的类型为map(object),定义每个对象必须包含的属性及类型:

variable "nics" {
  type = map(object({
    name              = string
    resource_group    = string
    subnet_id         = string
    private_ip_address = optional(string) # 可选属性,按需添加
  }))
  description = "批量创建的网络接口配置"
}

variable "vms" {
  type = map(object({
    name              = string
    resource_group    = string
    nic_id            = string
    vm_size           = string
    admin_username    = string
    admin_password    = string # 生产环境建议用密钥 vault,此处为示例
  }))
  description = "批量创建的虚拟机配置"
}

2. terraform.tfvars(变量赋值)

以键值对形式配置每个实例,键作为for_each的唯一索引:

nics = {
  "nic-web-01" = {
    name              = "nic-web-01"
    resource_group    = "rg-demo"
    subnet_id         = "/subscriptions/xxx/resourceGroups/rg-demo/providers/Microsoft.Network/virtualNetworks/vnet-demo/subnets/subnet-web"
  }
  "nic-web-02" = {
    name              = "nic-web-02"
    resource_group    = "rg-demo"
    subnet_id         = "/subscriptions/xxx/resourceGroups/rg-demo/providers/Microsoft.Network/virtualNetworks/vnet-demo/subnets/subnet-web"
    private_ip_address = "10.0.1.10"
  }
}

vms = {
  "vm-web-01" = {
    name              = "vm-web-01"
    resource_group    = "rg-demo"
    nic_id            = azurerm_network_interface.nic["nic-web-01"].id
    vm_size           = "Standard_D2s_v3"
    admin_username    = "adminuser"
    admin_password    = "P@ssw0rd123!"
  }
  "vm-web-02" = {
    name              = "vm-web-02"
    resource_group    = "rg-demo"
    nic_id            = azurerm_network_interface.nic["nic-web-02"].id
    vm_size           = "Standard_D2s_v3"
    admin_username    = "adminuser"
    admin_password    = "P@ssw0rd123!"
  }
}

3. main.tf(资源创建)

通过for_each遍历变量,用each.key作为唯一标识,each.value引用对应属性:

resource "azurerm_network_interface" "nic" {
  for_each = var.nics

  name                = each.value.name
  location            = azurerm_resource_group.rg[each.value.resource_group].location
  resource_group_name = each.value.resource_group

  ip_configuration {
    name                          = "internal"
    subnet_id                     = each.value.subnet_id
    private_ip_address_allocation = each.value.private_ip_address != null ? "Static" : "Dynamic"
    private_ip_address            = each.value.private_ip_address
  }
}

resource "azurerm_linux_virtual_machine" "vm" {
  for_each = var.vms

  name                = each.value.name
  resource_group_name = each.value.resource_group
  location            = azurerm_resource_group.rg[each.value.resource_group].location
  size                = each.value.vm_size
  admin_username      = each.value.admin_username
  admin_password      = each.value.admin_password

  network_interface_ids = [each.value.nic_id]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }
}

错误原因说明

  • 索引无效错误:通常是因为变量类型与for_each要求不匹配(比如用了列表而非map),或者变量赋值时键名与引用时的索引不统一。
  • 属性不支持错误:如果将nics定义为包含列表的对象,for_each无法直接遍历列表元素(列表元素无唯一键),且引用属性时会因类型不匹配导致报错,而map(object)能明确每个实例的属性结构,避免类型冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 03:35:17