I am tryig to create disk using a dynamic block to match my template, everything works fine if I hardcode the disk block like that
disk {
label = "disk0"
size = data.vsphere_virtual_machine.template.disks.0.size
unit_number = 0
thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
}
disk {
label = "disk1"
size = data.vsphere_virtual_machine.template.disks.1.size
unit_number = 1
thin_provisioned = data.vsphere_virtual_machine.template.disks.1.thin_provisioned
}
disk {
label = "disk2"
size = data.vsphere_virtual_machine.template.disks.2.size
unit_number = 2
thin_provisioned = data.vsphere_virtual_machine.template.disks.2.thin_provisioned
}
disk {
label = "disk3"
size = data.vsphere_virtual_machine.template.disks.3.size
unit_number = 3
thin_provisioned = data.vsphere_virtual_machine.template.disks.3.thin_provisioned
}
However, when using a dynamic block it fails:
dynamic "disk" {
for_each = var.disk
content {
label = disk.value["label"]
size = data.vsphere_virtual_machine.template.disks.${disk.value["index"]}.size
thin_provisioned = data.vsphere_virtual_machine.template.disks.${disk.value["index"]}.thin_provisioned
unit_number = disk.value["index"]
}
}
variable "disk" {
description = "My disks. Such disks. Much wow."
type = list(map(string))
default = [
{
label = "disk0",
index = 0
},
{
label = "disk1",
index = 1
},
{
label = "disk2",
index = 2
},
{
label = "disk3",
index = 3
}
]
}
Finally, i know the interpolation is wrong, but it seems i can't find the correct form to replace the disk index by a dynamic value.
Any help on that would be very much apprecated.
EDITED: POSTED THE ENTIRE CODE
provider "vsphere" {
user = var.vsphere_user
password = var.vsphere_password
vsphere_server = var.vsphere_server
allow_unverified_ssl = true
}
data "vsphere_datacenter" "dc" {
name = var.datacenter
}
data "vsphere_datastore" "datastore" {
name = var.datastore
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_compute_cluster" "cluster" {
name = var.cluster
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_network" "network" {
name = var.portgroup
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_virtual_machine" "template" {
name = var.template_name
datacenter_id = data.vsphere_datacenter.dc.id
}
resource "vsphere_virtual_machine" "linux" {
count = var.extra_disk_create ? 0 : 1
name = var.vm_name
resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
datastore_id = data.vsphere_datastore.datastore.id
num_cpus = var.vcpu_count
memory = var.memory
guest_id = data.vsphere_virtual_machine.template.guest_id
scsi_type = data.vsphere_virtual_machine.template.scsi_type
network_interface {
network_id = data.vsphere_network.network.id
adapter_type = data.vsphere_virtual_machine.template.network_interface_types[0]
}
dynamic "disk" {
for_each = local.disk
content {
label = disk.key
size = disk.value.size
thin_provisioned = disk.value.thin_provisioned
unit_number = disk.value.unit_number
}
}
clone {
template_uuid = data.vsphere_virtual_machine.template.id
linked_clone = "false"
customize {
linux_options {
host_name = var.vm_name
domain = var.domain_name
}
network_interface {
ipv4_address = var.vm_ip
ipv4_netmask = var.vm_cidr
}
ipv4_gateway = var.default_gw
dns_server_list = var.dns_list
}
}
}
Variables:
variable "vsphere_server" {
description = "vcentre Server"
}
variable "vsphere_password" {
description = "Vcentre Password"
}
variable "vsphere_user" {
description = "Vcentre Username"
}
variable "vm_root_pass" {
description = "Root password for the VM"
}
variable "datacenter" {
description = "datacenter name"
}
variable "datastore" {
description = "datastore name"
}
variable "cluster" {
description = "cluster name"
}
variable "portgroup" {
description = "portgroup name"
}
variable "domain_name" {
description = "domain name"
}
variable "default_gw" {
description = "domain name"
}
variable "template_name" {
description = "template to be used"
}
variable "vm_name" {
description = "vm_name to be used"
}
variable "vm_ip" {
description = "vm ip to be used"
}
variable "vm_cidr" {
description = "vm_cidr"
}
variable "vcpu_count" {
description = "vm_cidr"
}
variable "memory" {
description = "vm memory in megabytes"
}
variable "disk_name" {
description = "vm memory in megabytes"
}
variable "adminpassword" {
description = "vm memory in megabytes"
}
variable "is_windows_image" {
description = "vm memory in megabytes"
}
variable "extra_disk_size" {
description = "vm memory in megabytes"
}
variable "disk_size" {
description = "vm memory in megabytes"
}
variable "dns_list" {
description = "vm memory in megabytes"
}
variable "extra_disk_create" {
description = "vm memory in megabytes"
}
variable "extra_disk" {
description = "My extra disks. Such extra disks. Much wow."
}
locals {
disk = {
disk0 = {
size = data.vsphere_virtual_machine.template.disks.0.size
unit_number = 0
thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
}
disk1 = {
size = data.vsphere_virtual_machine.template.disks.1.size
unit_number = 1
thin_provisioned = data.vsphere_virtual_machine.template.disks.1.thin_provisioned
}
disk2 = {
size = data.vsphere_virtual_machine.template.disks.2.size
unit_number = 2
thin_provisioned = data.vsphere_virtual_machine.template.disks.2.thin_provisioned
}
disk3 = {
size = data.vsphere_virtual_machine.template.disks.3.size
unit_number = 3
thin_provisioned = data.vsphere_virtual_machine.template.disks.3.thin_provisioned
}
}
That will not work as you cannot use a list with for_each
. I would suggest rewriting the variable to have this look and to be a local variable:
locals {
disk = {
disk0 = {
size = data.vsphere_virtual_machine.template.disks.0.size
unit_number = 0
thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
} # repeat this for the rest of the disks
}
}
Then in the dynamic
block you should set the following:
dynamic "disk" {
for_each = local.disk
content {
label = disk.key
size = disk.value.size
thin_provisioned = disk.value.thin_provisioned
unit_number = disk.value.unit_number
}
}