Open Adinadu opened 1 year ago
Hello, Adinadu! 🖐
Thank you for submitting an issue for this provider. The issue will now enter into the issue lifecycle.
If you want to contribute to this project, please review the contributing guidelines and information on submitting pull requests.
Hi 👋 -
Please format the code blocks, provide a working link to the gist, and a complete reproducible example.
Thanks!
Here is another one for your reference!
https://www.reddit.com/r/Terraform/comments/125xhgv/trouble_deploying_a_vsphere_vm_using_terraform/
Questions:
Why? " successful using a template. However, still the issue if I use that same template as an OVF from a content library. I'll just stick with the regular template."
Another issue I have no idea why you cannot use datastore_clutser_id just because it requires a lookup?
case d.Id() == "": if contentlibrary.IsContentLibraryItem(meta.(*Client).restClient, d.Get("clone.0.templateuuid").(string)) { if , ok := d.GetOk("datastore_cluster_id"); ok { return fmt.Errorf("Cannot use datastore_cluster_id with Content Library source") } } else if err := vmworkflow.ValidateVirtualMachineClone(d, client); err != nil { return err } fallthrough
Hi 👋 -
Please format the code blocks, provide a working link to the gist, and a complete reproducible example.
Thanks!
`data "vsphere_datacenter" "dc" {
name = var.dc
}
data "vsphere_datastore_cluster" "datastore_cluster" {
count = var.datastore_cluster != "" ? 1 : 0
name = var.datastore_cluster
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_datastore" "datastore" {
count = 1
name = var.datastore
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_datastore" "disk_datastore" {
count = 1
name = var.disk_datastore
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_resource_pool" "pool" {
name = var.vmrp
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_network" "network" {
count = length(var.network)
name = keys(var.network)[count.index]
datacenter_id = data.vsphere_datacenter.dc.id
}
//Evaluate template with or without content library
data "vsphere_virtual_machine" "template" {
count = 1 //var.content_library == null ? 1 : 0
name = var.vmtemp
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_content_library" "library" {
count = var.content_library != null ? 1 : 0
name = var.content_library
depends_on = [var.tag_depends_on]
}
data "vsphere_content_library_item" "library_item_template" {
count = var.content_library != null ? 1 : 0
library_id = data.vsphere_content_library.library[0].id
type = "ovf"
name = var.vmtemp
depends_on = [var.tag_depends_on]
}
data "vsphere_tag_category" "category" {
count = var.tags != null ? length(var.tags) : 0
name = keys(var.tags)[count.index]
depends_on = [var.tag_depends_on]
}
data "vsphere_tag" "tag" {
count = var.tags != null ? length(var.tags) : 0
name = var.tags[keys(var.tags)[count.index]]
category_id = data.vsphere_tag_category.category[count.index].id
depends_on = [var.tag_depends_on]
}
data "vsphere_folder" "folder" {
count = var.vmfolder != null ? 1 : 0
path = "/${data.vsphere_datacenter.dc.name}/vm/${var.vmfolder}"
depends_on = [var.vm_depends_on]
}
locals {
interface_count = length(var.ipv4submask) #Used for Subnet handeling
template_disk_count = var.content_library == null ? length(data.vsphere_virtual_machine.template[0].disks) : 0
}
// Cloning a Linux or Windows VM from a given template.
resource "vsphere_virtual_machine" "vm" {
lifecycle {
ignore_changes = [
custom_attributes,
disk
]
}
count = var.instances
depends_on = [var.vm_depends_on]
name = var.staticvmname != null ? var.staticvmname : format("${var.vmname}${var.vmnameformat}", count.index + 1)
resource_pool_id = data.vsphere_resource_pool.pool.id
folder = var.vmfolder
tags = var.tag_ids != null ? var.tag_ids : data.vsphere_tag.tag[*].id
custom_attributes = var.custom_attributes
annotation = var.annotation
extra_config = var.extra_config
firmware = var.content_library == null && var.firmware == null ? data.vsphere_virtual_machine.template[0].firmware : var.firmware
efi_secure_boot_enabled = var.content_library == null && var.efi_secure_boot == null ? data.vsphere_virtual_machine.template[0].efi_secure_boot_enabled : var.efi_secure_boot
enable_disk_uuid = var.content_library == null && var.enable_disk_uuid == null ? data.vsphere_virtual_machine.template[0].enable_disk_uuid : var.enable_disk_uuid
storage_policy_id = var.storage_policy_id
datastore_id = var.datastore != "" ? data.vsphere_datastore.datastore[0].id : null
num_cpus = var.cpu_number
num_cores_per_socket = var.num_cores_per_socket
cpu_hot_add_enabled = var.cpu_hot_add_enabled
cpu_hot_remove_enabled = var.cpu_hot_remove_enabled
cpu_reservation = var.cpu_reservation
cpu_limit = var.cpu_limit
cpu_share_level = var.cpu_share_level
cpu_share_count = var.cpu_share_level == "custom" ? var.cpu_share_count : null
memory_reservation = var.memory_reservation
memory = var.ram_size
memory_hot_add_enabled = var.memory_hot_add_enabled
memory_share_level = var.memory_share_level
memory_share_count = var.memory_share_level == "custom" ? var.memory_share_count : null
guest_id = var.content_library == null ? data.vsphere_virtual_machine.template[0].guest_id : null
scsi_bus_sharing = var.scsi_bus_sharing
scsi_type = var.scsi_type != "" ? var.scsi_type : (var.content_library == null ?
data.vsphere_virtual_machine.template[0].scsi_type : null)
scsi_controller_count = max(
max(0, flatten([
for item in values(var.data_disk) : [
for elem, val in item :
elem == "data_disk_scsi_controller" ? val : 0
]])...) + 1,
ceil((max(0, flatten([
for item in values(var.data_disk) : [
for elem, val in item :
elem == "unit_number" ? val : 0
]])...) + 1) / 15),
var.scsi_controller)
wait_for_guest_net_routable = var.wait_for_guest_net_routable
wait_for_guest_ip_timeout = var.wait_for_guest_ip_timeout
wait_for_guest_net_timeout = var.wait_for_guest_net_timeout
ignored_guest_ips = var.ignored_guest_ips
dynamic "network_interface" {
for_each = keys(var.network) #data.vsphere_network.network[].id #other option
content {
network_id = data.vsphere_network.network[network_interface.key].id
adapter_type = var.network_type != null ? var.network_type[network_interface.key] : (var.content_library == null ? data.vsphere_virtual_machine.template[0].network_interface_types[0] : null)
ovf_mapping = true
}
}
// Disks defined in the original template
dynamic "disk" {
for_each = var.content_library == null ? data.vsphere_virtual_machine.template[0].disks : []
iterator = template_disks
content {
label = length(var.disk_label) > 0 ? var.disk_label[template_disks.key] : "disk${template_disks.key}"
size = var.disk_size_gb != null ? var.disk_size_gb[template_disks.key] : data.vsphere_virtual_machine.template[0].disks[template_disks.key].size
unit_number = var.scsi_controller != null ? var.scsi_controller 15 + template_disks.key : template_disks.key
thin_provisioned = data.vsphere_virtual_machine.template[0].disks[template_disks.key].thin_provisioned
eagerly_scrub = data.vsphere_virtual_machine.template[0].disks[template_disks.key].eagerly_scrub
datastore_id = var.disk_datastore != "" ? data.vsphere_datastore.disk_datastore[0].id : null
storage_policy_id = length(var.template_storage_policy_id) > 0 ? var.template_storage_policy_id[template_disks.key] : null
io_reservation = length(var.io_reservation) > 0 ? var.io_reservation[template_disks.key] : null
io_share_level = length(var.io_share_level) > 0 ? var.io_share_level[template_disks.key] : "normal"
io_share_count = length(var.io_share_level) > 0 && var.io_share_level[template_disks.key] == "custom" ?
var.io_share_count[template_disks.key] : null
}
}
// Disk for template from Content Library ( *** USE CL disks because we want override thick/thin provisions)
dynamic "disk" {
for_each = var.content_library == null ? [] : data.vsphere_virtual_machine.template[0].disks
iterator = template_disks
content {
label = length(var.disk_label) > 0 ? var.disk_label[template_disks.key] : "disk${template_disks.key}"
size = var.disk_size_gb != null ? var.disk_size_gb[template_disks.key] :
data.vsphere_virtual_machine.template[0].disks[template_disks.key].size
//size = var.disk_size_gb[template_disks.key]
unit_number = var.scsi_controller != null ? var.scsi_controller * 15 + template_disks.key : template_disks.key
// thin_provisioned = data.vsphere_virtual_machine.template[0].disks[template_disks.key].thin_provisioned
// eagerly_scrub = data.vsphere_virtual_machine.template[0].disks[template_disks.key].eagerly_scrub
//Use externally provided values for disk provisioning
thin_provisioned = var.thin_provisioned
eagerly_scrub = var.eagerly_scrub
datastore_id = var.disk_datastore != "" ? data.vsphere_datastore.disk_datastore[0].id : null
storage_policy_id = length(var.template_storage_policy_id) > 0 ? var.template_storage_policy_id[template_disks.key] : null
io_reservation = length(var.io_reservation) > 0 ? var.io_reservation[template_disks.key] : null
io_share_level = length(var.io_share_level) > 0 ? var.io_share_level[template_disks.key] : "normal"
io_share_count = length(var.io_share_level) > 0 && var.io_share_level[template_disks.key] == "custom" ? var.io_share_count[template_disks.key] : null
disk_mode = length(var.disk_mode) > 0 ? var.disk_mode[template_disks.key] : null
}
}
// Additional disks defined by Terraform config
dynamic "disk" {
for_each = var.data_disk
iterator = terraform_disks
content {
label = terraform_disks.key
size = lookup(terraform_disks.value, "size_gb", null)
unit_number = (
lookup(
terraform_disks.value,
"unit_number",
-1
) < 0 ? (
lookup(
terraform_disks.value,
"data_disk_scsi_controller",
0
) > 0 ? (
(terraform_disks.value.data_disk_scsi_controller * 15) +
index(keys(var.data_disk), terraform_disks.key) +
(var.scsi_controller == tonumber(terraform_disks.value["data_disk_scsi_controller"]) ? local.template_disk_count : 0)
) : (
index(keys(var.data_disk), terraform_disks.key) + local.template_disk_count
)
) : (
tonumber(terraform_disks.value["unit_number"])
)
)
thin_provisioned = var.thin_provisioned
eagerly_scrub = var.eagerly_scrub
# eagerly_scrub = lookup(terraform_disks.value, "eagerly_scrub", "false")
datastore_id = lookup(terraform_disks.value, "datastore_id", null)
storage_policy_id = lookup(terraform_disks.value, "storage_policy_id", null)
io_reservation = lookup(terraform_disks.value, "io_reservation", null)
io_share_level = lookup(terraform_disks.value, "io_share_level", "normal")
io_share_count = lookup(terraform_disks.value, "io_share_level", null) == "custom" ? lookup(terraform_disks.value, "io_share_count") : null
disk_mode = lookup(terraform_disks.value, "disk_mode", null)
}
}
clone {
template_uuid = var.content_library == null ? data.vsphere_virtual_machine.template[0].id : data.vsphere_content_library_item.library_item_template[0].id
linked_clone = var.linked_clone
timeout = var.timeout
customize {
dynamic "linux_options" {
for_each = var.is_windows_image ? [] : [1]
content {
host_name = var.staticvmname != null ? var.staticvmname : format("${var.vmname}${var.vmnameformat}", count.index + 1)
domain = var.domain
hw_clock_utc = var.hw_clock_utc
}
}
dynamic "windows_options" {
for_each = var.is_windows_image ? [1] : []
content {
computer_name = var.staticvmname != null ? var.staticvmname : format("${var.vmname}${var.vmnameformat}", count.index + 1)
admin_password = var.local_adminpass
workgroup = var.workgroup
join_domain = var.windomain
domain_admin_user = var.domain_admin_user
domain_admin_password = var.domain_admin_password
organization_name = var.orgname
run_once_command_list = var.run_once
auto_logon = var.auto_logon
auto_logon_count = var.auto_logon_count
time_zone = var.time_zone
product_key = var.productkey
full_name = var.full_name
}
}
dynamic "network_interface" {
for_each = keys(var.network)
content {
ipv4_address = "10.152.140.190" # split("/", var.network[keys(var.network)[network_interface.key]][count.index])[0]
ipv4_netmask = "23" #var.network[keys(var.network)[network_interface.key]][count.index] == "" ? null : (
length(split("/", var.network[keys(var.network)[network_interface.key]][count.index])) == 2 ? (
split("/", var.network[keys(var.network)[network_interface.key]][count.index])[1]
) : (
length(var.ipv4submask) == 1 ? var.ipv4submask[0] : var.ipv4submask[network_interface.key]
)
)
}
}
dns_server_list = var.dns_server_list
dns_suffix_list = var.dns_suffix_list
ipv4_gateway = "10.152.140.1" # var.vmgateway
}
}
// Advanced options
hv_mode = var.hv_mode
ept_rvi_mode = var.ept_rvi_mode
nested_hv_enabled = var.nested_hv_enabled
enable_logging = var.enable_logging
cpu_performance_counters_enabled = var.cpu_performance_counters_enabled
swap_placement_policy = var.swap_placement_policy
latency_sensitivity = var.latency_sensitivity
shutdown_wait_timeout = var.shutdown_wait_timeout
force_power_off = var.force_power_off
}
`
Don't know what is going on with code block I did this twice and it is getting garbled as soon as lines reached certain threshold. It is difficult to produce an exact working example as it contains company's infrastructure.
I know it is hard for you to make sense of the problem without the whole picture.
Community Guidelines
Terraform
1.4.4
Terraform Provider
vsphere_v2.3.1_x
VMware vSphere
vSphere Client version 7.0.3.00600
Description
Error: Provider produced inconsistent final plan │ │ When expanding the plan for module.itss-tf-vm.vsphere_virtual_machine.vm[0] to include new values learned so far during apply, provider "registry.terraform.io/hashicorp/vsphere" produced an invalid new value for .disk[0].datastore_id: was │ cty.StringVal(""), but now cty.StringVal("datastore-31753").
│
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.
Affected Resources or Data Sources
resource "vsphere_virtual_machine"
Terraform Configuration
resource "vsphere_virtual_machine" "vm" { lifecycle { ignore_changes = [ custom_attributes, disk ] } count = var.instances depends_on = [var.vm_depends_on] name = var.staticvmname != null ? var.staticvmname : format("${var.vmname}${var.vmnameformat}", count.index + 1)
resource_pool_id = data.vsphere_resource_pool.pool.id folder = var.vmfolder tags = var.tag_ids != null ? var.tag_ids : data.vsphere_tag.tag[*].id custom_attributes = var.custom_attributes annotation = var.annotation extra_config = var.extra_config firmware = var.content_library == null && var.firmware == null ? data.vsphere_virtual_machine.template[0].firmware : var.firmware efi_secure_boot_enabled = var.content_library == null && var.efi_secure_boot == null ? data.vsphere_virtual_machine.template[0].efi_secure_boot_enabled : var.efi_secure_boot enable_disk_uuid = var.content_library == null && var.enable_disk_uuid == null ? data.vsphere_virtual_machine.template[0].enable_disk_uuid : var.enable_disk_uuid storage_policy_id = var.storage_policy_id
datastore_cluster_id = var.datastore_cluster != "" ? data.vsphere_datastore_cluster.datastore_cluster[0].id : null datastore_id = var.datastore != "" ? data.vsphere_datastore.datastore[0].id : null
num_cpus = var.cpu_number num_cores_per_socket = var.num_cores_per_socket cpu_hot_add_enabled = var.cpu_hot_add_enabled cpu_hot_remove_enabled = var.cpu_hot_remove_enabled cpu_reservation = var.cpu_reservation cpu_limit = var.cpu_limit cpu_share_level = var.cpu_share_level cpu_share_count = var.cpu_share_level == "custom" ? var.cpu_share_count : null memory_reservation = var.memory_reservation memory = var.ram_size memory_hot_add_enabled = var.memory_hot_add_enabled memory_share_level = var.memory_share_level memory_share_count = var.memory_share_level == "custom" ? var.memory_share_count : null guest_id = var.content_library == null ? data.vsphere_virtual_machine.template[0].guest_id : null scsi_bus_sharing = var.scsi_bus_sharing scsi_type = var.scsi_type != "" ? var.scsi_type : (var.content_library == null ? data.vsphere_virtual_machine.template[0].scsi_type : null) scsi_controller_count = max( max(0, flatten([ for item in values(var.data_disk) : [ for elem, val in item : elem == "data_disk_scsi_controller" ? val : 0 ]])...) + 1, ceil((max(0, flatten([ for item in values(var.data_disk) : [ for elem, val in item : elem == "unit_number" ? val : 0 ]])...) + 1) / 15), var.scsi_controller) wait_for_guest_net_routable = var.wait_for_guest_net_routable wait_for_guest_ip_timeout = var.wait_for_guest_ip_timeout wait_for_guest_net_timeout = var.wait_for_guest_net_timeout
ignored_guest_ips = var.ignored_guest_ips
dynamic "network_interface" { for_each = keys(var.network) #data.vsphere_network.network[].id #other option content { network_id = data.vsphere_network.network[network_interface.key].id adapter_type = var.network_type != null ? var.network_type[network_interface.key] : (var.content_library == null ? data.vsphere_virtual_machine.template[0].network_interface_types[0] : null) } } // Disks defined in the original template dynamic "disk" { for_each = var.content_library == null ? data.vsphere_virtual_machine.template[0].disks : [] iterator = template_disks content { label = length(var.disk_label) > 0 ? var.disk_label[template_disks.key] : "disk${template_disks.key}" size = var.disk_size_gb != null ? var.disk_size_gb[template_disks.key] : data.vsphere_virtual_machine.template[0].disks[template_disks.key].size unit_number = var.scsi_controller != null ? var.scsi_controller 15 + template_disks.key : template_disks.key thin_provisioned = data.vsphere_virtual_machine.template[0].disks[template_disks.key].thin_provisioned eagerly_scrub = data.vsphere_virtual_machine.template[0].disks[template_disks.key].eagerly_scrub datastore_id = var.disk_datastore != "" ? data.vsphere_datastore.disk_datastore[0].id : null storage_policy_id = length(var.template_storage_policy_id) > 0 ? var.template_storage_policy_id[template_disks.key] : null io_reservation = length(var.io_reservation) > 0 ? var.io_reservation[template_disks.key] : null io_share_level = length(var.io_share_level) > 0 ? var.io_share_level[template_disks.key] : "normal" io_share_count = length(var.io_share_level) > 0 && var.io_share_level[template_disks.key] == "custom" ? var.io_share_count[template_disks.key] : null } } // Disk for template from Content Library dynamic "disk" {
for_each = var.content_library == null ? [] : [1]
} // Additional disks defined by Terraform config dynamic "disk" { for_each = var.data_disk iterator = terraform_disks content { label = terraform_disks.key size = lookup(terraform_disks.value, "size_gb", null) unit_number = ( lookup( terraform_disks.value, "unit_number", -1 ) < 0 ? ( lookup( terraform_disks.value, "data_disk_scsi_controller", 0 ) > 0 ? ( (terraform_disks.value.data_disk_scsi_controller * 15) + index(keys(var.data_disk), terraform_disks.key) + (var.scsi_controller == tonumber(terraform_disks.value["data_disk_scsi_controller"]) ? local.template_disk_count : 0) ) : ( index(keys(var.data_disk), terraform_disks.key) + local.template_disk_count ) ) : ( tonumber(terraform_disks.value["unit_number"]) ) ) thin_provisioned = var.thin_provisioned
eagerly_scrub = var.eagerly_scrub
thin_provisioned = lookup(terraform_disks.value, "thin_provisioned", "true")
} clone { template_uuid = var.content_library == null ? data.vsphere_virtual_machine.template[0].id : data.vsphere_content_library_item.library_item_template[0].id linked_clone = var.linked_clone timeout = var.timeout
}
// Advanced options hv_mode = var.hv_mode ept_rvi_mode = var.ept_rvi_mode nested_hv_enabled = var.nested_hv_enabled enable_logging = var.enable_logging cpu_performance_counters_enabled = var.cpu_performance_counters_enabled swap_placement_policy = var.swap_placement_policy latency_sensitivity = var.latency_sensitivity
shutdown_wait_timeout = var.shutdown_wait_timeout force_power_off = var.force_power_off }
Debug Output
https://gist.github.com/Adinadu
Panic Output
No response
Expected Behavior
Not to deal with buggy code.
Actual Behavior
Failed to create VM
Steps to Reproduce
Use a content library to clone a Linux VM
Environment Details
No response
Screenshots
No response
References
No response