Skip to content
Latchkey

How to Run Terraform in a Reusable Workflow in GitHub Actions

Copy-pasting Terraform steps into every environment workflow guarantees drift; a reusable workflow centralizes the pipeline.

Define a workflow_call workflow that takes the working directory and role ARN as inputs, then call it from thin per-environment workflows.

Steps

  • Create a reusable workflow with on: workflow_call and inputs for the dir and role.
  • Run terraform init, validate, plan, and gated apply inside it.
  • Pass secrets with secrets: inherit from the caller.
  • Call it from each environment workflow with different inputs.

Reusable workflow

.github/workflows/terraform.yml
name: terraform
on:
  workflow_call:
    inputs:
      workdir: { required: true, type: string }
      role-arn: { required: true, type: string }
permissions:
  id-token: write
  contents: read
jobs:
  tf:
    runs-on: ubuntu-latest
    defaults:
      run: { working-directory: ${{ inputs.workdir }} }
    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ inputs.role-arn }}
          aws-region: us-east-1
      - uses: hashicorp/setup-terraform@v3
      - run: terraform init
      - run: terraform validate
      - run: terraform plan -out=tfplan
      - if: github.ref == 'refs/heads/main'
        run: terraform apply -auto-approve tfplan

Caller

.github/workflows/deploy-prod.yml
jobs:
  prod:
    uses: ./.github/workflows/terraform.yml
    secrets: inherit
    with:
      workdir: environments/prod
      role-arn: ${{ vars.PROD_ROLE_ARN }}

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →