Why Terragrunt exists
The DRY and state problems it solves.
Terragrunt is a thin wrapper around Terraform (and OpenTofu) that exists to fix the problems you hit once a Terraform codebase grows past a handful of modules. It does not replace Terraform — it calls it under the hood — but it removes the repetition and adds the orchestration that raw Terraform lacks at scale. If you have ever copy-pasted the same backend block into thirty directories, or struggled to apply twenty interdependent modules in the right order, Terragrunt is the answer.
Two problems dominate. First, repetition: every Terraform root module needs its own backend configuration, provider setup, and often the same input values, duplicated across environments and components — and duplication drifts. Second, orchestration: Terraform has no built-in way to apply many separate state units in dependency order or share outputs between them cleanly. Terragrunt keeps configuration DRY (define it once, reference it) and understands dependencies between units.
Small state units, kept DRY
The design Terragrunt encourages is many small, independent state files — one per component per environment (a vpc unit, a database unit, an app unit, times dev/staging/prod) — instead of one giant state. Small units mean small blast radius and fast plans, but they multiply the boilerplate; Terragrunt makes that structure practical by generating the repetitive parts and wiring the units together. Small units plus DRY glue is the whole philosophy.