Line continuation within a variable

Is there a way to store multiple lines of bash commands into a variable? I’ve not found any examples of how to do this anywhere and have failed to come up with it on my own so far.

use case - i’m trying to use a null_resource to call provisioner “local-exec” and then pass in multiple commands. i can do this using <<EOT if i do it directly in the null_resource itself, but if i try to put the commands into a variable, terraform will fail on PLAN or APPLY because it “failed to load root config module, error parsing (path/variables.tf)” with illegal characters usually as the reason.

i’d like to be able to create a couple of different variables with different commands, then do a lookup in the actual null_resource to call the proper variable based on my lookup criteria. i just am struggling to figure out how to pass in multiple lines via a variable. Any help would be appreciated.

Hi @kylecompassion!

Could you please share exactly what you tried that led to the error “failed to load root config module, error parsing (path/variables.tf)”? That should help clarify what exactly you are trying to do here.

I’ll try to explain the outcome i’m looking for as it may be i’m going the completely wrong direction in the first place. Below is a null_resource with multiple commands in the local-exec piece. I’m trying to get everything within {} of local-exec into a variable so that i can maintain multiple variables with unique commands in each variable, and then use a LOOKUP within the null_resource so i can call different variables based on different ${terraform.workspace} values. So I’m trying to figure out how to properly write the variable so that it works when called by the local-exec provisioner.

  1. if there’s a better way to do this, let me know
  2. if this is a good way to reach my desired outcome, how do i do it?

Thanks!

resource “null_resource” “datadog_metrics” {
depends_on = [“null_resource.platform_auth”]
provisioner “local-exec” {
command = <<EOT
sudo runuser -l user -c ‘kubectl apply -f /home/terraform/kube-state-metrics/’;
sudo runuser -l user -c ‘kubectl apply -f /home/terraform/datadog_cluster_agent’/
EOT
}
}

Hi @kylecompassion! Here’s one way to do what you’re trying to do:

locals {
  per_workspace_commands = {
    workspace_a = <<-EOT
      sudo runuser -l user -c ‘kubectl apply -f /home/terraform/kube-state-metrics/’
      sudo runuser -l user -c ‘kubectl apply -f /home/terraform/datadog_cluster_agent/'
    EOT
    workspace_b = <<-EOT
      sudo runuser -l user -c ‘kubectl apply -f /home/terraform/kube-state-metrics/’
    EOT
  }
}

resource "null_resource" "datadog_metrics" {
  depends_on = [null_resource.platform_auth]

  provisioner "local-exec" {
    command = local.per_workspace_commands[terraform.workspace]
  }
}

I used a local value here because it didn’t sound from your description like this is something that should be overridden by a calling module, but if you do need the calling module to customize this then you could use a variable block instead, with the default value set to the same map expression:

variable "per_workspace_commands" {
  type = map(string)
  default = {
    workspace_a = <<-EOT
      sudo runuser -l user -c ‘kubectl apply -f /home/terraform/kube-state-metrics/’
      sudo runuser -l user -c ‘kubectl apply -f /home/terraform/datadog_cluster_agent/'
    EOT
    workspace_b = <<-EOT
      sudo runuser -l user -c ‘kubectl apply -f /home/terraform/kube-state-metrics/’
    EOT
  }
}