Terraform in CI/CD & automation
Plan on PR, apply on merge, safely.
Running Terraform from laptops does not scale and is not safe: no review of what will change, no audit trail, credentials scattered across machines. The mature pattern automates it — plan on every pull request so reviewers see the exact diff, and apply automatically on merge, from CI, using short-lived credentials. Git becomes the source of truth and the audit log.
Save the plan, apply exactly it
The safety hinge is separating plan and apply across the review boundary. CI runs terraform plan -out=tfplan on the PR and posts it; a human approves; on merge, CI runs terraform apply tfplan — applying precisely the reviewed plan, with no recomputation. Tools like Atlantis wrap this whole flow around pull requests (comment atlantis plan / atlantis apply); Terraform Cloud, GitLab, and GitHub Actions all implement the same shape.
jobs:plan:permissions: { id-token: write, contents: read } # OIDC, not static keyssteps:- uses: aws-actions/configure-aws-credentials@v4with: { role-to-assume: arn:aws:iam::...:role/tf-ci, aws-region: us-east-1 }- run: terraform init- run: terraform plan -out=tfplan- run: terraform show -json tfplan | conftest test - # policy gate# apply job runs on merge to main, using the saved tfplan artifact
Credentials: OIDC, not long-lived keys
The biggest CI security win is deleting static cloud keys. Modern CI (GitHub Actions, GitLab) can exchange a short-lived OIDC token for a cloud role at run time, so the pipeline assumes a scoped IAM role for minutes instead of storing a permanent access key that could leak. Combined with a narrow role (only what this pipeline provisions) and a protected apply job, the automation is more secure than any laptop.