Re-triggering shell script in terraform

Hi All, I am using null_resource to trigger my shell script in terraform.
Is there a way terraform apply can re trigger my shell script if I update my shell script.

Hi,

You could add a triggers block to the null_resource with the sha256 hash of the script contents.
That way when the script changes, the hash changes, triggering the null_resource to re-apply.


Something like:

resource "null_resource" "run_script" {
  triggers = {
    script_hash = "${sha256(var.bash_script)}"
  }
...
}

The sha256 hash is optional, but might help keep your .tfstate a little more compact if you use this pattern a lot (so the whole bash script isn’t stored in the state file repeatedly).

Thanks Matt for your response, I will try this.
Is there a way, we can trigger a shell script only during terraform destroy.

Yes, flag the provisioner with when = "destroy".

Example

  provisioner "local-exec" {
    when    = "destroy"
    command = "echo 'Destroy-time provisioner'"
  }

Thanks Matt for your response :slight_smile:
Regarding the below, is it possible to check the entire folder so that if there is any change it will trigger instead of checking only one file. My requirement is I have a helm folder, triggering that folder through shell scripts, if there is any change in the charts, templates, values file, terraform apply should trigger that.

I tried something like below, but it is not detecting any changes.

Terraform doesn’t have a single primitive for hashing a whole directory, but if you are using Terraform v0.12.8 or later then you can construct such a thing using the new fileset function in conjunction with the filesha256 function:

  triggers = {
    file_hashes = jsonencode({
      for fn in fileset("${path.module}/helm-files", "**") :
      fn => filesha256("${path.module}/helm-files/${fn}")
    })
  }

I used jsonencode here because triggers values are required to be strings, and so JSON encoding was a convenient way to flatten that constructed map into a single string. It doesn’t really matter which encoding you use there, but using JSON may help terraform plan's change output to show you specifically what changed inside that object, because it’s often able to detect when a string contains JSON and show a structural changeset instead of a string-oriented one.

1 Like

Thanks Maat for your response. Its working fine :slight_smile: and now I got what I expected :slight_smile:

Hi Matt, for the below statement, is it possible to pass any path as variable.

  triggers = {
    file_hashes = jsonencode({
      for fn in fileset("${path.module}/helm-files", "**") :
      fn => filesha256("${path.module}/helm-files/${fn}")
    })
  }

Below is the example script I am using.

image

In this instead of /Users/dhineshbabu.elango/Documents/istio/istio-1.2.5 if I put any variable like ${var.path}. it is not accepting.

Even in my shell script I am passing the value by hardcoding. The istio version if I set that in variable and pass that as ${var.version} it is not working.
image