8000 Field `file_id` not populated when importing vm, causing recreation · Issue #1998 · bpg/terraform-provider-proxmox · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Field file_id not populated when importing vm, causing recreation #1998
Open
@MacherelR

Description

@MacherelR

Describe the bug
When importing an existing VM that was originally created with a disk.file_id reference (e.g., pointing to a downloaded image), the provider does not populate the file_id field during the import. As a result, a subsequent terraform plan triggers a forced replacement of the VM, even though no actual configuration has changed.

To Reproduce
Steps to reproduce the behavior:

  1. Create a VM using proxmox_virtual_environment_vm with a disk.file_id referring to a proxmox_virtual_environment_download_file.

  2. Run terraform apply to create the VM. -> VM will be created and its file_id populated.

  3. Run terraform state rm proxmox_virtual_environment_vm.centos_vm to remove the VM from the Terraform state.

  4. Import the VM again using terraform import proxmox_virtual_environment_vm.centos_vm <node>/<vmid>. -> file_id field won't be populated.

  5. Run terraform plan.

  6. See that Terraform proposes to destroy and recreate the VM due to file_id mismatch (even though nothing has changed on the VM).

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

terraform {
  required_providers {
    proxmox = {
      source = "bpg/proxmox"
      version = "0.78.1"
    }
  }
}

provider "proxmox" {
  endpoint = var.virtual_environment_endpoint
  username = "root@pam"
  password = var.virtual_environment_password

  insecure = true
  ssh {
    agent = true
    username = var.virtual_environment_ssh_username
  }
}

resource "proxmox_virtual_environment_vm" "centos_vm" {
  name      = "test-centos"
  node_name = var.proxmox_node_name

  # should be true if qemu agent is not installed / enabled on the VM
  stop_on_destroy = true

  initialization {
    datastore_id = "local"
    user_account {
      # do not use this in production, configure your own ssh key instead!
      username = "xxxxx"
      password = "yyyyy"
    }
  }

  disk {
    datastore_id = "local"
    file_id      = proxmox_virtual_environment_download_file.centos_cloud_image.id
    interface    = "virtio0"
    iothread     = true
    discard      = "on"
    size         = 20
  }
}

resource "proxmox_virtual_environment_download_file" "centos_cloud_image" {
  content_type = "iso"
  datastore_id = "local"
  node_name    = var.proxmox_node_name
  url          = "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2"
  file_name    = "centos8.img"
}

and the output of terraform|tofu apply initially launched.

