Removing OCI security list and updating associated subnet

Hi,

I ran into a situation where Terraform does not update/delete resources, and I’d like to learn if this is a bug (either in the Oracle OCI provider or in Terraform) and if there is an alternative solution.

First, I create a VCN and subnet:

locals {
  tenancy_id = "..."
}

resource "oci_core_vcn" "main_vcn" {
  compartment_id = local.tenancy_id
  cidr_blocks    = ["10.0.0.0/16"]
  display_name   = "main-vcn"
}

resource "oci_core_subnet" "main_subnet" {
  cidr_block        = "10.0.0.0/24"
  compartment_id    = local.tenancy_id
  vcn_id            = oci_core_vcn.main_vcn.id
  display_name      = "main-subnet"
}

Terraform successfully creates these resources. Now I add a security list:

resource "oci_core_security_list" "main_security_list" {
  compartment_id = local.tenancy_id
  vcn_id         = oci_core_vcn.main_vcn.id
  display_name   = "main_security_list"
}

resource "oci_core_subnet" "main_subnet" {
  cidr_block        = "10.0.0.0/24"
  compartment_id    = local.tenancy_id
  vcn_id            = oci_core_vcn.main_vcn.id
  display_name      = "main-subnet"
  security_list_ids = [oci_core_security_list.main_security_list.id]
}

Terraform succeeds in creating the security list and updating the subnet to use the security list.

The problem is: if I now rollback to the first version (without the security list), Terraform only plans to destroy the security list. However, OCI won’t let you destroy a security list that is used by a subnet. The right thing to do is to 1. update the subnet to no longer use the security list and then 2. delete the security list.

How come Terraform does not understand this? Is this a bug in the OCI Terraform provider or in Terraform itself? And what is the best practice in this situation?

Hi @martijndwars,

What you have here is a relatively common pattern in some providers, where one resource is “registered” with another, and must be de-registered before it can be removed.

The default ordering for Terraform’s resource lifecycle is to delete the resource before replacement and updates. However as you’ve shown that default ordering can’t work in this case, since the update must come before the removal of the old resource instance.

The feature you are looking for to invert this ordering in terraform is the lifecycle option create_before_destroy. This will instruct Terraform that create and update actions must happen before the destroy action, resulting in the oci_core_security_list being removed from the oci_core_subnet before it is deleted.

It is currently up to the providers to document when this option may be needed for certain combinations of resources. The terraform CLI alone cannot determine when an alternate ordering is required, so it must be explicitly set in the configuration.