WEBINARLive webinar: Terraform in Buddy, Oct 21st.Terraform: plan, approve, apply with state in Buddy. Live on October 21st.Save your seat

Workspaces and environments

View as Markdown

Most teams run one configuration against several environments - dev, staging, prod. In Buddy, you separate their states in one of three ways.

Terraform workspaces

tf_workspace selects a Terraform workspace. Buddy exports it as TF_WORKSPACE before init, so Terraform selects the workspace, or creates it if needed.

yaml
- action: Plan type: TERRAFORM_PLAN tool: OPENTOFU version: 1.12.6 tf_workspace: staging
  • When tf_workspace is empty, the action uses the TF_WORKSPACE variable if it is set, and default otherwise.
  • The workspace that actually ran is exported as BUDDY_ACTION_TF_PLAN_WORKSPACE.
  • Use the same tf_workspace in Plan and Apply. Otherwise, Apply runs against a different state.

To use one pipeline for all environments, set tf_workspace: $ENVIRONMENT and pass ENVIRONMENT when you run the pipeline.

Warning
Terraform's HTTP backend, which the artifact backend uses, supports only the default workspace. With the artifact backend, separate environments with artifact versions instead (see below).

Separate backends

You can give each environment its own state instead:

  • Artifact backend: one artifact version per environment - artifact_version: $ENVIRONMENT.
  • S3 or GCS: a different key or prefix per environment. additional_args is only added to plan and apply, not init, so pass backend settings in the TF_CLI_ARGS_init variable, for example -backend-config=key=staging/terraform.tfstate.

Keep each environment's variables in a separate .tfvars file and pick it with additional_args: -var-file=env/$ENVIRONMENT.tfvars.

Several directories in one repository

When one repository holds several root modules - network/, database/, app/ - each one needs its own working_directory:

  • One pipeline per directory. Trigger each pipeline only on changes in its directory, so a change to app/ doesn't plan network/.
  • Several Plan and Apply pairs in one pipeline. Give each Apply an explicit plan_file_path, because by default Apply picks up the plan from the most recent Plan action. See The plan file.

Promoting a change between environments

A common setup is one pipeline per environment, run in order:

  1. A push to main runs the staging pipeline: Plan → Apply.
  2. When it succeeds, it triggers the prod pipeline: Plan → Approve Run → Apply.

Each pipeline plans against its own state, so the production plan always reflects what's actually deployed in production.

Last modified on Oct 19, 2026