oracle / terraform-provider-oci

Terraform Oracle Cloud Infrastructure provider
https://www.terraform.io/docs/providers/oci/
Mozilla Public License 2.0
757 stars 680 forks source link

oci_core_instance incorrectly identify destroy action as in-place-change #2136

Open luckeyca opened 5 months ago

luckeyca commented 5 months ago

Community Note

Terraform Version and Provider Version

Terraform v1.5.4 on linux_amd64

oci_core_instance

Terraform Configuration Files

# Copy-paste your Terraform configurations here - for large Terraform configs,
# please use a service like Dropbox and share a link to the ZIP file. 
# Please remove any sensitive information from configuration files before sharing them. 

resource "oci_core_instance" "vm" {
  for_each            = var.vm-info
  availability_domain = var.availability_domain_name
  compartment_id      = var.compute_compartment_ocid
  display_name        = each.value.vm_display_name
  shape               = each.value.vm_compute_shape
  fault_domain        = data.oci_identity_fault_domains.fds.fault_domains[each.value.fault_domain - 1].name
  freeform_tags       = each.value.freeform_tags

  dynamic "shape_config" {
    for_each = reverse(split(".", each.value.vm_compute_shape))[0] == "Flex" ? [each.value.vm_flex_shape_params] : []

    content {
      ocpus         = shape_config.value.ocpu
      memory_in_gbs = shape_config.value.memory
    }
  }

  create_vnic_details {
    subnet_id        = each.value.subnet_id
    display_name     = format("%s-%s", each.value.vm_display_name, "nic1")
    assign_public_ip = each.value.assign_public_ip
    hostname_label   = lower(each.value.hostname_label)
    private_ip       = each.value.private_ip
    freeform_tags    = each.value.freeform_tags
    nsg_ids          = each.value.nsg_ids
  }

  source_details {
    source_type             = "image"
    source_id               = local.image_info[each.key].listing-resource-id
    boot_volume_size_in_gbs = each.value.boot_volume_size
  }

  metadata = {
    ssh_authorized_keys = each.value.ssh_public_key
    user_data           = try(base64encode(templatefile("${path.root}${each.value.user_data_file}", each.value.user_data_vars)), null)
  }

  timeouts {
    create = "60m"
  }

  lifecycle {
    ignore_changes = [
      metadata
    ]
  }

}

Debug Output

Panic Output

Expected Behavior

When changing the "source_id" under "source_details" from a windows OS OCID to a linux OS OCID, instance should be destroyed and recreated.

Actual Behavior

When changing the "source_id" under "source_details" from a windows OS OCID to a linux OS OCID, terraform plan shows the action was "in-place" update. Then terraform apply failed.

