Skip to content

importing vm with clone / efi disk forces replacement #1988

@aquirdTurtle

Description

@aquirdTurtle

Describe the bug
The provider seems to not realize that an imported vm was originally cloned. It thinks it must add the cloned part of the state which forces replacement.

To Reproduce
Steps to reproduce the behavior:

  1. Create a cloned vm resource proxmox_virtual_environment_vm.test_vm
  2. Remove the vm from state tofu state rm proxmox_virtual_environment_vm.test_vm
  3. Re-import the vm tofu import proxmox_virtual_environment.test_vm <mynode>/<vmid>
  4. Check state tofu plan, notice that it wants to replace the vm.

Please also provide a minimal Terraform configuration that reproduces the issue.

resource "proxmox_virtual_environment_vm" "test_vm" {
  name = "test-vm"
  node_name = "my-node-name"
  agent {
    enabled = false
  }
  clone {
    vm_id = 1005
    full = false
  }
}

and the output of terraform|tofu apply.

> tofu plan
proxmox_virtual_environment_vm.test_vm: Refreshing state... [id=192]

OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

OpenTofu will perform the following actions:

  # proxmox_virtual_environment_vm.test_vm must be replaced
-/+ resource "proxmox_virtual_environment_vm" "test_vm" {
      ~ bios                    = "ovmf" -> "seabios"
      ~ id                      = "192" -> (known after apply)
      ~ ipv4_addresses          = [] -> (known after apply)
      ~ ipv6_addresses          = [] -> (known after apply)
      + keyboard_layout         = "en-us"
      ~ mac_addresses           = [
          - "BC:24:11:FA:A8:1E",
        ] -> (known after apply)
      - machine                 = "q35" -> null
      + migrate                 = false
        name                    = "test-vm"
      ~ network_interface_names = [] -> (known after apply)
      + on_boot                 = true
      + reboot                  = false
      + reboot_after_update     = true
      + stop_on_destroy         = false
      - tags                    = [
          - "24_04",
          - "cloudinit",
          - "ubuntu-template",
        ] -> null
      + timeout_clone           = 1800
      + timeout_create          = 1800
      + timeout_migrate         = 1800
      + timeout_move_disk       = 1800
      + timeout_reboot          = 1800
      + timeout_shutdown_vm     = 1800
      + timeout_start_vm        = 1800
      + timeout_stop_vm         = 300
      ~ vm_id                   = 192 -> (known after apply)
        # (7 unchanged attributes hidden)

      + agent {
          + enabled = false
          + timeout = "15m"
          + trim    = false
          + type    = "virtio"
        }

      + clone {
          + full    = false # forces replacement
          + retries = 1 # forces replacement
          + vm_id   = 1005 # forces replacement
        }

      - cpu {
          - cores      = 2 -> null
          - flags      = [] -> null
          - hotplugged = 0 -> null
          - limit      = 0 -> null
          - numa       = false -> null
          - sockets    = 1 -> null
          - type       = "host" -> null
          - units      = 1024 -> null
        }

      - disk {
          - aio               = "io_uring" -> null
          - backup            = true -> null
          - cache             = "none" -> null
          - datastore_id      = "vms_ssd" -> null
          - discard           = "on" -> null
          - file_format       = "raw" -> null
          - interface         = "virtio0" -> null
          - iothread          = false -> null
          - path_in_datastore = "vm-192-disk-1" -> null
          - replicate         = true -> null
          - size              = 64 -> null
          - ssd               = false -> null
        }

      - efi_disk { # forces replacement
          - datastore_id      = "vms_ssd" -> null
          - file_format       = "raw" -> null
          - pre_enrolled_keys = false -> null
          - type              = "2m" -> null
        }

      - initialization {
          - datastore_id = "vms_ssd" -> null
          - interface    = "scsi1" -> null

          - ip_config {
              - ipv4 {
                  - address = "dhcp" -> null
                }
            }

          - user_account {
              - keys     = [] -> null
              - password = (sensitive value) -> null
              - username = "atom" -> null
            }
        }

      - memory {
          - dedicated      = 2048 -> null
          - floating       = 0 -> null
          - keep_hugepages = false -> null
          - shared         = 0 -> null
        }

      ~ network_device {
          + acpi                    = (known after apply)
          + bios                    = (known after apply)
          + boot_order              = (known after apply)
          + description             = (known after apply)
          + hook_script_file_id     = (known after apply)
          + id                      = (known after apply)
          + ipv4_addresses          = (known after apply)
          + ipv6_addresses          = (known after apply)
          + keyboard_layout         = (known after apply)
          + kvm_arguments           = (known after apply)
          + mac_addresses           = (known after apply)
          + machine                 = (known after apply)
          + migrate                 = (known after apply)
          + name                    = (known after apply)
          + network_interface_names = (known after apply)
          + node_name               = (known after apply)
          + on_boot                 = (known after apply)
          + pool_id                 = (known after apply)
          + protection              = (known after apply)
          + reboot                  = (known after apply)
          + reboot_after_update     = (known after apply)
          + scsi_hardware           = (known after apply)
          + started                 = (known after apply)
          + stop_on_destroy         = (known after apply)
          + tablet_device           = (known after apply)
          + tags                    = (known after apply)
          + template                = (known after apply)
          + timeout_clone           = (known after apply)
          + timeout_create          = (known after apply)
          + timeout_migrate         = (known after apply)
          + timeout_move_disk       = (known after apply)
          + timeout_reboot          = (known after apply)
          + timeout_shutdown_vm     = (known after apply)
          + timeout_start_vm        = (known after apply)
          + timeout_stop_vm         = (known after apply)
          + vm_id                   = (known after apply)
        } -> (known after apply)

      - operating_system {
          - type = "l26" -> null
        }

      ~ vga {
          + acpi                    = (known after apply)
          + bios                    = (known after apply)
          + boot_order              = (known after apply)
          + description             = (known after apply)
          + hook_script_file_id     = (known after apply)
          + id                      = (known after apply)
          + ipv4_addresses          = (known after apply)
          + ipv6_addresses          = (known after apply)
          + keyboard_layout         = (known after apply)
          + kvm_arguments           = (known after apply)
          + mac_addresses           = (known after apply)
          + machine                 = (known after apply)
          + migrate                 = (known after apply)
          + name                    = (known after apply)
          + network_interface_names = (known after apply)
          + node_name               = (known after apply)
          + on_boot                 = (known after apply)
          + pool_id                 = (known after apply)
          + protection              = (known after apply)
          + reboot                  = (known after apply)
          + reboot_after_update     = (known after apply)
          + scsi_hardware           = (known after apply)
          + started                 = (known after apply)
          + stop_on_destroy         = (known after apply)
          + tablet_device           = (known after apply)
          + tags                    = (known after apply)
          + template                = (known after apply)
          + timeout_clone           = (known after apply)
          + timeout_create          = (known after apply)
          + timeout_migrate         = (known after apply)
          + timeout_move_disk       = (known after apply)
          + timeout_reboot          = (known after apply)
          + timeout_shutdown_vm     = (known after apply)
          + timeout_start_vm        = (known after apply)
          + timeout_stop_vm         = (known after apply)
          + vm_id                   = (known after apply)
        } -> (known after apply)
    }

Plan: 1 to add, 0 to change, 1 to destroy.

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so OpenTofu can't guarantee to take exactly these actions if you run "tofu apply" now.

Expected behavior
I would expect removing the vm from state and re-importing it to work without needing replacement.

I note that tofu also seems to want to remove a lot of state which was present from my template image that it cloned from, despite me not declaring anything about it in my resource config. This also seems not ideal but not a big deal as I can make my resource config reflect the template for these types of things. The issue with the clone however seems impossible to fix, so my options seem to be to recreate resources (which I can't for my actual use case) or to remove the clone section from my resource definition for the resources which I import.

Additional context
Add any other context about the problem here.

  • Single or clustered Proxmox: clustered
  • Proxmox version: 8.3
  • Provider version (ideally it should be the latest version): 0.78.1
  • Terraform/OpenTofu version: v1.9.0
  • OS (where you run Terraform/OpenTofu from): ubuntu server 24.04

Metadata

Metadata

Assignees

No one assigned

    Labels

    🐛 bugSomething isn't workingpriority:P2Medium priority

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions