Re-Running scripts using Terraform

When deploying complex architectures, sometimes it might be necessary to run SQL imports or PowerShell scripts using Terraform. It is not uncommon that these commands are executed in local or remote provisioner under a special resource called null_resource. A Null Resource simply stores the desired state without doing anything to the environment.

After the first execution of a null_resource, whether successful or failed. The null_resource desired state will exist in the tfstate file. This happens as the desired state will be stored as the execution of the provisioner script rather than on its outcome of execution. If the script executed failed or have simply been updated, as long as the parameters to the script don’t change the update will never get executed.

There are 2 ways of getting around this issue with the null_resource:

  1. Putting a dummy parameter to the command executed if it is supported
  2. Using the triggers parameter of the null_resource

What is the best approach? Mainly it is a preference of the person developing the scripts. Below are the two options in practice to build your personal preference.

Option 1: Using dummy parameter

# File: script1.ps1
param ( [Parameter()]$Version )
 
Write-Host -ForeGround "Yellow" "Some text ignoring parameter"
# File: main.tf
variable "update_version" {
    type = string
    description = "This field is used to determine whether a new version of the PowerShell Script needs to be executed"
}
 
# Allowing Re-run of null resource using a dummy variable
resource "null_resource" "dummy_variable_example" {
    provisioner "local-exec" {
        command = "powershell -ExecutionPolicy ByPass -File script1.ps1 -Version ${var.update_version}"
    }
}

Option 2: Using the triggers block

# File: script2.ps1
Write-Host -ForeGround "Yellow" "Some text ignoring parameter"
# File: main.tf
variable "update_version" {
    type = string
    description = "This field is used to determine whether a new version of the PowerShell Script needs to be executed"
}
 
# Allowing Re-run of null resource using the triggers map
resource "null_resource" "triggers_example" {
    triggers = {
        "version" = var.update_version
    }
 
    provisioner "local-exec" {
        command = "powershell -ExecutionPolicy ByPass -File script2.ps1"
    }
}

Reference

  • https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource