首页 > 解决方案 > 有没有办法将 terraform 配置为具有可选的第二个 nic 的 VM?

问题描述

我当前的 terraform 设置了一个带有 2 个网卡的 VMware vm。

我想更改它,以便第二个 nic (nfs) 是可选的,并且只有在 tfvars 文件中说明了它的参数时才会创建它。

参数是

vsphere_vm_nfs_network
vsphere_vm_nfs_network_address
vsphere_vm_nfs_ip_address_start

这是 tf 文件。

variable "vsphere_vm_count"                {}
variable "vsphere_vm_name"                 {}
variable "vsphere_vm_num_cpus"             {}
variable "vsphere_vm_memory"               {}
variable "centos_root_password"                 {}
variable "vsphere_vm_resource_pool_id"     {}
variable "vsphere_vm_datastore_id"         {}
variable "vsphere_folder"                   {}
variable "vsphere_guest_id"                     {}
variable "vsphere_vm_network_id"           {}
variable "vsphere_nfs_vm_network_id"           {}
variable "vsphere_adapter_type"                 {}
variable "vsphere_disk_size"                    {}
variable "vsphere_template_uuid"                {}
variable "vsphere_domain"                   {}
variable "vsphere_vm_ipv4_gateway"         {}
variable "vsphere_vm_network_address"      {}
variable "vsphere_vm_ip_address_start"     {}
variable "vsphere_vm_nfs_network_address"  {}
variable "vsphere_vm_nfs_ip_address_start" {}
variable "vsphere_wait_for_guest_net_timeout"   {}
variable "vsphere_vm_firmware"             {}
variable "vsphere_dns_server_list"          {
    type    = list(string)
}


resource "vsphere_virtual_machine" "vm" {
  count                      = var.vsphere_vm_count
  name                       = "${var.vsphere_vm_name}${count.index + 1}"
  firmware                   = var.vsphere_vm_firmware
  resource_pool_id           = var.vsphere_vm_resource_pool_id
  datastore_id               = var.vsphere_vm_datastore_id
  folder                     = var.vsphere_folder
  num_cpus                   = var.vsphere_vm_num_cpus
  memory                     = var.vsphere_vm_memory
  guest_id                   = var.vsphere_guest_id
  wait_for_guest_net_timeout = var.vsphere_wait_for_guest_net_timeout

  network_interface {
    network_id      = var.vsphere_vm_network_id
    adapter_type    = var.vsphere_adapter_type
  }

    network_interface {
    network_id      = var.vsphere_nfs_vm_network_id
    adapter_type    = var.vsphere_adapter_type
  }

  disk {
    label           = "${var.vsphere_vm_name}${count.index + 1}"
    size            = var.vsphere_disk_size
  }

  clone {
    template_uuid    = var.vsphere_template_uuid

    customize {
      timeout        = 0
      
      linux_options {
        host_name    = "${var.vsphere_vm_name}${count.index + 1}"
        domain       = var.vsphere_domain
      }

      network_interface {
        ipv4_address = "${cidrhost(var.vsphere_vm_network_address, var.vsphere_vm_ip_address_start + count.index)}"
        ipv4_netmask = 24
      }

      network_interface {
        ipv4_address = "${cidrhost(var.vsphere_vm_nfs_network_address, var.vsphere_vm_nfs_ip_address_start + count.index)}"
        ipv4_netmask = 24
      }

      ipv4_gateway    = var.vsphere_vm_ipv4_gateway
      dns_server_list = var.vsphere_dns_server_list
    }
  }

  provisioner "remote-exec" {
    inline = [
      "systemctl stop firewalld",
      "systemctl disable firewalld",
      "sed -i 's/net.ipv4.ip_forward=0/net.ipv4.ip_forward=1/g' /etc/sysctl.conf",
    ]
    connection {
      script_path     = "/script.sh"
      type            = "ssh"
      user            = "root"
      password        = var.centos_root_password
      host            = "${cidrhost(var.vsphere_vm_network_address, var.vsphere_vm_ip_address_start + count.index)}"
    }
  }

}

output "vsphere_vm_ip_addresses" {
 value = vsphere_virtual_machine.vm.*.clone.0.customize.0.network_interface.0.ipv4_address
}                  

这是我的 tfvars

#  Configuration    
vsphere_vm_name                    = "vm-hard-1-20"
vsphere_vm_firmware                = "efi"    
vsphere_vm_count                   = "5"
vsphere_vm_num_cpus                = "48"
vsphere_vm_memory                  = "135168"
vsphere_vm_resource_pool           = "LAB-Cluster1/Resources/"
vsphere_vm_datastore               = "datastore_01"
vsphere_vm_ipv4_gateway            = "172.16.41.254"  
vsphere_vm_network                 = "-Support"
vsphere_vm_network_address         = "172.16.41.0/24" 
vsphere_vm_ip_address_start        = "201"
vsphere_vm_nfs_network             = "-NFS"
vsphere_vm_nfs_network_address     = "172.16.64.0/24" 
vsphere_vm_nfs_ip_address_start    = "201"

谢谢,阿维拉姆

标签: terraformvmwarenetwork-interface

解决方案


我认为您可以使用动态块来简化此问题,因此我建议您稍微更改一下变量的结构:

variable "vsphere_vm_nics" {
  type = list(map(string))
}

在您的 *.tfvars 中,您将拥有如下结构:

vsphere_vm_nics = [
  {
    vsphere_vm_network = "1st NIC value"
    vsphere_vm_network_address = "1st NIC value"
    vsphere_vm_ip_address_start = "1st NIC value"
  },
  {
    vsphere_vm_network = "Optional 2nd NIC value"
    vsphere_vm_network_address = "Optional 2nd NIC value"
    vsphere_vm_ip_address_start = "Optional 2nd NIC value"
  }
]

最后,修改资源的network_interface部分vsphere_virtual_machine以使用动态块:

dynamic "network_interface" {
  for_each = toset(var.vsphere_vm_nics)
  content {
    ipv4_address = "${cidrhost(each.value["vsphere_vm_network_address"], each.value["vsphere_vm_ip_address_start"] + count.index)}"
    ipv4_netmask = 24
  }
}

至少在理论上,这应该允许您根据需要指定尽可能多的 NIC,只需在var.vsphere_vm_nics.


推荐阅读