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

如何通过Terraform仅基于CSV中maxview字段值为1的条目创建虚拟机?

实现仅创建CSV中maxview为1的虚拟机

当然可以实现这个需求!你只需要先对CSV读取的数据进行过滤,仅保留maxview字段值为"1"的条目,再基于过滤后的列表创建虚拟机即可。下面是具体的修改方案:

1. 过滤CSV数据

首先修改locals块,先读取原始CSV数据,再添加过滤逻辑筛选出符合条件的实例:

locals {
  # 读取原始CSV数据(保留原始数据,方便后续扩展)
  raw_instances = csvdecode(file("./data/sys-${local.environment}.csv"))
  # 过滤出maxview字段为"1"的条目
  # 注意:csvdecode会把所有CSV字段解析为字符串,所以要匹配字符串"1"而非数字1
  instances = [for inst in local.raw_instances : inst if inst.maxview == "1"]
  
  # 原有的vsphere_hn配置保持不变
  vsphere_hn = {
    domain = "hn"
    dev1 = {
      app_datastores = ["sata_ssd_storage_140-1"]
    }
    eu1 = {
      app_datastores = ["sata_ssd_storage_140-1"]
    }
  }
}

2. 基于过滤后的列表创建虚拟机

推荐使用for_each替代count来创建虚拟机(count依赖列表索引,当CSV条目顺序变化时可能导致不必要的VM销毁重建,for_each使用唯一键更稳定):

// VMs
module "vm-hn-maxview-maxview_vm" {
  # 使用for_each遍历过滤后的实例,以node字段作为唯一标识键
  for_each = { for inst in local.instances : inst.node => inst }
  providers = {
    vsphere = vsphere.vcadmin
  }
  
  # 注意:将原有的local.instances[count.index]替换为each.value
  name = "${each.value.node}.${local.vsphere_hn.domain}.${var.dns_local_name[local.environment]}"
  annotation = "Managed by Terraform"
  dc = var.vsphere_core_datacenter_name[local.environment]
  # 这里注意:原代码用count.index取datastore可能会因过滤后列表长度变化导致越界,这里先取第一个datastore,可根据实际需求调整
  datastore = local.vsphere_hn[local.environment].app_datastores[0]
  template = var.centos7_vsphere_template[local.environment].template
  resource_pool_vapp = vsphere_vapp_container.vm-hn-maxview-vapp.id
  customize_name = "maxview"
  customize_domain = "${each.value.node}.${local.vsphere_hn.domain}.${var.dns_local_name[local.environment]}"
  cpu_number = 2
  num_cores_per_socket = 1
  ram_size = 2048
  network = {
    "${var.network_vlan_maxview_name[local.environment]}" = ["${var.network_address_prefix[local.environment]}.8.${each.value.node_id}"]
  }
  network_gateway = "${var.network_address_prefix[local.environment]}.9.254"
  network_submask = ["${var.network_address_submask_maxview[local.environment]}"]
  data_disk = {
    disk1 = {
      size_gb = 10, thin_provisioned = false, data_disk_scsi_controller = 0,
    }
  }
}

关键说明

  • 你之前尝试的for_each写法有误:{ for inst in local.instances : inst.node => inst } ? 1:0不符合Terraform语法,正确的过滤逻辑是在for表达式中添加if条件,直接生成仅包含目标实例的map/列表。
  • csvdecode会将CSV中所有字段解析为字符串类型,所以判断时要使用inst.maxview == "1"而非inst.maxview == 1。
  • 如果坚持使用count,只需将count = length(local.instances)即可(因为local.instances已经是过滤后的列表),但依然推荐for_each以避免不必要的资源变动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 14:52:44