the multi-env problem
With plain Terraform, managing multiple environments means duplicating config - same modules, different variable files, same backend boilerplate repeated everywhere.
environments/
├── dev/
│ ├── main.tf # copy
│ ├── variables.tf # copy
│ └── backend.tf # copy with different key
├── staging/
│ ├── main.tf # copy
│ ├── variables.tf # copy
│ └── backend.tf # copy with different key
└── prod/
├── main.tf # copy
├── variables.tf # copy
└── backend.tf # copy with different key
Any change to the module requires updating all three.
what Terragrunt does
Terragrunt is a thin wrapper around Terraform that adds:
- DRY backend config - define once, inherit everywhere
-
dependencyblocks - wire modules together without a monolith -
run-all- apply/plan/destroy across multiple modules in one command -
generateblocks - auto-generate files (provider configs, backend configs) -
mock_outputs- unblockplanin CI when dependencies haven't been applied yet
terraform vs terragrunt
| Terraform | Terragrunt | |
|---|---|---|
| Backend config | per-module | inherited from root |
| Multi-module apply | manual | run-all |
| Module wiring | terraform_remote_state |
dependency block |
| DRY config | variables only | full config inheritance |
installation
asdf plugin-add terragrunt
asdf install terragrunt 0.67.0
asdf local terragrunt 0.67.0
or developer.hashicorp.com/terraform/tutorials/automation/terragrunt
what the structure looks like
Instead of duplicated .tf files, you get one root.hcl and small terragrunt.hcl files per unit that only define what's different:
root.hcl
environments/
├── dev/
│ ├── vpc/
│ │ └── terragrunt.hcl # 5 lines: include + inputs
│ ├── rds/
│ │ └── terragrunt.hcl
│ └── eks/
│ └── terragrunt.hcl
└── prod/
├── vpc/
│ └── terragrunt.hcl
├── rds/
│ └── terragrunt.hcl
└── eks/
└── terragrunt.hcl
A typical leaf terragrunt.hcl:
include "root" {
path = find_in_parent_folders("root.hcl")
}
terraform {
source = "git::https://github.com/org/tf-modules.git//vpc?ref=v1.2.0"
}
inputs = {
name = "prod-vpc"
cidr_block = "10.0.0.0/16"
}
The backend, provider, and locking config all come from root.hcl - no repetition.
See folder structure and include for the full root.hcl setup.
Originally published at https://bard.sh/posts/what_is_terragrunt/
Top comments (0)