Terraform vSphere:VM多磁盘嵌套for_each循环配置失败求助
vSphere Terraform批量部署VM多磁盘加载失败问题
在vSphere环境中使用Terraform的for_each批量部署VM,期望每个VM按variables.tf中定义的多磁盘配置创建,但实际仅能加载disk0,disk1等其他磁盘无法生成。
问题根源
- 变量类型不匹配:
variables.tf中disks定义为list(map(any)),但实际赋值是map类型,导致Terraform解析时仅识别第一个元素。 - Locals逻辑错误:原
local.env_provisioning将每个磁盘拆为独立条目,导致每个VM被重复创建(每个磁盘对应一个VM实例),且动态磁盘块遍历对象错误。 - 动态磁盘遍历错误:
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
相关产品推荐
相关产品推荐

