vmware / terraform-provider-vcd

Terraform VMware Cloud Director provider
https://www.terraform.io/docs/providers/vcd/
Mozilla Public License 2.0
151 stars 112 forks source link

Problem using "vapp_template_id" instead of "catalog_name" and "template_name" #1045

Open jl0815 opened 1 year ago

jl0815 commented 1 year ago

Hello,

I have an Org + catalog in my VCD environment for VM templates that are published to all other orgs. These templates are recreated every month with current patch level, tested and then uploaded to the public catalog. The existing template there will be overwritten. However, this changes the ID of the templates. This results in VMs created from the template being deleted and recreated by Terraform. To work around this, instead of "vapp_template_id" I can use "catalog_name" and "template_name". But these two parameters are marked as deprecated.

Kind regards, Jan

Terraform Version

Terraform v1.4.4 on windows_amd64

Affected Resource(s)

Please list the resources as a list, for example:

Terraform Configuration Files

data "vcd_org_vdc" "orgvdc" {
  name = "orgvdc name"
}

data "vcd_catalog" "templates-catalog" {
  name = "templates"
  org = "templates"
}

data "vcd_catalog_vapp_template" "ubuntu_template" {
  catalog_id  = data.vcd_catalog.templates-catalog.id
  name        = "ubuntu"
}

resource "vcd_vm" "ubuntu01" {
  vdc                     = data.vcd_org_vdc.orgvdc.name
  vapp_template_id        = data.vcd_catalog_vapp_template.ubuntu_template.id
  name                    = "ubuntu01"
  computer_name           = "ubuntu01"
  memory                  = 4096
  cpus                    = 2
  cpu_cores               = 2
  storage_profile         = "storage profile name"
  power_on                = true

  override_template_disk {
    bus_type          = "paravirtual"
    size_in_mb        = 40960
    bus_number        = 0
    unit_number       = 0
    iops              = 0
  }
  network {
    type                = "org"
    name                = vcd_network_routed_v2.ovdc_net_01.name
    ip_allocation_mode  = "POOL"
    is_primary          = true
  }
  customization {
    allow_local_admin_password  = true
    auto_generate_password      = false
    admin_password              = "SomePassword"
  }
}

Expected Behavior

A VM once created from a template should not be deleted and recreated because of a change to the template.

Actual Behavior

In the vcd_vm resource, the changed ID causes the VM to be deleted and recreated.

# vcd_vm.ubuntu01 must be replaced
~ vapp_template_id               = "urn:vcloud:vapptemplate:5c6fe033-e73e-4094-bfd9-91bd00f9021e" -> "urn:vcloud:vapptemplate:f4f09ddb-0323-4f10-9928-c3ad509655bb" # forces replacement

Steps to Reproduce

  1. deploy VM from template via Terraform
  2. overwrite the template in catalog with newer verison
  3. run terraform apply again

User Access rights

Tested with default Org Admin Role

Jellyfrog commented 1 year ago

We're seeing the same behaviour and it's rather annoying because you seldom want to destroy your vms

carmine73 commented 1 year ago

did you try lifecycle? https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle

resource "vcd_vm" "ubuntu01" {
  # ...

  lifecycle {
    ignore_changes = [
      vapp_template_id
    ]
  }
}
carmine73 commented 1 year ago

It works, tested on vcd_vapp_vm, as you can see vapp_template_id # forces replacement

  # vcd_vapp_vm.my-vms["AS-01"] must be replaced
-/+ resource "vcd_vapp_vm" "my-vms" {
      + cpu_limit                      = (known after apply)
      + cpu_priority                   = (known after apply)
      + cpu_reservation                = (known after apply)
      + cpu_shares                     = (known after apply)
      ~ description                    = <<-EOT
            vRAM: 41 MB, so I set to 48.
            vDisk: 45 MB. It's thin provisioned anyway.
            I don't install VMware Tools as that will add 200 MB.
            No password. auto-login.
            Simple GUI.
            DHCP.
        EOT -> (known after apply)
      ~ hardware_version               = "vmx-09" -> (known after apply)
      ~ href                           = "https://vcd/api/vApp/vm-f1f044f4-91e0-48cf-8bd2-da0a95989ea1" -> (known after apply)
      ~ id                             = "urn:vcloud:vm:f0f264f4-92e0-48cf-8bd2-da0a95989ga1" -> (known after apply)
      ~ vapp_template_id               = "urn:vcloud:vapptemplate:b9557b02-48eb-47ee-bd17-a8f6d7b03136" -> "urn:vcloud:vapptemplate:fd76f267-070a-4f1d-8715-e7728faa2b41" # forces replacement
      ~ vm_type                        = "vcd_vapp_vm" -> (known after apply)
        # (13 unchanged attributes hidden)
      . . .
    }

when you add lifecycle block

No changes. Your infrastructure matches the configuration.
jl0815 commented 1 year ago

Hi @carmine73.

Thanks for the tip. I was not aware of the lifecycle argument. Maybe it is a good idea to give a small hint in the vcd provider doc.

Kind regards

dataclouder commented 1 year ago

@carmine73 Thanks for the tip. I tried with this VM:

resource "vcd_vapp_vm" "myvm" {
  org           = "datacloud"
  vdc           = "vdc-datacloud"
  vapp_name     = vcd_vapp.myvapp.name
  name          = "myvm"
  computer_name = "myvm-unique"
  catalog_name  = "cat-datacloud"
  template_name = "photon-hw11"
  power_on      = false
  memory        = 1024
  cpus          = 2
  cpu_cores     = 1
}

When I change it to

resource "vcd_vapp_vm" "myvm" {
  org              = "datacloud"
  vdc              = "vdc-datacloud"
  vapp_name        = vcd_vapp.myvapp.name
  name             = "myvm"
  computer_name    = "myvm-unique"
  vapp_template_id = data.vcd_catalog_vapp_template.tmpl.id
  power_on         = false
  memory           = 1024
  cpus             = 2
  cpu_cores        = 1
  lifecycle {
    ignore_changes = [
      vapp_template_id
    ]
  }
}

I still get an attempt to removal

  # vcd_vapp_vm.myvm must be replaced
-/+ resource "vcd_vapp_vm" "myvm" {
      - catalog_name                   = "cat-datacloud" -> null
      ~ cpu_limit                      = 2000 -> (known after apply)
      ~ cpu_priority                   = "NORMAL" -> (known after apply)
      ~ cpu_reservation                = 400 -> (known after apply)
      ~ cpu_shares                     = 2000 -> (known after apply)
      [...]
      - template_name                  = "photon-hw11" -> null # forces replacement
      + vapp_template_id               = "urn:vcloud:vapptemplate:1a4dca10-9b87-4f99-88b9-aefd0a8cd529" # forces replacement
      ~ vm_type                        = "vcd_vapp_vm" -> (known after apply)
        # (13 unchanged attributes hidden)

It is not only the addition of vapp_template_id that forces replacement, but also the removal of template_name.

Is there some more detail to add ? Side note: if I add catalog_name and template_name to lifecycle.ignore_change, we're back to the "Argument is deprecated" warning

carmine73 commented 1 year ago

I'm sorry but I just use template_id, I forgot deprecated parameter

anttiah commented 11 months ago

Ran into this issue recently. Our service provider updated the template I've been using and now I have to ignore all template id changes in our configs because, while the name and content of the template is still the same, the id isn't.

In my opinion, it should be possible to use either template name or template id in the config. Name should be considered as a pointer to the latest version of the template, whereas id could be used when an exact version of the template is required.