Skip to content
All projects

Enterprise AWS Infrastructure

Multi-environment AWS infrastructure platform built with Terragrunt and Terraform using a hierarchical blueprint pattern — DRY, policy-gated and cost-aware.

Source code
  • Terragrunt
  • Terraform
  • AWS
  • OPA/Conftest
  • GitHub Actions

The problem

Multi-environment Terraform drifts: dev and prod diverge through copy-paste, and nothing stops a change that is syntactically valid but violates security or blows the budget.

Constraints

Architecture

Governance gates — run in parallel

TFLintstatic analysis
Plandiff check
OPA / Conftestsecurity policy
Infracostcost delta

↓ all gates pass ↓

Dev

eu-central-1 / vpc
eu-central-1 / eks

Prod — protected

eu-central-1 / vpc
eu-central-1 / eks

Interactive CI/CD Pipeline Simulator

Governance Gate Fan-Out & Policy Engine

CI Job Execution Topology

PR Trigger → Terraform Plan Generated (60s)
TFLintStatic Syntax
Diff CheckPlan Analysis
OPA / ConftestSecurity Policy
InfracostCost Delta
✓ All 4 gates fan in simultaneously → Ready to Merge

Review Loop Impact

PR Feedback Velocity:1m 15s (1 Round Trip)
Cost Gate Timing:At PR time (revertable)
Policy Target:Evaluated against compiled Plan, not source HCL

Modeled from typical gate run-times, not a measured production run.

Key decisions

What was chosen, what it was chosen over, and why.

Also decided

  • Infracost sits alongside the security gatesnotReviewing cost monthly, after the fact

    Cost surfaces while the change is still one revert away and in front of the person who made it, rather than weeks later in front of someone who did not.

  • Nightly drift detectionnotTrusting that applied state stays applied

    Out-of-band changes are found on a schedule instead of during the next incident, which is the only way a Git-declared environment stays true over time.

  • Manual approval gate on prod onlynotUniform automation across environments

    Dev applies automatically so the loop stays fast; prod requires a human after dev is stable. The gate is placed where the blast radius is, not everywhere.

Production resilience & failure modes

Failure mode this architecture has to account for

A CI runner is killed mid-apply (a GitHub Actions cancellation, a spot interruption on the runner) before Terraform releases its DynamoDB state lock — the next plan on that environment fails with "Error acquiring the state lock."

How it's handled

The platform doesn't roll back a partial apply — Terraform can't safely destroy resources stuck mid-creation, so the documented recovery is roll-forward: read the lock ID from the error, confirm the runner is actually dead, then `terragrunt force-unlock <LOCK_ID>` and re-apply. The S3 backend means the partial state from the failed run is already durable, so the next plan reconciles from wherever it stopped rather than from scratch.

Source: DISASTER_RECOVERY.md

Deep dive writing