Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking change in 0.25.0 - all instances that use cloud_config must be replaced due to destroy_cloud_config_vdi_after_boot #267

Closed
InputObject2 opened this issue Oct 5, 2023 · 8 comments

Comments

@InputObject2
Copy link

InputObject2 commented Oct 5, 2023

The addition of destroy_cloud_config_vdi_after_boot in #255 adds a new field to all existing VM instances.

Since it forces recreation on change (going from null to true/false in the case of existing VM's), terraform will destroy any existing virtual machines that doesn't specifically ignore_changes on it.

For example, when nothing is specified:

# xenorchestra_vm.ubuntu must be replaced
-/+ resource "xenorchestra_vm" "ubuntu" {
      - blocked_operations                  = [] -> null
      + destroy_cloud_config_vdi_after_boot = false # forces replacement

Anyway the quick and easy solution is to add a lifecycle ignore_changes to the VM instances, but this seems like something that could impact some users.

lifecycle {
    ignore_changes = [ destroy_cloud_config_vdi_after_boot ]
  }

So I guess my question is: was this an intentional effect in 0.25.0? If yes, that seems like something that should be in the release notes.

@ddelnano
Copy link
Collaborator

ddelnano commented Oct 5, 2023

@InputObject2 it was not intended to be a breaking change. It was an oversight during the testing the change and I apologize for that. I need to research the best way to apply the default value, but my current thinking is that the plan diff should be customized to ignore this condition or the state needs to be explicitly migrated to apply the default value.

@ddelnano
Copy link
Collaborator

ddelnano commented Oct 5, 2023

It seems it should be possible to write an acceptance test for the type of state migration I explained above (hashicorp/terraform-plugin-sdk#253 (comment)).

I have a code change that I believe should address the problem, but I need to further investigate the acceptance test portion of it.

@ddelnano
Copy link
Collaborator

ddelnano commented Oct 5, 2023

@InputObject2 can you provide detailed steps for reproducing the issue (terraform version, provider version before, terraform code for the VM)?

I tried to reproduce it through this acceptance test, which simulates creating a VM with v0.24.2 of the provider followed by a terraform plan with v0.25.0. I was expected the second step to have a non empty plan with the diff you provided, however, the plan is empty. I thought that this issue might be terraform version dependent, so I ran the test with v0.14.11 and v1.6.0 but I didn't see any difference in behavior.

terraform acc test
TEST=TestAccXenorchestraVm_createWithV0StateMigration make testacc

=== RUN   TestAccXenorchestraVm_createWithV0StateMigration
=== PAUSE TestAccXenorchestraVm_createWithV0StateMigration
=== CONT  TestAccXenorchestraVm_createWithV0StateMigration
    resource_xenorchestra_vm_test.go:1480: Step 2/2 error: Expected a non-empty plan, but got an empty plan
--- FAIL: TestAccXenorchestraVm_createWithV0StateMigration (81.51s)
FAIL
[DEBUG] Running sweeper
FAIL    github.com/ddelnano/terraform-provider-xenorchestra/xoa 110.467s
FAIL
make: *** [Makefile:40: testacc] Error 1

# Testing against terraform 1.6.0
export TF_ACC_TERRAFORM_VERSION=1.6.0
TEST=TestAccXenorchestraVm_createWithV0StateMigration make testacc

# Fails with the same error

I also performed the same test manually and could not reproduce the issue.

Manual test output
acaddress.mac: Refreshing state... [id=00:aa:af:cb:12:42]
xenorchestra_cloud_config.bar: Refreshing state... [id=051e055b-cbd0-4f16-843a-de55376ac96b]
xenorchestra_vm.vm: Refreshing state... [id=7af4a81c-fa5d-9b5b-e864-15564c02ff7f]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # xenorchestra_vm.vm will be created
  + resource "xenorchestra_vm" "vm" {
      + auto_poweron      = false
      + cloud_config      = <<-EOT
            #cloud-config
            package_upgrade: true
        EOT
      + core_os           = false
      + cpu_cap           = 0
      + cpu_weight        = 0
      + cpus              = 1
      + exp_nested_hvm    = false
      + hvm_boot_firmware = "bios"
      + id                = (known after apply)
      + ipv4_addresses    = (known after apply)
      + ipv6_addresses    = (known after apply)
      + memory_max        = 2147467264
      + name_label        = "XO terraform testing"
      + power_state       = (known after apply)
      + start_delay       = 0
      + template          = "9b0fd2ac-c89a-93b4-5103-8506391395cd"
      + vga               = "std"
      + videoram          = 8
      + wait_for_ip       = false

      + disk {
          + name_label = "VM root volume"
          + position   = (known after apply)
          + size       = 4294967296
          + sr_id      = "86a9757d-9c05-9fe0-e79a-8243cb1f37f3"
          + vbd_id     = (known after apply)
          + vdi_id     = (known after apply)
        }

      + network {
          + device         = (known after apply)
          + ipv4_addresses = (known after apply)
          + ipv6_addresses = (known after apply)
          + mac_address    = (known after apply)
          + network_id     = "6c4e1cdc-9fe0-0603-e53d-4790d1fce8dd"
        }
    }

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

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

ddelnano@ddelnano-desktop:~/code/terraform/xolab (master) $ terraform apply
macaddress.mac: Refreshing state... [id=00:aa:af:cb:12:42]
xenorchestra_cloud_config.bar: Refreshing state... [id=051e055b-cbd0-4f16-843a-de55376ac96b]
xenorchestra_vm.vm: Refreshing state... [id=7af4a81c-fa5d-9b5b-e864-15564c02ff7f]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # xenorchestra_vm.vm will be created
  + resource "xenorchestra_vm" "vm" {
      + auto_poweron      = false
      + cloud_config      = <<-EOT
            #cloud-config
            package_upgrade: true
        EOT
      + core_os           = false
      + cpu_cap           = 0
      + cpu_weight        = 0
      + cpus              = 1
      + exp_nested_hvm    = false
      + hvm_boot_firmware = "bios"
      + id                = (known after apply)
      + ipv4_addresses    = (known after apply)
      + ipv6_addresses    = (known after apply)
      + memory_max        = 2147467264
      + name_label        = "XO terraform testing"
      + power_state       = (known after apply)
      + start_delay       = 0
      + template          = "9b0fd2ac-c89a-93b4-5103-8506391395cd"
      + vga               = "std"
      + videoram          = 8
      + wait_for_ip       = false

      + disk {
          + name_label = "VM root volume"
          + position   = (known after apply)
          + size       = 4294967296
          + sr_id      = "86a9757d-9c05-9fe0-e79a-8243cb1f37f3"
          + vbd_id     = (known after apply)
          + vdi_id     = (known after apply)
        }

      + network {
          + device         = (known after apply)
          + ipv4_addresses = (known after apply)
          + ipv6_addresses = (known after apply)
          + mac_address    = (known after apply)
          + network_id     = "6c4e1cdc-9fe0-0603-e53d-4790d1fce8dd"
        }
    }

Plan: 1 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

xenorchestra_vm.vm: Creating...
xenorchestra_vm.vm: Still creating... [10s elapsed]
xenorchestra_vm.vm: Still creating... [20s elapsed]
xenorchestra_vm.vm: Creation complete after 20s [id=b8aab65b-95bf-6274-a7bf-57703d581109]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
ddelnano@ddelnano-desktop:~/code/terraform/xolab (master) $ terraform state list
data.xenorchestra_network.network
data.xenorchestra_pool.pool
data.xenorchestra_sr.sr
data.xenorchestra_template.vm_template
macaddress.mac
xenorchestra_cloud_config.bar
xenorchestra_vm.vm

ddelnano@ddelnano-desktop:~/code/terraform/xolab (master) $ terraform state show xenorchestra_vm.vm
# xenorchestra_vm.vm:
resource "xenorchestra_vm" "vm" {
    auto_poweron      = false
    cloud_config      = <<-EOT
        #cloud-config
        package_upgrade: true
    EOT
    core_os           = false
    cpu_cap           = 0
    cpu_weight        = 0
    cpus              = 1
    exp_nested_hvm    = false
    hvm_boot_firmware = "bios"
    id                = "b8aab65b-95bf-6274-a7bf-57703d581109"
    ipv4_addresses    = []
    ipv6_addresses    = []
    memory_max        = 2147467264
    name_label        = "XO terraform testing"
    power_state       = "Running"
    start_delay       = 0
    template          = "9b0fd2ac-c89a-93b4-5103-8506391395cd"
    vga               = "std"
    videoram          = 8
    wait_for_ip       = false

    disk {
        attached   = true
        name_label = "VM root volume"
        position   = "0"
        size       = 4294967296
        sr_id      = "86a9757d-9c05-9fe0-e79a-8243cb1f37f3"
        vbd_id     = "12609971-b1ef-4d30-3113-87da16ac3587"
        vdi_id     = "e154f19a-ba3d-4a65-9254-40e811dce529"
    }

    network {
        attached       = true
        device         = "0"
        ipv4_addresses = []
        ipv6_addresses = []
        mac_address    = "02:6b:02:3b:2a:e6"
        network_id     = "6c4e1cdc-9fe0-0603-e53d-4790d1fce8dd"
    }
}
ddelnano@ddelnano-desktop:~/code/terraform/xolab (master) $ terraform init -upgrade

Initializing the backend...

Initializing provider plugins...
- Finding ivoronin/macaddress versions matching "0.3.0"...
- Finding terra-farm/xenorchestra versions matching "0.25.0"...
- Finding hashicorp/http versions matching "3.2.1"...
- Finding hashicorp/local versions matching "2.2.3"...
- Using previously-installed hashicorp/http v3.2.1
- Using previously-installed hashicorp/local v2.2.3
- Using previously-installed ivoronin/macaddress v0.3.0
- Installing terra-farm/xenorchestra v0.25.0...
- Installed terra-farm/xenorchestra v0.25.0 (self-signed, key ID 6A6E2EACF91F3875)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has made some changes to the provider dependency selections recorded
in the .terraform.lock.hcl file. Review those changes and commit them to your
version control system if they represent changes you intended to make.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
ddelnano@ddelnano-desktop:~/code/terraform/xolab (master) $ terraform plan
macaddress.mac: Refreshing state... [id=00:aa:af:cb:12:42]
xenorchestra_cloud_config.bar: Refreshing state... [id=051e055b-cbd0-4f16-843a-de55376ac96b]
xenorchestra_vm.vm: Refreshing state... [id=b8aab65b-95bf-6274-a7bf-57703d581109]

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
ddelnano@ddelnano-desktop:~/code/terraform/xolab (master) $ terraform --version
Terraform v0.14.11
+ provider registry.terraform.io/hashicorp/http v3.2.1
+ provider registry.terraform.io/hashicorp/local v2.2.3
+ provider registry.terraform.io/ivoronin/macaddress v0.3.0
+ provider registry.terraform.io/terra-farm/xenorchestra v0.25.0

Your version of Terraform is out of date! The latest version
is 1.6.0. You can update by downloading from https://www.terraform.io/downloads.html

@InputObject2
Copy link
Author

InputObject2 commented Oct 5, 2023

Hi! Thanks for diving into this so quick!

This is a bit of a long post but here we go.
Here are my versions:

current: terraform 1.5.7, provider v.0.25.0
previous: terraform 1.5.7, provider v0.24.2

Steps

1- Terraform setup with v0.24.2

Here's some terraform code for it:

Terraform full code
terraform {
  required_providers {
    xenorchestra = {
      source  = "terra-farm/xenorchestra"
      version = "0.24.2"
    }
  }
}

provider "xenorchestra" {}

variable "instance_os_disk_xoa_sr_uuid" {
    default = "b1280ccc-2d73-6d34-8285-78ad87a5c4d1"
}
variable "instance_xoa_template_uuid" {
    default = "c1a888dc-8cc7-9444-f995-391a92a9af07"
}
variable "instance_xoa_network" {
    default = "7c2a2531-1298-495c-edd2-fad16e7c2226"
}
variable "public_ssh_key" {
    default = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvUQ/2WaIYub7Ns8psnOPoYaaArZcoRrfTtDDHXruSZfOnbPrvfFInuIdI11AxwodzKILv8oeUOqmFSpmGOBZn4Hy1An2eM39WG8025JKNE9UainAfKlpX8HgMeSyqdT7X50HI7LsgUYvrbW4tPnLt9Dh+Wsgn9+ErQsE0Hj8IExZv9O/YDLJ6Lin3nD775ncXvHbI1nFfcTmJ/kW9NXvyP+AJYVrbP1hxC72BNQfbJWvhYymyDAhEhzFudCjz420ajqrWwsNzJIAV4P3gVWHUNVntllqJtf60EoQhKTAPZxl3Pm+OgneG8zLMC4PkSeXG4nw26kmusH7CLxd/BX3DrlXLpdvL7RMbDuwl/b183HoKsCfx9kAID6KVB1qCLRw/E5g/F6EeIhK4n2Tr/82PIi3Iw3N93PyfLAjn9HmAgQnXW/uQCqwR2+s5uPflysOTRExxIEIaZsWSaTrgte1+33dIQMpYK7YgpYNncuQGYGZH1cxYYbs0Y8UheQ5i0mgSzsTQWY+VPnZRgAGZ2Wmz+1Ndr8AaHvzL81DLGl8355wfXiuK06eTqRzAaepIUZGAanVwllCm4XFVVzeIPIFcnfcVTnsCJ0xcDFQxdUlsrRGdD04fQu1ioX1lhT0P03VA1thUtKRkmo+thT2bOwZV+eZeGzaHxQe21WQmKU/WDQ== cloud-user@localhost"
}

data "local_file" "cloud_network_config" {
  filename = "templates/cloud_network_config.yaml"
}

resource "xenorchestra_cloud_config" "test" {
  name  = "repro-test"
  template = <<EOF
#cloud-config
hostname: "repro-test"

users:
  - name: cloud-user
    gecos: cloud-user
    shell: /bin/bash
    sudo: ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_keys:
      - ${var.public_ssh_key}

packages:
  - ca_root_nss
EOF
}

resource "xenorchestra_vm" "instance" {
  name_label           = "test-repro"
  cloud_config         = xenorchestra_cloud_config.test.template
  cloud_network_config = data.local_file.cloud_network_config.content
  template             = var.instance_xoa_template_uuid
  auto_poweron         = true

 network {
      network_id  = var.instance_xoa_network
    }

  disk {
    sr_id      = var.instance_os_disk_xoa_sr_uuid
    name_label = "test-repro"
    size       = 10 * 1024 * 1024 * 1024 # GB to B
  }

  cpus       = 2
  memory_max = 2 * 1024 * 1024 * 1024 # GB to B

  wait_for_ip = false
}

2- Terraform init

Terraform init
terraform init

Initializing the backend...

Initializing provider plugins...
- Finding terra-farm/xenorchestra versions matching "0.24.2"...
- Finding latest version of hashicorp/local...
- Installing terra-farm/xenorchestra v0.24.2...
- Installed terra-farm/xenorchestra v0.24.2 (self-signed, key ID 6A6E2EACF91F3875)
- Installing hashicorp/local v2.4.0...
- Installed hashicorp/local v2.4.0 (signed by HashiCorp)

3- Terraform plan

Terraform plan in v0.24.2
terraform plan
data.local_file.cloud_network_config: Reading...
data.local_file.cloud_network_config: Read complete after 0s [id=a0f68fd5efd854626b32e9305902189d3f626b1f]

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:

  # xenorchestra_cloud_config.test will be created
  + resource "xenorchestra_cloud_config" "test" {
      + id       = (known after apply)
      + name     = "repro-test"
      + template = <<-EOT
            #cloud-config
            hostname: "repro-test"

            users:
              - name: cloud-user
                gecos: cloud-user
                shell: /bin/bash
                sudo: ALL=(ALL) NOPASSWD:ALL
                ssh_authorized_keys:
                  - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvUQ/2WaIYub7Ns8psnOPoYaaArZcoRrfTtDDHXruSZfOnbPrvfFInuIdI11AxwodzKILv8oeUOqmFSpmGOBZn4Hy1An2eM39WG8025JKNE9UainAfKlpX8HgMeSyqdT7X50HI7LsgUYvrbW4tPnLt9Dh+Wsgn9+ErQsE0Hj8IExZv9O/YDLJ6Lin3nD775ncXvHbI1nFfcTmJ/kW9NXvyP+AJYVrbP1hxC72BNQfbJWvhYymyDAhEhzFudCjz420ajqrWwsNzJIAV4P3gVWHUNVntllqJtf60EoQhKTAPZxl3Pm+OgneG8zLMC4PkSeXG4nw26kmusH7CLxd/BX3DrlXLpdvL7RMbDuwl/b183HoKsCfx9kAID6KVB1qCLRw/E5g/F6EeIhK4n2Tr/82PIi3Iw3N93PyfLAjn9HmAgQnXW/uQCqwR2+s5uPflysOTRExxIEIaZsWSaTrgte1+33dIQMpYK7YgpYNncuQGYGZH1cxYYbs0Y8UheQ5i0mgSzsTQWY+VPnZRgAGZ2Wmz+1Ndr8AaHvzL81DLGl8355wfXiuK06eTqRzAaepIUZGAanVwllCm4XFVVzeIPIFcnfcVTnsCJ0xcDFQxdUlsrRGdD04fQu1ioX1lhT0P03VA1thUtKRkmo+thT2bOwZV+eZeGzaHxQe21WQmKU/WDQ== cloud-user@localhost

            packages:
              - ca_root_nss
        EOT
    }

  # xenorchestra_vm.instance will be created
  + resource "xenorchestra_vm" "instance" {
      + auto_poweron         = true
      + cloud_config         = <<-EOT
            #cloud-config
            hostname: "repro-test"

            users:
              - name: cloud-user
                gecos: cloud-user
                shell: /bin/bash
                sudo: ALL=(ALL) NOPASSWD:ALL
                ssh_authorized_keys:
                  - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvUQ/2WaIYub7Ns8psnOPoYaaArZcoRrfTtDDHXruSZfOnbPrvfFInuIdI11AxwodzKILv8oeUOqmFSpmGOBZn4Hy1An2eM39WG8025JKNE9UainAfKlpX8HgMeSyqdT7X50HI7LsgUYvrbW4tPnLt9Dh+Wsgn9+ErQsE0Hj8IExZv9O/YDLJ6Lin3nD775ncXvHbI1nFfcTmJ/kW9NXvyP+AJYVrbP1hxC72BNQfbJWvhYymyDAhEhzFudCjz420ajqrWwsNzJIAV4P3gVWHUNVntllqJtf60EoQhKTAPZxl3Pm+OgneG8zLMC4PkSeXG4nw26kmusH7CLxd/BX3DrlXLpdvL7RMbDuwl/b183HoKsCfx9kAID6KVB1qCLRw/E5g/F6EeIhK4n2Tr/82PIi3Iw3N93PyfLAjn9HmAgQnXW/uQCqwR2+s5uPflysOTRExxIEIaZsWSaTrgte1+33dIQMpYK7YgpYNncuQGYGZH1cxYYbs0Y8UheQ5i0mgSzsTQWY+VPnZRgAGZ2Wmz+1Ndr8AaHvzL81DLGl8355wfXiuK06eTqRzAaepIUZGAanVwllCm4XFVVzeIPIFcnfcVTnsCJ0xcDFQxdUlsrRGdD04fQu1ioX1lhT0P03VA1thUtKRkmo+thT2bOwZV+eZeGzaHxQe21WQmKU/WDQ== cloud-user@localhost

            packages:
              - ca_root_nss
        EOT
      + cloud_network_config = <<-EOT
            network:
              version: 1
              config:
              - type: physical
                name: xn0
                subnets:
                - type: dhcp
        EOT
      + core_os              = false
      + cpu_cap              = 0
      + cpu_weight           = 0
      + cpus                 = 2
      + exp_nested_hvm       = false
      + hvm_boot_firmware    = "bios"
      + id                   = (known after apply)
      + ipv4_addresses       = (known after apply)
      + ipv6_addresses       = (known after apply)
      + memory_max           = 2147483648
      + name_label           = "test-repro"
      + power_state          = (known after apply)
      + start_delay          = 0
      + template             = "c1a888dc-8cc7-9444-f995-391a92a9af07"
      + vga                  = "std"
      + videoram             = 8
      + wait_for_ip          = false

      + disk {
          + name_label = "test-repro"
          + position   = (known after apply)
          + size       = 10737418240
          + sr_id      = "b1280ccc-2d73-6d34-8285-78ad87a5c4d1"
          + vbd_id     = (known after apply)
          + vdi_id     = (known after apply)
        }

      + network {
          + device         = (known after apply)
          + ipv4_addresses = (known after apply)
          + ipv6_addresses = (known after apply)
          + mac_address    = (known after apply)
          + network_id     = "7c2a2531-1298-495c-edd2-fad16e7c2226"
        }
    }

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

4- Terraform apply

Terraform apply in v0.24.2
terraform apply
data.local_file.cloud_network_config: Reading...
data.local_file.cloud_network_config: Read complete after 0s [id=a0f68fd5efd854626b32e9305902189d3f626b1f]

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:

  # xenorchestra_cloud_config.test will be created
  + resource "xenorchestra_cloud_config" "test" {
      + id       = (known after apply)
      + name     = "repro-test"
      + template = <<-EOT
            #cloud-config
            hostname: "repro-test"

            users:
              - name: cloud-user
                gecos: cloud-user
                shell: /bin/bash
                sudo: ALL=(ALL) NOPASSWD:ALL
                ssh_authorized_keys:
                  - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvUQ/2WaIYub7Ns8psnOPoYaaArZcoRrfTtDDHXruSZfOnbPrvfFInuIdI11AxwodzKILv8oeUOqmFSpmGOBZn4Hy1An2eM39WG8025JKNE9UainAfKlpX8HgMeSyqdT7X50HI7LsgUYvrbW4tPnLt9Dh+Wsgn9+ErQsE0Hj8IExZv9O/YDLJ6Lin3nD775ncXvHbI1nFfcTmJ/kW9NXvyP+AJYVrbP1hxC72BNQfbJWvhYymyDAhEhzFudCjz420ajqrWwsNzJIAV4P3gVWHUNVntllqJtf60EoQhKTAPZxl3Pm+OgneG8zLMC4PkSeXG4nw26kmusH7CLxd/BX3DrlXLpdvL7RMbDuwl/b183HoKsCfx9kAID6KVB1qCLRw/E5g/F6EeIhK4n2Tr/82PIi3Iw3N93PyfLAjn9HmAgQnXW/uQCqwR2+s5uPflysOTRExxIEIaZsWSaTrgte1+33dIQMpYK7YgpYNncuQGYGZH1cxYYbs0Y8UheQ5i0mgSzsTQWY+VPnZRgAGZ2Wmz+1Ndr8AaHvzL81DLGl8355wfXiuK06eTqRzAaepIUZGAanVwllCm4XFVVzeIPIFcnfcVTnsCJ0xcDFQxdUlsrRGdD04fQu1ioX1lhT0P03VA1thUtKRkmo+thT2bOwZV+eZeGzaHxQe21WQmKU/WDQ== cloud-user@localhost

            packages:
              - ca_root_nss
        EOT
    }

  # xenorchestra_vm.instance will be created
  + resource "xenorchestra_vm" "instance" {
      + auto_poweron         = true
      + cloud_config         = <<-EOT
            #cloud-config
            hostname: "repro-test"

            users:
              - name: cloud-user
                gecos: cloud-user
                shell: /bin/bash
                sudo: ALL=(ALL) NOPASSWD:ALL
                ssh_authorized_keys:
                  - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCvUQ/2WaIYub7Ns8psnOPoYaaArZcoRrfTtDDHXruSZfOnbPrvfFInuIdI11AxwodzKILv8oeUOqmFSpmGOBZn4Hy1An2eM39WG8025JKNE9UainAfKlpX8HgMeSyqdT7X50HI7LsgUYvrbW4tPnLt9Dh+Wsgn9+ErQsE0Hj8IExZv9O/YDLJ6Lin3nD775ncXvHbI1nFfcTmJ/kW9NXvyP+AJYVrbP1hxC72BNQfbJWvhYymyDAhEhzFudCjz420ajqrWwsNzJIAV4P3gVWHUNVntllqJtf60EoQhKTAPZxl3Pm+OgneG8zLMC4PkSeXG4nw26kmusH7CLxd/BX3DrlXLpdvL7RMbDuwl/b183HoKsCfx9kAID6KVB1qCLRw/E5g/F6EeIhK4n2Tr/82PIi3Iw3N93PyfLAjn9HmAgQnXW/uQCqwR2+s5uPflysOTRExxIEIaZsWSaTrgte1+33dIQMpYK7YgpYNncuQGYGZH1cxYYbs0Y8UheQ5i0mgSzsTQWY+VPnZRgAGZ2Wmz+1Ndr8AaHvzL81DLGl8355wfXiuK06eTqRzAaepIUZGAanVwllCm4XFVVzeIPIFcnfcVTnsCJ0xcDFQxdUlsrRGdD04fQu1ioX1lhT0P03VA1thUtKRkmo+thT2bOwZV+eZeGzaHxQe21WQmKU/WDQ== cloud-user@localhost

            packages:
              - ca_root_nss
        EOT
      + cloud_network_config = <<-EOT
            network:
              version: 1
              config:
              - type: physical
                name: xn0
                subnets:
                - type: dhcp
        EOT
      + core_os              = false
      + cpu_cap              = 0
      + cpu_weight           = 0
      + cpus                 = 2
      + exp_nested_hvm       = false
      + hvm_boot_firmware    = "bios"
      + id                   = (known after apply)
      + ipv4_addresses       = (known after apply)
      + ipv6_addresses       = (known after apply)
      + memory_max           = 2147483648
      + name_label           = "test-repro"
      + power_state          = (known after apply)
      + start_delay          = 0
      + template             = "c1a888dc-8cc7-9444-f995-391a92a9af07"
      + vga                  = "std"
      + videoram             = 8
      + wait_for_ip          = false

      + disk {
          + name_label = "test-repro"
          + position   = (known after apply)
          + size       = 10737418240
          + sr_id      = "b1280ccc-2d73-6d34-8285-78ad87a5c4d1"
          + vbd_id     = (known after apply)
          + vdi_id     = (known after apply)
        }

      + network {
          + device         = (known after apply)
          + ipv4_addresses = (known after apply)
          + ipv6_addresses = (known after apply)
          + mac_address    = (known after apply)
          + network_id     = "7c2a2531-1298-495c-edd2-fad16e7c2226"
        }
    }

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

xenorchestra_cloud_config.test: Creating...
xenorchestra_cloud_config.test: Creation complete after 0s [id=d7b437bc-969c-4bc1-83d0-65b1cd01ba8e]
xenorchestra_vm.instance: Creating...
xenorchestra_vm.instance: Creation complete after 8s [id=33b5ddb6-c126-7de9-cd58-329d29da5c48]

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

4- Set version in the provider and terraform init -upgrade

Terraform provider 0.25.0
terraform {
  required_providers {
    xenorchestra = {
      source  = "terra-farm/xenorchestra"
      version = "0.25.0"
    }
  }
}

Then upgrade the provider

Terraform init -upgrade
terraform init -upgrade

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/local...
- Finding terra-farm/xenorchestra versions matching "0.25.0"...
- Using previously-installed hashicorp/local v2.4.0
- Installing terra-farm/xenorchestra v0.25.0...
- Installed terra-farm/xenorchestra v0.25.0 (self-signed, key ID 6A6E2EACF91F3875)

5- Terraform plan again

Terraform plan in v0.25.0
terraform plan
data.local_file.cloud_network_config: Reading...
data.local_file.cloud_network_config: Read complete after 0s [id=a0f68fd5efd854626b32e9305902189d3f626b1f]
xenorchestra_cloud_config.test: Refreshing state... [id=d7b437bc-969c-4bc1-83d0-65b1cd01ba8e]
xenorchestra_vm.instance: Refreshing state... [id=33b5ddb6-c126-7de9-cd58-329d29da5c48]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

It seems to be hit or miss as to why Terraform decides to see the added property, but changing litteraly anything (in my case I set name_description = "test") and terraform will decide it now sees the parameter and destroys the vm.

resource "xenorchestra_vm" "instance" {
  [...]
  name_description =  "test"

Then if we plan again, now it's detected, and even though name_description is not something that usually needs instance destroyed...

Terraform plan in v0.25.0 with any other changes
terraform plan
data.local_file.cloud_network_config: Reading...
data.local_file.cloud_network_config: Read complete after 0s [id=a0f68fd5efd854626b32e9305902189d3f626b1f]
xenorchestra_cloud_config.test: Refreshing state... [id=d7b437bc-969c-4bc1-83d0-65b1cd01ba8e]
xenorchestra_vm.instance: Refreshing state... [id=33b5ddb6-c126-7de9-cd58-329d29da5c48]

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:

  # xenorchestra_vm.instance must be replaced
-/+ resource "xenorchestra_vm" "instance" {
      - blocked_operations                  = [] -> null
      + destroy_cloud_config_vdi_after_boot = false # forces replacement
      ~ id                                  = "33b5ddb6-c126-7de9-cd58-329d29da5c48" -> (known after apply)
      ~ ipv4_addresses                      = [] -> (known after apply)
      ~ ipv6_addresses                      = [] -> (known after apply)
      + name_description                    = "test"
      ~ power_state                         = "Running" -> (known after apply)
      - tags                                = [] -> null
        # (16 unchanged attributes hidden)

      ~ disk {
          - attached   = true -> null
          ~ position   = "0" -> (known after apply)
          ~ vbd_id     = "952f2645-e014-1975-0a2e-b0ceac2facda" -> (known after apply)
          ~ vdi_id     = "ce5d24d5-eb8e-491a-b033-b03308211006" -> (known after apply)
            # (3 unchanged attributes hidden)
        }

      ~ network {
          - attached       = true -> null
          ~ device         = "0" -> (known after apply)
          ~ ipv4_addresses = [] -> (known after apply)
          ~ ipv6_addresses = [] -> (known after apply)
          ~ mac_address    = "4a:38:dc:3a:a2:d5" -> (known after apply)
            # (1 unchanged attribute hidden)
        }
    }

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

@ddelnano
Copy link
Collaborator

ddelnano commented Oct 6, 2023

@InputObject2 thanks for the detailed information. I'm able to reproduce it in my acceptance test now 👍

@ddelnano
Copy link
Collaborator

ddelnano commented Oct 7, 2023

Unfortunately the state migration testing capability requires terraform-plugin-sdk v2.23.0 or later and a newer go version. Since it's been a while since the sdk has been upgraded, I'm going to upgrade it to the latest version (v2.29.0) as a prerequisite.

I don't believe there will be any complications with upgrading, but our nightly CI that was recently put into place hard codes the given go version. So in addition to the sdk and go upgrade, I need to enhance CI to support parameterizing the Go version before making that change. This should pave the way for testing the provider against different terraform versions and opentofu as well.

@ddelnano
Copy link
Collaborator

ddelnano commented Oct 9, 2023

I decided to hold off on the build work that I mentioned above. I was able to get the terraform-provider-sdk and the go upgrade tested without too much trouble. I'll try to get the fix for this merged in this week and make a release around the same time frame.

@ddelnano
Copy link
Collaborator

This will be fixed in v0.25.1, which will be released shortly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants