VMware 虚拟机的 Terraform 模块

Terraform Module for VMware VMs

我正在创建一个用于在 VMware 中创建 VM 的模块,并且我希望克隆一个 VM 模板。挂起是指添加更多磁盘而不仅仅是模板提供的单个磁盘或将来需要时添加磁盘。

我不知道在虚拟机资源中添加另一个磁盘部分并将变量类型设置为使用插值语法进行映射是否可行。

如果有一种方法可以使用像 jinja 这样的东西来做模板就好了。

正在进行的模块工作:

data "vsphere_datacenter" "dc" {
  name = "${var.vmw_dc}"
}

data "vsphere_datastore" "datastore" {
  name          = "${var.vmw_datastore}"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

data "vsphere_resource_pool" "pool" {
  name          = "${var.vmw_cluster}"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

data "vsphere_network" "network" {
  name          = "${var.vmw_network}"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

resource "vsphere_virtual_machine" "vm" {
  name             = "${var.vm_name}"
  resource_pool_id = "${data.vsphere_resource_pool.pool.id}"
  datastore_id     = "${data.vsphere_datastore.datastore.id}"

  num_cpus = "${var.vm_cpu}"
  memory   = "${var.vm_mem}"
  guest_id = "${var.vm_GuestType}"

  network_interface {
    network_id = "${data.vsphere_network.network.id}"
  }

  disk {
    label = "disk0"
    size  = 20
  }
  disk {
    label = "${var.vm_disk.*.label, count.index}"
  }
}

作为非模块执行此操作很容易。只需像上面的代码那样进行一堆资源声明,或者创建一个模块并在每个需要创建的 VM 的模块中传递变量。

如果您忽略第二个磁盘声明,以上内容适用于单个磁盘 VM。但是,如果我需要添加第二个磁盘,则需要第二个磁盘声明,第三个等等。

所以我想确定,如果创建包含 Disk2 到 X 的映射或映射变量列表,那么在第二个磁盘声明中,其他磁盘将在执行 terraform plan 时呈现。

"vm_disk" = {
  Disk2 = {label=X,Size=X,Position=X},
  Disk3 = {label=X,Size=X,Position=X},
  Disk4 = {label=X,Size=X,Position=X},
}

目前没有办法在 Terraform 中拥有动态数量的子资源,因此您不能简单地使用类似的东西:

resource "vsphere_virtual_machine" "vm" {
  ...
  disk {
    count = "${length(var.disks)}"
    ...
  }
}

在 AWS 等其他提供商中,您的模块可以创建一个没有任何 aws_instance 资源的 ebs_block_device 子资源的实例,然后使用单独的 aws_ebs_volume 资源创建单独的磁盘,然后附加 aws_volume_attachment 资源,因为它们都是顶级资源,所以您可以使用 count 元参数动态设置每个实例获得的卷数量。

虽然 VSphere 提供程序确实提供了单独的 vsphere_virtual_disk 资源,但将这些单独的磁盘资源附加到 VM 的唯一方法是使用 disk 子资源的 attach 参数因此您将无法在模块中动态附加不同数量的磁盘。

terraform 中具有相同名称的任何子资源,例如 disknetworkvsphere_virtual_machine,只是一个对象数组。所以你可以改变

disk {
  label = "disk0"
  size  = 20
}
disk {
  label = "disk1"
  size  = 20
}

类似于

disk = [
  {
    label = "disk0"
    size = 20
  },
  {
    label = "disk0"
    size = 20
  }
]

从那里很容易看出您可以创建一个变量或一些其他逻辑来构建数组并将其分配给磁盘。

disk = ${var.disks}