Use local variable in local-exec destroy provisioner

using terraform 1.5.7

I know we should not use provisioners if we can avoid it.
But Im doing stuff with openstack workflow/mistral that the provider does not support so here I am.

I am basically looping setting up cron triggers with a bash script that uses openstack cli from the “local-exec” provisioner with “when: create” running in a terraform_data resource block. It works nicely

resource "terraform_data" "my_cron" {
  for_each = { for host, values in var.hosts : host => values if values.extra != null }

  provisioner "local-exec" {
    when    = create
    command = "bash ${templatefile("my_create_script.tftpl", {
      cloud_name="${local.cloud_name}"
      exec_description="Created by automation"
      other_variable=each.key
    } )}"
  }

But I obviously I want the ability to also remove the cron jobs that I create.
so added a destroy provisioner to the resource:

provisioner "local-exec" {
    when    = destroy
    command = "bash ${templatefile("my_destroy_script.tftpl", {
      cloud_name="${local.cloud_name}"
    } )}"
  }

However this destroy part fails due to the local.cloud_name not being allowed.

Destroy-time provisioners and their connection configurations may only reference attributes >of the related resource, via ‘self’, ‘count.index’, or ‘each.key’.

If I change it to a string directly it works. But I want this as part of a terraform module where the cloud_name could be different so it should be a variable (var or local) but I cant wrap my head around it.
One suggestion was to use tags { cloud = local.cloud_name } in the resource and reference it, but terraform_data does not seem to suport tags … if I instead put the provisioner in another existing resource that does, then I need to have the provisioners as dynamic depending on the input host var (see for_each in code) and provisioners does not support that …

So how do I solve this…? It feels like it should be something easy, but Im stuck now.

Hi @tomasbackman1,

This type of coordination is often better handled in the workflow outside of Terraform, but if you’re comfortable with the limitations of provisioners, specifically here with the fact that a destroy provisioner cannot work if the configuration is removed entirely, then you can store whatever data you want in the in the terraform_data resource.

Assigning the local.cloud_name value to one of the resource attributes, like input (or replace_triggered_by if that extra behavior suits your purposes) will allow you to reference the data via self from within the provisioner.

Ah input could be used, thank you!
tags did not, and not

did in resource:

input = { cloud = local.cloud_name }
Then changed the references in the provisioners to ${self.input.cloud}

Works perfectly now

I did not find this anywhere else, but after looking around some more in the documentation now I found that the terraform_data has this input argument. Hard to use but useful! =)