| name | terragrunt-skill |
| description | Use this skill when working with Terragrunt infrastructure configurations. Triggers include:
- Setting up a new Terragrunt infrastructure catalog from scratch
- Creating or managing Terragrunt stacks (terragrunt.stack.hcl)
- Creating units that wrap OpenTofu modules from separate repos
- Configuring live infrastructure repositories with root.hcl hierarchy
- Setting up remote state backends (S3 with native lockfile or DynamoDB locking)
- Multi-account/multi-environment deployments with cross-account role assumption
- Working with classic Gruntwork-style live repos (account/region/env hierarchy, _envcommon includes)
- Migrating a monolithic Terraform/OpenTofu repo (terralith) to Terragrunt
- Exploring or auditing an existing Terragrunt repository (find, list, dag graph)
- Wiring unit dependencies (values pattern or autoinclude blocks)
- Speeding up clones/fetches or making catalog stacks self-contained with the Content Addressable Store (CAS, update_source_with_cas)
|
Terragrunt Infrastructure Skill
Overview
This skill provides guidance for infrastructure using Terragrunt with OpenTofu, following a three-repository pattern:
- Infrastructure Catalog - Units and stacks that reference modules from separate repos
- Infrastructure Live - Environment-specific deployments consuming the catalog
- Module Repos - Separate repositories for each OpenTofu module (independent versioning)
Choosing an Architecture
Default recommendation: explicit stacks — the catalog + terragrunt.stack.hcl + values pattern this skill teaches. Units are generated from stack files; configuration flows through values; no per-unit boilerplate.
Supported alternative: classic implicit stacks — the original Gruntwork pattern: account/region/env/component directory hierarchy, per-level .hcl variable files, shared component config in _envcommon/ via include + expose. Any directory of units is an implicit stack. Use it when the repo already follows it, when the footprint is too small to justify a catalog, or when the team isn't ready for stacks. See classic-live-structure.md.
Orthogonal choice: module organization — modules monorepo (modules/ + examples/, one tag versions all, //modules/x?ref= sourcing) vs module-per-repo (independent versioning). Either works with either architecture. See modules-monorepo.md.
Migrating classic → stacks: follow the official Terralith to Terragrunt guide.
Quick Navigation
Core Concepts
Values Pattern
Units receive configuration through values.xxx:
inputs = {
name = values.name
environment = values.environment
instance_class = try(values.instance_class, "db.t3.medium") # Optional with default
}
Reference Resolution
Units resolve symbolic references like "../acm" to dependency outputs:
inputs = {
acm_certificate_arn = try(values.acm_certificate_arn, "") == "../acm" ?
dependency.acm.outputs.acm_certificate_arn :
values.acm_certificate_arn
}
Terragrunt 1.1+ adds autoinclude blocks as an alternative — dependencies declared in the stack file, catalog units stay dependency-agnostic. See dependencies.md for choosing between them.
Module Sourcing
Units reference modules via Git URL with version from values:
terraform {
source = "git::git@github.com:YOUR_ORG/modules/rds.git//app?ref=${values.version}"
}
For catalog-internal references (units/stacks/modules in the same repo), Terragrunt 1.1+ allows plain relative paths with update_source_with_cas = true — stack generate rewrites them to content-addressed references, so no URL pinning or version plumbing is needed. See cas.md.
Common Operations
Create New Unit
- Create
units/<name>/terragrunt.hcl
- Reference module via Git URL with
${values.version}
- Use
values.xxx for inputs
- Add dependencies with mock outputs
- Implement reference resolution for
"../unit" patterns
Create New Stack
- Create
stacks/<name>/terragrunt.stack.hcl
- Define
locals for computed values
- Add
unit blocks referencing catalog units
- Pass values including version and dependency paths
Deploy to New Environment
- Create environment directory structure
- Add
env.hcl with state_bucket_suffix
- Run
terragrunt run --all -- backend bootstrap to create state resources
- Add stack files referencing catalog
Best Practices
- Pin module versions - Use Git tags in
values.version
- Pin catalog versions - Use refs in unit source URLs
- Use reference resolution -
"../unit" → dependency outputs
- Provide mock outputs - Enable plan/validate without dependencies
- Auto-detect features -
length(keys(try(values.X, {}))) > 0
- Override paths -
try(values.X_path, "../default")
- Separate state per environment - Use
state_bucket_suffix
Common Pitfalls
- Git refspec error - Use
//path?ref=branch NOT ?ref=branch//path
- Heredoc in ternary - Wrap in parentheses:
condition ? (\n<<-EOF\n...\nEOF\n) : ""
- Missing mock outputs - Always provide for plan/validate
- Hardcoded paths - Use local paths only for testing
Version Management
- Development: Branch refs (
ref=feature-branch)
- Testing: RC tags (
ref=v1.0.0-rc1)
- Production: Stable tags (
ref=v1.0.0)