terramate-io / terramate

Terramate CLI is an open-source Infrastructure as Code (IaC) Orchestration and Code Generation tool for Terraform, OpenTofu and Terragrunt.

Home Page:https://terramate.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[FEATURE] lets-Block for scripts

cwe1ss opened this issue · comments

Is your feature request related to a problem? Please describe.
I want to calculate some variables in my scripts based on some globals and use them in multiple commands. I currently have to duplicate that logic in every command.

Describe the solution you'd like
A lets-block lets me create a new variable that I can then use within my commands (similar to https://terramate.io/docs/cli/code-generation/variables/lets in generate_hcl and generate_file) .

Proposed example:

script "plan" {
  description "Plan stack and upload plan file"
  lets {
    plan_file = "${terramate.stack.id}.tfplan" # Real logic would be more complex (e.g. add a job ID from CI, etc)
  }
  job {
    commands = [
      ["terraform", "plan", "--out=${let.plan_file}"],
      ["aws", "s3", "cp", "${let.plan_file}", "s3://mybucket/plans/${let.plan_file}"],
    ]
  }
}

Describe alternatives you've considered
Duplicate logic in every command, or write to environment variable (which might conflict with future parallel runs).

PS: This new script feature looks great and very helpful!! thank you for it! :)

Hi @cwe1ss

Yes, lets support is planned for scripts. We do not have an ETA at the moment as we are still evaluating the scripts feature in its current state before continuing adding more features.

fun fact: we have the exact use-case you described in this issue in our design document from the very first day of planning this feature.

We will keep you updated here.

Thank you for the update!

I ended up switching to invoking /bin/bash, so that I can set variables and also use if-logic etc. within a multi-line script block! Do you see any drawback with this approach?

script "plan" {
  description "Plan stack and upload plan file"
  job {
    commands = [
      ["/bin/bash", "-c", <<-EOT
        set -e
        if [ -z "$JOB_ID" ]; then
          echo "JOB_ID missing."
          exit 1
        fi

        PLAN_NAME=${terramate.stack.id}-$JOB_ID.tfplan
        terraform plan --out=$PLAN_NAME
        aws s3 cp $PLAN_NAME "s3://${global.backend.bucket}/plans/$PLAN_NAME" --profile ${global.backend.profile}
      EOT
      ]
    ]
  }
}

i like it, if this works with correct handling of $ uses, then I do not see obvious drawbacks ;)