Terraform Workflows
Nine reusable workflows cover the full Terraform lifecycle: format checking, linting, plan comparison, deployment with approval gates, drift detection, and cost estimation.
tf-checks
Full Terraform validation pipeline — runs format check, init, validate, and optionally terraform plan across multiple cloud providers.
When to use: On every pull request to catch Terraform errors before merging.
jobs:
terraform-checks:
uses: clouddrove/github-shared-workflows/.github/workflows/tf-checks.yml@master
with:
working_directory: ./
provider: aws # aws | azure | gcp
terraform_version: latest
enable_plan: true
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
BUILD_ROLE: ${{ secrets.BUILD_ROLE }}
| Input | Required | Default | Description |
|---|---|---|---|
working_directory | No | ./ | Path to Terraform root |
provider | No | aws | Cloud provider (aws, azure, gcp) |
terraform_version | No | latest | Terraform version to install |
enable_plan | No | false | Run terraform plan |
aws_region | No | us-east-1 | AWS region |
gcp_credentials | No | — | GCP service account JSON |
stf-checks
Terraform min/max version, format, init, validate — a lighter variant of tf-checks focused on version compatibility.
jobs:
stf-checks:
uses: clouddrove/github-shared-workflows/.github/workflows/stf-checks.yml@master
with:
working_directory: ./
provider: aws
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
tf-lint
Lint Terraform with TFLint — catches common errors and enforces best practices beyond what terraform validate checks.
jobs:
lint:
uses: clouddrove/github-shared-workflows/.github/workflows/tf-lint.yml@master
secrets:
GITHUB: ${{ secrets.GITHUB_TOKEN }}
tf-pr-checks
Terraform plan comparison on PRs — generates a plan for the PR branch and compares it against the target branch plan, posting a diff as a PR comment.
When to use: On pull requests to show reviewers exactly what infrastructure will change.
jobs:
tf-pr-checks:
uses: clouddrove/github-shared-workflows/.github/workflows/tf-pr-checks.yml@master
with:
terraform_directory: ./infra
target_branch: main
provider: aws
aws_region: us-east-1
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
BUILD_ROLE: ${{ secrets.BUILD_ROLE }}
| Input | Required | Description |
|---|---|---|
terraform_directory | Yes | Path to Terraform code |
target_branch | Yes | Branch to compare against |
provider | Yes | aws, azure, or gcp |
tf-workflow
Terraform deploy with plan approval gates and targeted resource management — runs plan, waits for human approval, then applies. Supports terraform destroy and -target flags.
When to use: Production deployments that require a human to review the plan before apply.
jobs:
deploy:
uses: clouddrove/github-shared-workflows/.github/workflows/tf-workflow.yml@master
with:
working_directory: ./infra/production
provider: aws
approvers: alice,bob # GitHub usernames who can approve
timeout: 30 # minutes to wait for approval
destroy: false
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
BUILD_ROLE: ${{ secrets.BUILD_ROLE }}
| Input | Required | Default | Description |
|---|---|---|---|
working_directory | Yes | — | Path to Terraform root |
provider | Yes | — | aws, azure, or gcp |
approvers | No | — | GitHub usernames who can approve |
timeout | No | 30 | Minutes to wait for approval |
destroy | No | false | Run terraform destroy instead of apply |
target | No | — | Specific resource to target |
plan_only | No | false | Stop after plan, do not apply |
tf-smurf
Multi-cloud Terraform orchestration with approval gates — similar to tf-workflow but adds SSH key support for modules pulled from private repos.
jobs:
deploy:
uses: clouddrove/github-shared-workflows/.github/workflows/tf-smurf.yml@master
with:
working_directory: ./
provider: gcp
approvers: alice
secrets:
GCP_CREDENTIALS: ${{ secrets.GCP_CREDENTIALS }}
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
tf-drift
Detect infrastructure configuration drift — runs terraform plan on a schedule and creates or updates a GitHub Issue when drift is found.
When to use: Schedule nightly or weekly to catch manual changes made outside Terraform.
on:
schedule:
- cron: '0 6 * * *' # every day at 6 AM UTC
jobs:
drift:
uses: clouddrove/github-shared-workflows/.github/workflows/tf-drift.yml@master
with:
working_directory: ./infra
provider: aws
aws_region: us-east-1
secrets:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GITHUB: ${{ secrets.GITHUB_TOKEN }}
| Input | Required | Description |
|---|---|---|
working_directory | Yes | Path to Terraform root |
provider | Yes | aws, azure, or gcp |
var_file | No | Path to .tfvars file |
tf-monorepo-tag-release
Auto-detect module changes and bump versions in monorepos — detects which Terraform module directories changed, bumps the patch/minor/major version, and creates a new git tag.
When to use: Monorepos containing multiple Terraform modules where each module needs its own versioned release.
on:
push:
branches: [master]
jobs:
tag-release:
uses: clouddrove/github-shared-workflows/.github/workflows/tf-monorepo-tag-release.yml@master
with:
module_prefix: terraform-aws- # prefix used in tag names
infracost
Terraform infrastructure cost estimation — runs Infracost to calculate the monthly cost of your Terraform plan and posts a breakdown comment on the pull request.
When to use: On pull requests that change infrastructure, so reviewers can see the cost impact before merging.
jobs:
cost:
uses: clouddrove/github-shared-workflows/.github/workflows/infracost.yml@master
with:
working-directory: ./infra
slack_notification: true
secrets:
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}
GITHUB: ${{ secrets.GITHUB_TOKEN }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
Sign up free at infracost.io to get your INFRACOST_API_KEY.
sst_workflow
Deploy Serverless Stack (SST) applications to AWS — builds and deploys SST v2/v3 apps with support for preview environments and self-hosted runners.
jobs:
deploy:
uses: clouddrove/github-shared-workflows/.github/workflows/sst_workflow.yml@master
with:
app-env: production
working-directory: ./
deploy: true
preview: false
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
build-role: ${{ secrets.BUILD_ROLE }}
env-vars: |
DATABASE_URL=${{ secrets.DATABASE_URL }}
| Input | Required | Default | Description |
|---|---|---|---|
app-env | Yes | — | Environment name (production, staging) |
preview | No | false | Create a preview environment on PRs |
working-directory | No | ./ | App root directory |
deploy | No | true | Run sst deploy |