Skip to main content

Allow the use of custom Terraform/Tofu commands without the need for a custom workflow

https://docs.spacelift.io/vendors/terraform/workflow-tool

As per the above doc, the current behaviour of Spacelift using custom terraform or tofu commands requires the use of a custom workflow meaning that Spacelift will no longer manage the Terraform or tofu binary and this must be done either with a pre_init hook or custom runtime image.


It would be a great advantage to be able to use the Terraform or Tofu versions managed by Spacelift but allow custom terraform workflow commands to be configured in Spacelift. The below commands could be configured in the stack or the workflow.yml without the requirement of changing terraform_workflow_tool.

Example:

init: terraform init -backend-config="{{ .WorkspaceName }}"/state.config 
plan: terraform plan -var-file="{{ .WorkspaceName }}"/terraform.tfvars 
apply: terraform apply -auto-approve -var-file="{{ .WorkspaceName }}"/terraform.tfvars 
Status: ❌ Rejected3 comments

Log in to comment and vote

Comments3

  • Jonah Kowall

    Team•

    Jul 27

    Thanks for the detailed write-up, and apologies for the slow reply here.


    We're going to close this one as not planned after 12 months+ with only 4 votes, but I want to leave a proper answer behind rather than just changing the status, because most of what you're after is achievable today without switching Workflow Tool to Custom.


    Extra flags on init and plan

    Terraform and OpenTofu both read TF_CLI_ARGS_<command> environment variables, and Spacelift lets you set those on the stack directly or on a shared context. Spacelift keeps managing the binary and the version selector stays in place.

    TF_CLI_ARGS_init = -backend-config=prod/state.config
    TF_CLI_ARGS_plan = -var-file=prod/terraform.tfvars
    

    Per-workspace values

    Those variables are static strings, so they can't reference {{ .WorkspaceName }} the way a custom workflow file can. If the path needs to vary per workspace, the usual approach is a before_init hook that copies or symlinks the right file into an auto-loaded location, which avoids the CLI flag entirely:

    cp "$TF_WORKSPACE/terraform.tfvars" terraform.tfvars
    

    Terraform auto-loads terraform.tfvars and anything ending in .auto.tfvars, so no plan flag is needed after that. More detail here: https://docs.spacelift.io/vendors/terraform/handling-tfvars


    On the apply example

    We can't support -var-file on apply regardless of the mechanism. Spacelift applies a saved plan file, and Terraform rejects variable flags when applying a saved plan. That plan file is what guarantees the change you approved is the change that runs, so it isn't something we want to give up.


    We're also going to add a note to the Workflow Tool docs pointing at the TF_CLI_ARGS approach, since that page is where people land when looking for this and the guidance currently lives elsewhere.

    If the env var and hook approach doesn't cover your case, reply here or open a support
    ticket with the specifics and we'll take another look.

  • Natalia Gazda

    Team•

    Jul 19, 2025

    Hi Chloe,

    Thanks for this request. To understand the underlying need better:

    1. I see you're using -backend-config - since Spacelift manages state automatically, what backend configuration are you overriding? External state?

    2. Your workspace-specific tfvars pattern is interesting. What prevents using Spacelift's environment variables or mounted files via Contexts?

    3. What's the main friction with custom workflows - managing Terraform versions, or something else?

    Understanding your specific constraints will help us find the right solution.

    • Magenta Sun

      •

      Jul 21, 2025

      1. We are using external state and don’t want to change that

      2. We don’t want to use contexts as we still want the ability to run terraform locally. We have been told the spacelift ctl tool does not support SSO with SAML (our own provider), so that is ruled out. We also need to support terraform import commands.

      3. We want to make use our generated backend config and share terraform files amongst stacks, similar to terraform workspaces but for obvious reasons do not want to tie ourselves to that avenue at this juncture

      Thanks for your reply :)