Terraform in CI/CD Pipelines

Production-level Terraform CI/CD: Code Commit → Validate → Format Check → Terraform Init → Plan → Policy Check (Sentinel/OPA) → Manual Approval → Apply. Remote state in S3 + DynamoDB lock. GitHub Actions flow, folder structure, and best practices for safe infrastructure automation.

Overview

Why Terraform needs a pipeline

Running Terraform manually is fine for experiments. In production without CI/CD there is no peer review, no audit trail, no policy enforcement and no protection against two people applying at once.

  • Consistent — The same pipeline runs every time
  • Collaborative — Changes are reviewed via PR
  • Auditable — Full history in CI logs
  • Safe — Policy gates and manual approval before Apply

The nine-step pipeline

  • 1. Code commit — Engineer raises a PR with .tf changes
  • 2. Validate — terraform validate checks syntax and references
  • 3. Format check — terraform fmt -check fails if code is not formatted, enforcing one style
  • 4. Init — Downloads providers and configures the backend (S3 remote state)
  • 5. Plan — Shows exactly what will be created, modified or destroyed; uploaded as a CI artifact for reviewers
  • 6. Policy/security check — Sentinel (enterprise), OPA (open source) or Checkov scans the plan: no public S3 buckets, instance type allowlist, tagging requirements
  • 7. Manual approval — A human reviews the plan and policy results; the critical gate for production
  • 8. Apply — Applies the exact plan artifact from step 5, avoiding drift between plan and apply
  • 9. Production cloud — Resources are created or modified as planned

> [!IMPORTANT] Apply the saved plan from step 5, never a fresh one.

Remote state

terraform.tfstate is stored in S3, with S3 versioning for state recovery. A lock ensures only one operation modifies state at a time.

  • S3 — Stores terraform.tfstate centrally; versioning allows recovery
  • DynamoDB table — Classic state locking
  • use_lockfile = true — Native S3 locking since Terraform 1.10; 1.11 deprecated dynamodb_table

Production folder structure

  • modules/ — Reusable components: vpc, ec2, alb
  • envs/dev, envs/prod — Environment-specific configurations calling modules
  • backend.tf — S3 backend config
  • provider.tf, variables.tf, outputs.tf, main.tf — Provider, inputs, outputs, resources

Key concepts

terraform plan artifact
The binary plan file generated by terraform plan -out=tfplan. Using this artifact in the Apply step guarantees exactly what was reviewed gets applied — no drift between plan and apply due to code changes or timing.
DynamoDB state locking
Terraform writes a lock entry to a DynamoDB table when it starts plan or apply. If another operation tries to run simultaneously, it sees the lock and fails with an error. Prevents race conditions in CI/CD and concurrent manual runs.
Sentinel / OPA policy as code
Policy engines that evaluate the Terraform plan against rules. Example rules: EC2 instances must be in the allowed_instance_types list, S3 buckets must have encryption enabled, all resources must have required tags. Violations fail the pipeline before Apply.
Manual approval gate
A required human review step in the pipeline between Plan and Apply. In GitHub Actions: environment protection rules with required reviewers. In GitLab CI: manual job trigger. Ensures a human eyes the plan before infrastructure is modified.
Workspace vs environment folders
Terraform Workspaces allow multiple state files per configuration (dev/staging/prod). Environment folders (envs/dev/, envs/prod/) are separate directories with separate backend configs — more explicit and easier to review. Both approaches are valid; environment folders are preferred for large teams.
Checkov
Open-source static analysis tool for Terraform and other IaC. Scans .tf files for security misconfigurations before plan (faster than Sentinel/OPA which operate on the plan). Run as a CI step: checkov -d . — fails on high/critical findings.

When to use it

  • Any team running Terraform in production — manual apply is not acceptable at scale
  • Meeting compliance requirements for infrastructure changes (SOC2, PCI-DSS require change control)
  • Multi-engineer teams where two people could accidentally apply conflicting changes
  • Organizations that need an audit trail of every infrastructure change
  • Implementing GitOps for infrastructure — Terraform state follows Git as the source of truth

Interview questions

  • How do you safely run Terraform in a CI/CD pipeline?
  • Describe Terraform remote state with S3 and DynamoDB.

Sign up free to read the full topic

More DevOps topics

Start free on Cariara · Coding problems · System design studio