With Terraform, you can specify when you’d like a resource applied. For example, using when = destroy , the following resource will only be run when that plan is targeted for a destroy:
data "external" "create_cluster" {
program = ["python3", "${path.module}/scripts/create_cluster.py"]
query = {
du_fqdn = var.cluster_fqdn
user = var.cluster_user
pw = var.cluster_password
tenant = var.cluster_tenant
region = var.cluster_region
cluster_name = var.cluster_name
k8s_api_fqdn = metal_reserved_ip_block.cluster_ip.address
allow_workloads_on_master = var.allow_workloads_on_master
}
}
resource "null_resource" "delete_cluster" {
provisioner "local-exec" {
when = destroy
command = "printf '{\"du_fqdn\": \"${var..cluster_fqdn}\", \"user\": \"${var..cluster_user}\", \"pw\": \"${var..cluster_password}\", \"tenant\": \"${var..cluster_tenant}\", \"region\": \"${var..cluster_region}\", \"cluster_uuid\": \"${lookup(data.external.create_cluster.result, "cluster_id")}\"}' | python3 ${path.module}/scripts/delete_cluster.py"
environment = {
du_fqdn = var.cluster_fqdn
user = var.cluster_user
pw = var.cluster_password
tenant = var.cluster_tenant
region = var.cluster_region
cluster_uuid = lookup(data.external.create_cluster.result, "cluster_id")
}
}
}
In this case, we want the result from our create_cluster
datasource. However, in Terraform 0.13+, you can no longer reference data in this way, and when you try, you get a fatal error:
Error: Invalid reference from destroy provisioner
Destroy-time provisioners and their connection configurations may only
reference attributes of the related resource, via 'self', 'count.index',
or 'each.key'.
References to other resources during the destroy phase can cause dependency
cycles and interact poorly with create_before_destroy.
This means that, if you want to continue to reference this external data inside of a destroy-time provisioner, in order to ensure these values are available, you just need to modify the above null_resource slightly:
First, we need to, before the provisioner block, define a map of triggers so when Terraform can reference these objects as part of its class when this destroy event occurs, so in order to, for example, reference your variables, your map should look like:
resource "null_resource" "delete_cluster" {
triggers = {
cluster_uuid = lookup(data.external.create_cluster.result, "cluster_id")
cluster_fqdn = var.cluster_fqdn
cluster_user = var.cluster_user
cluster_password = var.cluster_password
cluster_tenant = var.cluster_tenant
cluster_region = var.cluster_region
}
and then to reference them in the plan, you simply use self.triggers.[key] :
provisioner "local-exec" {
when = destroy
command = "printf '{\"du_fqdn\": \"${self.triggers.cluster_fqdn}\", \"user\": \"${self.triggers.cluster_user}\", \"pw\": \"${self.triggers.cluster_password}\", \"tenant\": \"${self.triggers.cluster_tenant}\", \"region\": \"${self.triggers.cluster_region}\", \"cluster_uuid\": \"${self.triggers.cluster_uuid}\"}' | python3 ${path.module}/scripts/delete_cluster.py"
environment = {
du_fqdn = self.triggers.cluster_fqdn
user = self.triggers.cluster_user
pw = self.triggers.cluster_password
tenant = self.triggers.cluster_tenant
region = self.triggers.cluster_region
cluster_uuid = self.triggers.cluster_uuid
}
}
}
More about other Terraform upgrade (to 0.13 and beyond) concerns can be found here.
Top comments (0)