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

Terraform vSphere:VM多磁盘嵌套for_each循环配置失败求助

vSphere Terraform批量部署VM多磁盘加载失败问题

在vSphere环境中使用Terraform的for_each批量部署VM,期望每个VM按variables.tf中定义的多磁盘配置创建,但实际仅能加载disk0,disk1等其他磁盘无法生成。

问题根源

  1. 变量类型不匹配:variables.tf中disks定义为list(map(any)),但实际赋值是map类型,导致Terraform解析时仅识别第一个元素。
  2. Locals逻辑错误:原local.env_provisioning将每个磁盘拆为独立条目,导致每个VM被重复创建(每个磁盘对应一个VM实例),且动态磁盘块遍历对象错误。
  3. 动态磁盘遍历错误:dynamic "disk"的for_each指向单个磁盘对象,而非可遍历的磁盘集合。

修正后的代码

variables.tf

修正disks类型为map(object),匹配实际赋值结构:

variable "demo" {
  type = map(object({
    ip_address = string
    hostname   = string
    subnet     = string
    vcpu       = string
    ram        = string
    disks      = map(object({
      name         = string
      size         = number
      unit_number  = number
    }))
  }))
  default = { 
    demo1 = { 
      ip_address =  "111.111.111.111"
      hostname   =  "test1"
      subnet     =  "subnet1"
      vcpu       =  "4"
      ram        =  "8"
      disks =  {
        "disk0" = {
          name = "disk0" 
          size =  100
          unit_number = 0
        }
        "disk1" = {
          name = "disk1" 
          size =  100
          unit_number = 1
        }
      }
    },
    demo2 = { 
      ip_address =  "222.222.222.222"
      hostname   =  "test2"
      subnet     =  "subnet2"
      vcpu       =  "4"
      ram        =  "8"
      disks =  {
        "disk0" = {
          name = "disk0" 
          size =  100
          unit_number = 0
        }
        "disk1" = {
          name = "disk1" 
          size =  200
          unit_number = 1
        }
      }
    },
    demo3 = { 
      ip_address =  "333.333.333.333"
      hostname   =  "test3"
      subnet     =  "subnet3"
      vcpu       =  "4"
      ram        =  "8"
      disks =  {
        "disk0" = {
          name = "disk0" 
          size =  100
          unit_number = 0
        }
        "disk1" = {
          name = "disk1" 
          size =  300
          unit_number = 1
        }
      }
    }
  }
}

locals.tf

简化逻辑,直接保留VM完整配置:

locals {
  env_provisioning = var.demo
}

instance.tf

调整for_each以VM为单位遍历,动态磁盘块遍历当前VM的所有磁盘:

resource "vsphere_virtual_machine" "this" {
  for_each = local.env_provisioning

  name             = each.value.hostname
  resource_pool_id = data.vsphere_resource_pool.default.id
  datastore_id     = data.vsphere_datastore.datastore.id
  folder           = data.vsphere_folder.folder.path
  firmware         = "efi"
  num_cpus         = each.value.vcpu
  memory           = each.value.ram
  guest_id         = data.vsphere_virtual_machine.template.guest_id

  network_interface {
    network_id = (each.value.subnet == var.backend_subnet ? data.vsphere_network.backend-subnet1.id : data.vsphere_network.frontend-subnet0.id)
  }

  dynamic "disk" {
    for_each = each.value.disks
    content {
      label        = disk.value.name
      size         = disk.value.size
      unit_number  = disk.value.unit_number
    }
  }

  clone {
    template_uuid = data.vsphere_virtual_machine.template.id

    customize {
      linux_options {
        host_name = each.value.hostname
        domain    = var.internal_domain
      }
      network_interface {
        ipv4_address = each.value.ip_address
        ipv4_netmask = (each.value.subnet == var.backend_subnet.name ? var.backend_subnet.cidr : var.frontend_subnet.cidr)
      }
      ipv4_gateway = (each.value.subnet == var.backend_subnet.name ? var.backend_subnet.gateway : var.frontend_subnet.gateway)
      dns_server_list = var.dns
    }
  }
}

修正效果

每个VM将根据variables.tf中定义的disks映射创建对应数量的磁盘,for_each以VM为单位遍历确保每个VM仅创建一次,动态磁盘块正确遍历所有磁盘配置生成多磁盘条目。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 12:24:53