Skip to content

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 plan against 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 apply against 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-coredeploy-dev-appsdeploy-prod-coredeploy-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