Common workflows

View as Markdown

Plan on pull requests

Run Plan, without Apply, on every pull request, so reviewers know what a change does before it's merged.

yaml
- pipeline: Plan PR
  events:
    - type: PULL_REQUEST
  actions:
    - action: Plan
      type: TERRAFORM_PLAN
      tool: OPENTOFU
      version: 1.12.6
      working_directory: infra
      backend:
        type: ARTIFACT
        artifact: infra-state
        artifact_version: prod

The run status is reported to the pull request. Reviewers open the run to see the resource diff. To post the result somewhere else, add an action that sends $BUDDY_ACTION_TF_PLAN_SUMMARY, for example to Slack. See Pull request testing for how pull request pipelines work.

Info
A plan reads the state but doesn't change it. It still takes the state lock while it runs, so a PR plan and an apply on the same state wait for each other.

Destroy the infrastructure

Pass -destroy to the Plan action. The plan then deletes every resource in the state, and Apply runs it like any other plan. Keep this in a separate, manually triggered pipeline, with an approval that blocks self-approval:

yaml
- pipeline: Destroy staging
  actions:
    - action: Plan destroy
      type: TERRAFORM_PLAN
      tool: OPENTOFU
      version: 1.12.6
      working_directory: infra
      additional_args: -destroy
      backend:
        type: ARTIFACT
        artifact: infra-state
        artifact_version: staging
    - action: Approve
      type: WAIT_FOR_APPLY
      description: "Destroys: $BUDDY_ACTION_TF_PLAN_DESTROY_RESOURCES"
      prevent_self_approval: true
    - action: Apply
      type: TERRAFORM_APPLY
      tool: OPENTOFU
      version: 1.12.6
      working_directory: infra
      backend:
        type: ARTIFACT
        artifact: infra-state
        artifact_version: staging

Import existing resources

With an import block (Terraform 1.5 and later, OpenTofu): add the block to your code and run the regular Plan → Apply pipeline. The diff shows the resource being imported.

hcl
import {
  to = aws_s3_bucket.assets
  id = "my-assets-bucket"
}

With terraform import: run it in the Terraform CLI action.

Validate before planning

Catch formatting and syntax errors before they reach Plan. Run fmt and validate in the Terraform CLI action at the start of the pipeline:

yaml
- action: Validate
  type: TERRAFORM
  version: 1.5.7
  working_directory: infra
  commands: |-
    terraform fmt -check -recursive
    terraform init -backend=false
    terraform validate
- action: Plan
  type: TERRAFORM_PLAN
  tool: OPENTOFU
  version: 1.12.6
  working_directory: infra

init -backend=false downloads providers and modules without touching the state. If validation fails, the run stops before Plan.

Linters and security scanners such as tflint, checkov, or trivy can run in their own images in a Run Docker Image action.

Last modified on Oct 19, 2026