CI/CD Pipelines for Infrastructure Code

March 15, 2026 DevOps CI/CD

If you're still running terraform apply from your laptop, it's time to level up. A proper CI/CD pipeline for infrastructure code brings the same discipline you apply to application deployments.

The Pipeline Stages

  1. terraform fmt -check — Enforce consistent formatting
  2. terraform validate — Catch syntax and configuration errors
  3. tflint — Lint for provider-specific issues
  4. checkov or tfsec — Security scanning
  5. terraform plan — Generate and review the execution plan
  6. Manual approval gate
  7. terraform apply — Apply the approved plan

GitHub Actions Example

name: Terraform
on:
  push:
    branches: [main]
  pull_request:

jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - run: terraform init
      - run: terraform fmt -check
      - run: terraform validate
      - run: terraform plan -out=tfplan
      - uses: actions/upload-artifact@v4
        with:
          name: tfplan
          path: tfplan

  apply:
    needs: plan
    if: github.ref == 'refs/heads/main'
    environment: production
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: hashicorp/setup-terraform@v3
      - uses: actions/download-artifact@v4
        with: { name: tfplan }
      - run: terraform init
      - run: terraform apply tfplan

Key Principles

Always plan on pull requests so reviewers can see exactly what will change. Require approval before apply. Store the plan artifact so the apply step uses the exact same plan that was reviewed. And never, ever store secrets in your Terraform code — use a secrets manager or environment variables injected by your CI system.

← Back to all posts