CI/CD for infrastructure
Two GitHub Actions workflows automate Terraform in your IaC repository:
- one plans changes in pull requests
- another applies automatically when changes are merged
Both workflows are file-based - that is, they only run against stacks that contain changed files. They can, however, be manually triggered on-demand.
The CI/CD setup has standardized on two types of environments: dev (for non-production) and prod (for production). If your environments are called something else internally, you'll still use dev and prod when configuring CI/CD.
Manual trigger
Both workflows can be triggered on-demand by issuing a workflow_dispatch event on GitHub. The input supports glob wildcards (*, **), brace expansion ({a,b}), and comma- or newline-delimited lists (e.g., stacks/**, stacks/{dev,prod}/databases or stacks/dev/app-*).
Plan workflow
terraform-pr.yml in your IaC repo is a thin caller of the reusable-terraform-pr reusable workflow. It runs on pull requests that touch IaC files.
- Detects which stacks contain changed files and runs
terraform planagainst those stacks in parallel - unchanged stacks are skipped to keep PRs scoped to what actually changed. - Posts results as PR comments.
Apply workflow
terraform-apply.yml in your IaC repo is a thin caller of the reusable-terraform-apply reusable workflow. It runs automatically on pushes to the default branch (e.g., main).
Push to apply
Every push to the default branch automatically runs terraform apply against your environments. Your default branch becomes the source of truth for what's applied: everything on it is either already live or on its way out.
- Detects which stacks contain changed files and runs
terraform applyagainst those stacks in a predefined order. - Only one apply runs at a time per stack. A new push won't interrupt an apply that's already running, and if changes pile up while one is in progress, the workflow skips ahead to the most recent one.
The workflow runs up to four sequential jobs, and if a job fails, all later jobs are skipped:
deploy-dev-core → deploy-dev-apps → deploy-prod-core → deploy-prod-apps
Apply order
To determine the order in which stacks apply, the apply workflow groups them into two categories:
- "Core" stacks are foundational stacks that other stacks typically depend on (remote state, networking, IAM, databases,
<stack>-data, ...). Within an environment, core stacks are applied sequentially in a predefined order so dependencies are maintained. - "Apps" stacks are everything else - typically the stacks that contain individual applications and that depend on core stacks. Within an environment, apps stacks apply in parallel; they are assumed to not depend on each other.
A stack is treated as core if its directory name matches a list of built-in patterns (e.g., **/remote-state, **/networking, ...). Teams using standard Golden Path stack names get correct ordering with no configuration.
Customize apply order
You can configure additional-core-stacks (appends) or core-stacks (replaces) as inputs to the apply workflow to customize the apply order. See the determine-stacks composite action - used internally by the reusable workflow - for the full default pattern list.
See also
- Getting started with CI/CD for new environments:
- Setup CI/CD common
- Set up Terraform workflows
- Getting started with CI/CD for existing environments
- Architecture Decision Records (ADRs)