terraform apply                                                                                                                                                                                                                                                                                                                                           ─╯

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # proxmox_virtual_environment_download_file.centos_cloud_image will be created
  + resource "proxmox_virtual_environment_download_file" "centos_cloud_image" {
      + content_type        = "iso"
      + datastore_id        = "local"
      + file_name           = "centos8.img"
      + id                  = (known after apply)
      + node_name           = "bootstrap"
      + overwrite           = true
      + overwrite_unmanaged = false
      + size                = (known after apply)
      + upload_timeout      = 600
      + url                 = "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-latest.x86_64.qcow2"
      + verify              = true
    }

  # proxmox_virtual_environment_vm.centos_vm will be created
  + resource "proxmox_virtual_environment_vm" "centos_vm" {
      + acpi                    = true
      + bios                    = "seabios"
      + id                      = (known after apply)
      + ipv4_addresses          = (known after apply)
      + ipv6_addresses          = (known after apply)
      + keyboard_layout         = "en-us"
      + mac_addresses           = (known after apply)
      + migrate                 = false
      + name                    = "test-centos-remy"
      + network_interface_names = (known after apply)
      + node_name               = "bootstrap"
      + on_boot                 = true
      + protection              = false
      + reboot                  = false
      + reboot_after_update     = true
      + scsi_hardware           = "virtio-scsi-pci"
      + started                 = true
      + stop_on_destroy         = true
      + tablet_device           = true
      + template                = false
      + 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                   = (known after apply)

      + disk {
          + aio               = "io_uring"
          + backup            = true
          + cache             = "none"
          + datastore_id      = "local"
          + discard           = "on"
          + file_format       = (known after apply)
          + file_id           = (known after apply)
          + interface         = "virtio0"
          + iothread          = true
          + path_in_datastore = (known after apply)
          + replicate         = true
          + size              = 20
          + ssd               = false
        }

      + initialization {
          + datastore_id         = "local"
          + meta_data_file_id    = (known after apply)
          + network_data_file_id = (known after apply)
          + type                 = (known after apply)
          + user_data_file_id    = (known after apply)
          + vendor_data_file_id  = (known after apply)

          + user_account {
              + password = (sensitive value)
              + username = "user"
            }
        }

      + network_device (known after apply)

      + vga (known after apply)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

proxmox_virtual_environment_download_file.centos_cloud_image: Creating...
proxmox_virtual_environment_download_file.centos_cloud_image: Still creating... [00m10s elapsed]
proxmox_virtual_environment_download_file.centos_cloud_image: Still creating... [00m20s elapsed]
proxmox_virtual_environment_download_file.centos_cloud_image: Creation complete after 22s [id=local:iso/centos8.img]
proxmox_virtual_environment_vm.centos_vm: Creating...
proxmox_virtual_environment_vm.centos_vm: Still creating... [00m10s elapsed]
proxmox_virtual_environment_vm.centos_vm: Still creating... [00m20s elapsed]
proxmox_virtual_environment_vm.centos_vm: Still creating... [00m30s elapsed]
proxmox_virtual_environment_vm.centos_vm: Still creating... [00m40s elapsed]
proxmox_virtual_environment_vm.centos_vm: Still creating... [00m50s elapsed]
proxmox_virtual_environment_vm.centos_vm: Still creating... [01m00s elapsed]
proxmox_virtual_environment_vm.centos_vm: Still creating... [01m10s elapsed]
proxmox_virtual_environment_vm.centos_vm: Still creating... [01m20s elapsed]
proxmox_virtual_environment_vm.centos_vm: Still creating... [01m30s elapsed]
proxmox_virtual_environment_vm.centos_vm: Creation complete after 1m38s [id=100]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

the output of terraform|tofu plan after re-import:

terraform plan                                                                                                                                                                                                                                                                                                                                            ─╯
proxmox_virtual_environment_download_file.centos_cloud_image: Refreshing state... [id=local:iso/centos8.img]
proxmox_virtual_environment_vm.centos_vm: Refreshing state... [id=100]

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

Terraform will perform the following actions:

  # proxmox_virtual_environment_vm.centos_vm must be replaced
-/+ resource "proxmox_virtual_environment_vm" "centos_vm" {
      ~ id                      = "100" -> (known after apply)
      ~ ipv4_addresses          = [] -> (known after apply)
      ~ ipv6_addresses          = [] -> (known after apply)
      ~ mac_addresses           = [] -> (known after apply)
      + migrate                 = false
        name                    = "test-centos-remy"
      ~ network_interface_names = [] -> (known after apply)
      + on_boot                 = true
      + reboot                  = false
      + reboot_after_update     = true
      + stop_on_destroy         = true
      - tags                    = [] -> 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                   = 100 -> (known after apply)
        # (12 unchanged attributes hidden)

      ~ disk {
          ~ file_format       = "qcow2" -> (known after apply)
          + file_id           = "local:iso/centos8.img" # forces replacement
          ~ path_in_datastore = "100/vm-100-disk-0.qcow2" -> (known after apply)
            # (11 unchanged attributes hidden)
        }

      ~ initialization {
          - interface            = "ide2" -> null
          + meta_data_file_id    = (known after apply)
          + network_data_file_id = (known after apply)
          + type                 = (known after apply)
          + user_data_file_id    = (known after apply)
          + vendor_data_file_id  = (known after apply)
            # (1 unchanged attribute hidden)

          ~ user_account {
              - keys     = [] -> null
              ~ password = (sensitive value)
                # (1 unchanged attribute hidden)
            }
        }

      ~ network_device (known after apply)

      ~ vga (known after apply)
    }

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

Expected behavior
After importing the VM, Terraform should detect that the actual state of the VM matches the configuration. It should not try to replace the VM just because file_id is missing from state — ideally, the provider should populate it during the import/read phase, or at least not trigger a diff if it cannot.

Additional context
My guess is the provider's Read logic does actually not populate the disk.file_id field after import.
I'd gladly try to fix but as I didn't participate to the vm logic in the provider I'd be scared of breaking something 😆

  • Proxmox version: 8.4.1
  • Provider version (ideally it should be the latest version): 0.78.1
  • Terraform/OpenTofu version: v1.12.2
  • OS (where you run Terraform/OpenTofu from): Ubuntu 24.04.2

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    ☑️ Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0