hashicorp / terraform-provider-vsphere

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

Terraform is treating the disk created outside as orphan and forcing to delete #1947

Open dumpap opened 1 year ago

dumpap commented 1 year ago

Community Guidelines

Terraform

v1.4.6

Terraform Provider

v2.4.1

VMware vSphere

v2.4.1

Description

I have virtual machines created using terraform code for vSphere and it all working fine. I am testing a scenario of adding a virtual disk outside of terraform (thru the VM settings in vSphere console) and run a plan.

When I run a plan, below is whats happening

~ resource "vsphere_virtual_machine" "vm" {
        id                                      = "4221dc89-83a9-a20f-82df-5350f97cdfd8"
        name                                    = "testtemplate03"
        tags                                    = []
        # (67 unchanged attributes hidden)

      ~ disk {
          ~ label            = "orphaned_disk_0" -> "<remove, keep disk>"
            # (19 unchanged attributes hidden)
        }

        # (5 unchanged blocks hidden)
    }

I know this is expected, but is there a way I can include / import this newly added disk into my terraform config so that it will not complain.

Please advise if there is a way for this ?

thank you.

Affected Resources or Data Sources

vsphere_virtual_machine

Terraform Configuration

vm_instances = [
  {
    name             = "testtemplate03"
    env              = "prod"
    os               = "windows"
    region           = "syd"
    is_windows_image = true
    cpu_number       = "4"     # "2"
    ram_size         = "12288" # "8192"
    app              = "test"
    # tags    = {
    #     os = windows
    #     version  = 2019
    #     app = miles
    #     team = erp
    # }
    vm_template_name = "testwintmpl02"
    disk_size_gb     = [100]
    # disk_label              = [ "disk0_C" ]
    data_disk = {
      "disk1" = {
        size_gb      = 40,
        unit_number  = 1,
        drive_letter = "D"
      }
      "disk2" = {
        size_gb      = 20,
        unit_number  = 2,
        drive_letter = "E"
      }
      # "disk3" = {
      #     size_gb      = 10,
      #     unit_number  = 3,
      #     drive_letter = "F"
      # }
    }
    vlan         = "svr"
    ipv4_address = "0.0.0.0"
  }
]

// Cloning a Linux or Windows VM from a given template.
resource "vsphere_virtual_machine" "vm" {
  name     = var.name
  guest_id = data.vsphere_virtual_machine.vm_template.guest_id
  num_cpus = var.cpu_number
  memory   = var.ram_size
  folder   = var.folder # data.vsphere_folder.folder.path
  # tags    =   var.tag_ids
  resource_pool_id            = data.vsphere_compute_cluster.cluster.resource_pool_id
  datastore_id                = var.datastore != "" ? data.vsphere_datastore.datastore.id : null
  firmware                    = data.vsphere_virtual_machine.vm_template.firmware
  efi_secure_boot_enabled     = data.vsphere_virtual_machine.vm_template.efi_secure_boot_enabled
  enable_disk_uuid            = data.vsphere_virtual_machine.vm_template.enable_disk_uuid
  scsi_type                   = data.vsphere_virtual_machine.vm_template.scsi_type
  wait_for_guest_net_timeout  = 0
  wait_for_guest_ip_timeout   = 0
  wait_for_guest_net_routable = false

  #   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
  #   }
  # }

  network_interface {
    network_id   = data.vsphere_network.network.id
    adapter_type = data.vsphere_virtual_machine.vm_template.network_interface_types[0]
  }

  // Disks defined in the original template
  dynamic "disk" {
    for_each = data.vsphere_virtual_machine.vm_template.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.vm_template.disks[template_disks.key].size
      thin_provisioned = data.vsphere_virtual_machine.vm_template.disks[template_disks.key].thin_provisioned
      datastore_id     = var.datastore != "" ? data.vsphere_datastore.datastore.id : null
    }
  }

  // Additional disks defined by Terraform config
  # dynamic "disk" {
  #   for_each = var.data_disk
  #   iterator = terraform_disks
  #   content {
  #     label            = terraform_disks.key #"${terraform_disks.key}_${terraform_disks.value["drive_letter"]}"
  #     size             = terraform_disks.value["size_gb"]
  #     unit_number      = terraform_disks.value["unit_number"]
  #     thin_provisioned = lookup(terraform_disks.value, "thin_provisioned", null) != null ? terraform_disks.value["thin_provisioned"] : "true"
  #     datastore_id     = data.vsphere_datastore.datastore.id
  #   }
  # }

  dynamic "disk" {
    for_each = var.data_disk
    iterator = terraform_disks
    content {
      label            = terraform_disks.key #"${terraform_disks.key}_${terraform_disks.value["drive_letter"]}"
      # size             = terraform_disks.value["size_gb"]
      unit_number      = terraform_disks.value["unit_number"]
      attach = true
      path = "${var.name}/${var.name}_${terraform_disks.value["unit_number"]}.vmdk"
      # thin_provisioned = lookup(terraform_disks.value, "thin_provisioned", null) != null ? terraform_disks.value["thin_provisioned"] : "true"
      datastore_id     = data.vsphere_datastore.datastore.id
    }
  }

  clone {
    template_uuid = data.vsphere_virtual_machine.vm_template.id
    linked_clone  = true #var.linked_clone
    # timeout       = var.timeout

    customize {
      timeout = 0
      dynamic "linux_options" {
        for_each = var.is_windows_image ? [] : [1]
        content {
          host_name = var.name
          time_zone = var.time_zone
          domain    = "fleetpartners.local" #var.domain
          # hw_clock_utc = var.hw_clock_utc
        }
      }

      dynamic "windows_options" {
        for_each = var.is_windows_image ? [1] : []
        content {
          computer_name  = var.name
          admin_password = var.local_adminpass
          # workgroup             = var.workgroup
          join_domain           = var.join_domain
          domain_admin_user     = var.domain_admin_user
          domain_admin_password = var.domain_admin_password
          organization_name     = var.organization_name
          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.product_key
          full_name   = var.organization_name
        }
      }

      # dynamic "network_interface" {
      #   for_each = toset(var.ipv4_address)
      #   content {
      #     ipv4_address = network_interface.value
      #     ipv4_netmask = var.ipv4_netmask
      #   }
      # }

      network_interface {
        ipv4_address = var.ipv4_address
        ipv4_netmask = var.ipv4_netmask
      }
      dns_server_list = var.dns_server_list
      ipv4_gateway    = var.ipv4_gateway
    }
  }

  lifecycle {
    ignore_changes = [
      ept_rvi_mode,
      hv_mode
    ]
  }
}