Steps to Reproduce

  1. create a windows vm using the oci_core_instance
  2. update the source_id under "source_details" from a Windows OS OCID to a linux OS OCID
  3. terraform plan. this will should in-place update
  4. terraform apply will fail with the following error. Error: │ Error: 400-InvalidParameter, sourceDetails.kmsKeyId size must be between 1 and 255 │ Suggestion: Please update the parameter(s) in the Terraform config as per error message sourceDetails.kmsKeyId size must be between 1 and 255 │ Documentation: https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance │ API Reference: https://docs.oracle.com/iaas/api/#/en/iaas/20160918/Instance/UpdateInstance │ Request Target: PUT https://iaas.ca-toronto-1.oraclecloud.com/20160918/instances/ocid1.instance.oc1.ca-toronto-1.an2g6ljr5xeuumqcftjnlo53qhjmj5itl32cjkh6dp2qakiz3g3gbi37y4ca │ Provider version: 5.45.0, released on 2024-06-05.
    │ Service: Core Instance │ Operation Name: UpdateInstance │ OPC request ID: 48eb77dc5e532530893008576ae02dd3/FA9861117E6117B45EFD917A903E3B9F/F3040076B4090E60147B679A97AAE6A6
    │ with module.vms_toronto.oci_core_instance.vm["GcDs-PSPC-Spoke1-hr2paypoc-p1-db-vm1"], │ on .terraform/modules/vms_toronto/main.tf line 103, in resource "oci_core_instance" "vm": │ 103: resource "oci_core_instance" "vm" {

Important Factoids

References

12345ieee commented 4 months ago

This also happens when changing the source_type from image to bootVolume or viceversa.

This is impeding several of our workflows, as now we have to manually taint the resource.

cweeks72 commented 4 months ago

The problem seems to be related to this commit: https://github.com/oracle/terraform-provider-oci/commit/f0edc487a574031d86fe477fe0450a091d354d36 - it seems that they wanted to support in-place replacement of the boot volume, but seem to have also broken without any bypass, image replacement.

luckeyca commented 4 months ago

as of the latest provider 6.2.0 still has the issue. I created a windows instance using terraform and then switched the image id to an oracle linux 8 image. terraform plan still shows in-place change and apply still fails. see details below.

changes in terraform code: (only source_id changed) source_details {

windows

# source_id   = "ocid1.image.oc1.ca-toronto-1.aaaaaaaadal4ycxhc6eeayxjy2gpwbmowqbqqk5vjdom3cjkhzgo3z7csk2q"
# oracle linux 8
source_id   = "ocid1.image.oc1.ca-toronto-1.aaaaaaaaeonnf55icwpffvzbzfgva7fkf5mrnd7f53ope255vjmpbufcqlna"
source_type = "image"

}

$ terraform plan oci_core_instance.test_instance: Refreshing state... [id=ocid1.instance.oc1.ca-toronto-1.an2g6ljr5xeuumqcnv2hbtwqg4n3aaegqjnyextnxrqj5b3pfap6lzctnhja]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: ~ update in-place

Terraform will perform the following actions:

oci_core_instance.test_instance will be updated in-place

~ resource "oci_core_instance" "test_instance" { id = "ocid1.instance.oc1.ca-toronto-1.an2g6ljr5xeuumqcnv2hbtwqg4n3aaegqjnyextnxrqj5b3pfap6lzctnhja"

(23 unchanged attributes hidden)

  ~ source_details {
      ~ source_id                       = "ocid1.image.oc1.ca-toronto-1.aaaaaaaadal4ycxhc6eeayxjy2gpwbmowqbqqk5vjdom3cjkhzgo3z7csk2q" -> "ocid1.image.oc1.ca-toronto-1.aaaaaaaaeonnf55icwpffvzbzfgva7fkf5mrnd7f53ope255vjmpbufcqlna"
        # (5 unchanged attributes hidden)
    }

    # (6 unchanged blocks hidden)
}

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

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

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

$ terraform apply -auto-approve oci_core_instance.test_instance: Refreshing state... [id=ocid1.instance.oc1.ca-toronto-1.an2g6ljr5xeuumqcnv2hbtwqg4n3aaegqjnyextnxrqj5b3pfap6lzctnhja]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: ~ update in-place

Terraform will perform the following actions:

oci_core_instance.test_instance will be updated in-place

~ resource "oci_core_instance" "test_instance" { id = "ocid1.instance.oc1.ca-toronto-1.an2g6ljr5xeuumqcnv2hbtwqg4n3aaegqjnyextnxrqj5b3pfap6lzctnhja"

(23 unchanged attributes hidden)

  ~ source_details {
      ~ source_id                       = "ocid1.image.oc1.ca-toronto-1.aaaaaaaadal4ycxhc6eeayxjy2gpwbmowqbqqk5vjdom3cjkhzgo3z7csk2q" -> "ocid1.image.oc1.ca-toronto-1.aaaaaaaaeonnf55icwpffvzbzfgva7fkf5mrnd7f53ope255vjmpbufcqlna"
        # (5 unchanged attributes hidden)
    }

    # (6 unchanged blocks hidden)
}

Plan: 0 to add, 1 to change, 0 to destroy. oci_core_instance.test_instance: Modifying... [id=ocid1.instance.oc1.ca-toronto-1.an2g6ljr5xeuumqcnv2hbtwqg4n3aaegqjnyextnxrqj5b3pfap6lzctnhja] ╷ │ Error: 400-InvalidParameter, Boot volume replacement is not supported for Windows instances or Windows images. │ Suggestion: Please update the parameter(s) in the Terraform config as per error message Boot volume replacement is not supported for Windows instances or Windows images. │ Documentation: https://registry.terraform.io/providers/oracle/oci/latest/docs/resources/core_instance │ API Reference: https://docs.oracle.com/iaas/api/#/en/iaas/20160918/Instance/UpdateInstance │ Request Target: PUT https://iaas.ca-toronto-1.oraclecloud.com/20160918/instances/ocid1.instance.oc1.ca-toronto-1.an2g6ljr5xeuumqcnv2hbtwqg4n3aaegqjnyextnxrqj5b3pfap6lzctnhja │ Provider version: 6.2.0, released on 2024-07-10. │ Service: Core Instance │ Operation Name: UpdateInstance │ OPC request ID: e3b809231902ba76a262d265ea5effb7/9D4F3EC44401878BF0A9416770B19682/D9AC600279DA0D4D4BEE1E8BD074D4C3 │ │ │ with oci_core_instance.test_instance, │ on main.tf line 22, in resource "oci_core_instance" "test_instance": │ 22: resource "oci_core_instance" "test_instance" {

cweeks72 commented 3 months ago

For those looking for a solution to this issue, provider versions prior to 5.36.0 work as before.

terraform {
  required_providers {
    oci = {
      version = "< 5.36.0"
    }
  }
}
luckeyca commented 3 months ago

@cweeks72 I think more specifically it's 5.39.0 that causes this problem because from internal oracle support ticket, they told me that they added a feature to dynamically replace boot volume without having to destroy the instance(only works for linux). That's in 5.39.0(Support for Compute API: Replace instance boot volume via UpdateInstance). Evidently Oracle didn't put enough code logic to handle the situation where the instance still needs to be destroyed. I don't think this feature is that useful because the only case it's useful is when the app is not on boot volume AND has no dependencies on any OS packages.

cweeks72 commented 3 months ago

I tried a variety of versions, this was the one that worked for me. :shrug:

I agree on the analytics of the problem, but offering a workaround solution is useful for those who've hit this.

luckeyca commented 3 months ago

official answer from oracle on this while they are working with terraform team to see what needs to be done

  1. Manually destroy and re-create the instance
  2. Use TF provider version v5.38.0 and below