hashicorp / terraform-provider-vsphere

Terraform Provider for VMware vSphere
https://registry.terraform.io/providers/hashicorp/vsphere/
Mozilla Public License 2.0
609 stars 449 forks source link

race condition renaming `r/vsphere_folder` #1816

Open arnaudclerc opened 1 year ago

arnaudclerc commented 1 year ago

Community Guidelines

Terraform

v1.3.6

Terraform Provider

v2.2.0

VMware vSphere

v7.0.3

Description

Apply and Destroy are executed perfectly,

Apply: the folder get created then VM get created inside this folder

Destroy: the VM is deleted then the folder gets deleted

Editing a folder, throws an error due to bad dependency flow: when renaming a folder, the VM depending on it waits for the new folder name to be created and the old folder name to be deleted, thus, it is no possible as the old folder name still holds the VM.

Debug Output

Expected Behavior Terraform creates new folder name, moves the VM which depends on this folder (or recursively depends on it (child of child folder case..)), then delete the old folder name when VM is successfully moved.

Actual Behavior Terraform has a race condition in which a destroy is attempted on the folder before it's empty, causing the destroy to fail.

Steps to Reproduce terraform apply [[RENAME FOLDER]]] terraform apply

Important Factoids References https://github.com/hashicorp/terraform-provider-vsphere/issues/23 https://github.com/hashicorp/terraform-provider-vsphere/issues/453

Affected Resources or Data Sources

resource/vsphere_folder resource/vsphere_virtual_machine

Terraform Configuration

resource "vsphere_folder" "folders_level1" {
  # Folder Level 1
  # Create a vsphere_folder resource for each key
  for_each      = {
    for paths in distinct(local.folders_level1) : paths => paths
  }
  path          = each.value
  type          = "vm"
  datacenter_id = var.dc_id
}

resource "vsphere_folder" "folders_level2" {
  # Folder Level 2
  # Create a vsphere_folder with an interpolation dependency off the parent's folder
  for_each      =  {
    for paths in distinct(local.folders_level2) : paths => paths
  }
  path          = "${vsphere_folder.folders_level1[trimsuffix(each.value, format("/%s", split("/", each.value)[2]))].path}/${split("/", each.value)[2]}"
  type          = "vm"
  datacenter_id = var.dc_id
}
resource "vsphere_virtual_machine" "domain_controller" {
  name             = "${var.domain_controller.["hostname"]}.${var.client_info.["domain_name"]}"
  resource_pool_id = "${data.vsphere_resource_pool.pool.id}"
  datastore_id     = "${data.vsphere_datastore.datastore.id}"
# interpolation of folder resource using path length
  folder   = <<EOT
%{~ if length(split("/", each.value.folder)) > 2 ~}
${var.folder_lvl2[each.value.folder].path}%{~ else ~}
${var.folder_lvl1[each.value.folder].path}
%{~ endif ~}
  EOT

  num_cpus = "${var.domain_controller.["cpu_sockets"]}"
  memory   = "${var.domain_controller.["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]}"
  }

  disk {
    label            = "disk0"
    size             = "${data.vsphere_virtual_machine.template.disks.0.size}"
    eagerly_scrub    = "${data.vsphere_virtual_machine.template.disks.0.eagerly_scrub}"
    thin_provisioned = "${data.vsphere_virtual_machine.template.disks.0.thin_provisioned}"
  }

  clone {
    template_uuid = "${data.vsphere_virtual_machine.template.id}"

    customize {
      windows_options {
        computer_name = "${var.domain_controller["hostname"]}"
        organization_name = "${var.client_info.["folder_name"]}"
      }

      network_interface {
        ipv4_address = "${var.domain_controller.["ipv4_address"]}"
        ipv4_netmask = "${var.domain_controller.["ipv4_netmask"]}"
      }

      ipv4_gateway = "${var.client_info.["ipv4_gateway"]}"
    }
  }
}

Debug Output

https://gist.github.com/arnaudclerc/c5b5a9824bc4209d251d628a935b8b10

Panic Output

No response

Expected Behavior

module.folderstructure.vsphere_folder.folders_level2["2/WINDOWS/BBB"]: Creating...
module.folderstructure.vsphere_folder.folders_level2["2/WINDOWS/BBB"]: Creation complete after 0s [id=group-v3773]

module.vm-windows["./json_build/windows.json"].vsphere_virtual_machine.vm-windows["WINDOWS2"]: Modifying... [id=420909ba-e793-ff6e-9f2b-ebcdd8a2b1e7]
module.vm-windows["./json_build/windows.json"].vsphere_virtual_machine.vm-windows["WINDOWS2"]: Modifications complete after 2s [id=420909ba-e793-ff6e-9f2b-ebcdd8a2b1e7]

module.folderstructure.vsphere_folder.folders_level2["2/WINDOWS/AAA"]: Destroying... [id=group-v3770]
module.folderstructure.vsphere_folder.folders_level3["2/WINDOWS/AAA"]: Destruction complete after 1s

Actual Behavior

the folder that needs to be renamed is being deleted the re-created under its new name before the VM have been able to be move to the corresponding path.

the deletion of folder's old name crashes because VM is still in it.

Steps to Reproduce

apply once, rename the folder of the VM, apply a second time

Environment Details

No response

Screenshots

No response

References

No response

github-actions[bot] commented 1 year ago

Hello, arnaudclerc! 🖐

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.

tenthirtyam commented 1 year ago

Have you tried using depends_on?

arnaudclerc commented 1 year ago

Have you tried using depends_on?

Yes, in many different ways, it doesn't change the actual behaviour

(tried depending on a time resource, the last level folder, all subsequents folders)

i don't know if this is important but i'm using 2 differents modules, one for folder creation the other for VM creation, the first one outputs the folders and VM are using this output for interpolation dependency,

The code example is a bit complex to try to reflect my actual project but even with one folder and one simple vsphere_virtual_machine, the problem persists, have you been able to reproduce the error ?

tenthirtyam commented 1 year ago

have you been able to reproduce the error ?

No. Sorry, I’ve not had availability to do so.

arnaudclerc commented 1 year ago

No. Sorry, I’ve not had availability to do so.

no prob; i'm surprised as i don't see anyone else reporting this case, i don't think my configuration is so special to cause this, and it seems to be a common use case of the resource.

I think it is bound to Terraform's way of declaring resources, i might have a solution to this but my knowledge of the Vsphere provider is close to zero and i don't see any way of exploiting it locally by building the sources.

tenthirtyam commented 3 weeks ago

Hi there @arnaudclerc! Could you provide a concise example so that we can reproduce and triage the issue?