Debug Output

 ~ resource "vsphere_virtual_machine" "vm" {
        id                                      = "4221dc89-83a9-a20f-82df-5350f97cdfd8"
        name                                    = "testtemplate03"
        tags                                    = []
        # (67 unchanged attributes hidden)

      ~ disk {
          ~ label            = "orphaned_disk_0" -> "<remove, keep disk>"
            # (19 unchanged attributes hidden)
        }

        # (5 unchanged blocks hidden)
    }

Panic Output

no

Expected Behavior

A way to include/import the disk added externally into terraform config for the respective virtual machine.

Actual Behavior

Terraform is trying to delete the virtual disk added externally.

Steps to Reproduce

terraform plan

Environment Details

.

Screenshots

.

References

.

github-actions[bot] commented 1 year ago

Hello, dumpap! 🖐

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.

peterbaumert commented 2 months ago

Have you tried with lifecycle ignore_changes?

luanaBanana commented 4 weeks ago

I have a similar issue with additional disks created by with vsphere csi (kubernetes). Terraform wants to remove those disks. Have you found a solution?

lotusnoir commented 2 weeks ago

hello, i have a similar issue from a vm i've created some time ago.

      ~ disk {
          ~ label             = "orphaned_disk_0" -> "<remove, keep disk>"
            # (20 unchanged attributes hidden)
        }
      + disk {
          + attach           = false
          + controller_type  = "scsi"
          + datastore_id     = "datastore-5913"
          + disk_mode        = "persistent"
          + disk_sharing     = "sharingNone"
          + eagerly_scrub    = false
          + io_limit         = -1
          + io_reservation   = 0
          + io_share_count   = 0
          + io_share_level   = "normal"
          + keep_on_remove   = false
          + key              = 0
          + label            = "disk0"
          + size             = 65
          + thin_provisioned = true
          + unit_number      = 0
          + write_through    = false
        }

Dont know from where this state come from. I would like to increase the size of the disk so ignore in lifecycle is not an option.

I tried to unregister / register again the vm without success > https://docs.vmware.com/en/VMware-vSphere/6.5/com.vmware.vsphere.troubleshooting.doc/GUID-BFD8C9BC-30FB-4A92-AFEC-2FC9FF387920.html

I've quicky checks the uuid and the datastore path, they are good as well so :/ Maybe i need to edit the state manually in order to fix some wrong information ? any help is welcome