Comprehensive toolkit for generating best practice Terragrunt configurations (HCL files) following current standards and conventions. Use this skill when creating new Terragrunt resources (root configs, child modules, stacks, environment setups), or building multi-environment Terragrunt projects.
Overall
score
93%
Does it follow best practices?
Validation for skill structure
Generate production-ready Terragrunt configurations following current best practices, naming conventions, and security standards. All generated configurations are automatically validated.
Terragrunt 2025 Features Supported:
terragrunt.stack.hcl (GA since v0.78.0)feature blocksskip)retryable_errors)RECOMMENDED: Use
root.hclinstead ofterragrunt.hclfor root files per migration guide.
| Approach | Root File | Include Syntax |
|---|---|---|
| Modern | root.hcl | find_in_parent_folders("root.hcl") |
| Legacy | terragrunt.hcl | find_in_parent_folders() |
CRITICAL: Before generating ANY configuration, determine the architecture pattern and understand its constraints.
| Pattern | Use When | Root Behavior | Structure |
|---|---|---|---|
| A: Multi-Env Agnostic | Multiple environments with shared root | Root reads NO env files; uses static values or get_env() | root.hcl + {env}/env.hcl per environment |
| B: Single/Env-Aware | Single environment OR environment detection needed | Root can parse path or read get_env() | root.hcl with optional account.hcl/region.hcl |
| C: Centralized Vars | Shared environment definitions | Root is agnostic; env.hcl reads from _env/ | root.hcl + _env/{env}.hcl + {env}/env.hcl |
Key principle: root.hcl does NOT read env.hcl. Child modules read env.hcl directly.
infrastructure/
├── root.hcl # Environment-AGNOSTIC
├── dev/env.hcl # locals { environment = "dev" }
│ └── vpc/terragrunt.hcl
└── prod/env.hcl # locals { environment = "prod" }
└── vpc/terragrunt.hclChild module pattern:
include "root" { path = find_in_parent_folders("root.hcl") }
locals { env = read_terragrunt_config(find_in_parent_folders("env.hcl")) }
inputs = { name = "${local.env.locals.environment}-vpc" }Key principle: Root detects environment from path or environment variable.
# root.hcl
locals {
path_parts = split("/", path_relative_to_include())
environment = local.path_parts[0] # OR: get_env("TG_ENVIRONMENT", "dev")
}Key principle: Each env.hcl reads from centralized _env/{env}.hcl.
# prod/env.hcl
locals {
env_vars = read_terragrunt_config("${get_repo_root()}/_env/prod.hcl")
environment = local.env_vars.locals.environment
aws_region = local.env_vars.locals.aws_region
}Decision: Multi-env + shared root → A | Single env / env detection → B | Centralized vars → C
Create root-level root.hcl or terragrunt.hcl with remote state, provider config, and common variables.
Read before generating: assets/templates/root/terragrunt.hcl
Patterns: references/common-patterns.md → Root Configuration Patterns
Key placeholders to replace:
[BUCKET_NAME], [AWS_REGION], [DYNAMODB_TABLE][TERRAFORM_VERSION], [PROVIDER_NAME], [PROVIDER_VERSION][ENVIRONMENT], [PROJECT_NAME]Root.hcl Design Principles:
get_env() for runtime configpath_relative_to_include() — Automatically includes environment pathCreate child modules with dependencies, mock outputs, and proper includes.
Read before generating: assets/templates/child/terragrunt.hcl
Patterns: references/common-patterns.md → Child Module Patterns
Module source options:
"../../modules/vpc""git::https://github.com/org/repo.git//path?ref=v1.0.0""tfr:///terraform-aws-modules/vpc/aws?version=5.1.0"Self-contained modules without root dependency.
Read before generating: assets/templates/module/terragrunt.hcl
Complete directory structures for dev/staging/prod.
Before generating:
Patterns: references/common-patterns.md → Environment-Specific Patterns
Typical structure (Pattern A):
infrastructure/
├── root.hcl # Environment-AGNOSTIC root config
├── dev/
│ ├── env.hcl # Dev environment variables
│ └── vpc/terragrunt.hcl
└── prod/
├── env.hcl # Prod environment variables
└── vpc/terragrunt.hclInfrastructure blueprints using terragrunt.stack.hcl.
Read before generating: assets/templates/stack/terragrunt.stack.hcl and assets/templates/catalog/terragrunt.hcl
Docs: Stacks Documentation
Patterns: references/common-patterns.md → Stacks Patterns
Commands:
terragrunt stack generate # Generate unit configurations
terragrunt stack run plan # Plan all units
terragrunt stack run apply # Apply all units
terragrunt stack output # Get aggregated outputs
terragrunt stack clean # Clean generated directoriesRuntime control without code changes.
Docs: Feature Flags Documentation
Patterns: references/common-patterns.md → Feature Flags Patterns
CRITICAL: Feature flag
defaultvalues MUST be static (boolean, string, number) — they CANNOT referencelocal.*values.
# Correct: static default
feature "enable_monitoring" {
default = false
}
# Incorrect: dynamic reference — FAILS
feature "enable_monitoring" {
default = local.env.locals.enable_monitoring
}Usage:
terragrunt apply --feature enable_monitoring=true
# or
export TG_FEATURE="enable_monitoring=true"Fine-grained execution control (replaces deprecated skip).
Docs: Exclude Block Reference
Patterns: references/common-patterns.md → Exclude Block Patterns
Actions: "plan", "apply", "destroy", "all", "all_except_output"
Production recommendation: Protect critical resources from accidental destruction:
exclude {
if = true
actions = ["destroy"]
exclude_dependencies = false
}
prevent_destroy = trueAdvanced error handling (replaces deprecated retryable_errors).
Docs: Errors Block Reference
Patterns: references/common-patterns.md → Errors Block Patterns
Use OpenTofu as the IaC engine.
Docs: Engine Documentation
Patterns: references/common-patterns.md → OpenTofu Engine Patterns
When generating configs with custom providers:
"[provider] terraform provider [version] documentation"required_providers blockCRITICAL: Follow this workflow for EVERY generation task. Skipping steps leads to validation errors.
| Scenario | Pattern | Root.hcl Scope |
|---|---|---|
| Multi-env with shared root | Pattern A | Environment-agnostic |
| Single environment | Pattern B | Environment-aware |
| Centralized env vars | Pattern C | Environment-agnostic |
MANDATORY: Before writing any files, complete and output this checklist to the user.
## Architecture Pattern Selection
[x] Identified architecture pattern: Pattern ___ (A/B/C)
[x] Root.hcl scope: [ ] environment-agnostic OR [ ] environment-aware
[x] env.hcl location: ___________________
[x] Child modules access env via: ___________________
[x] Verified: No file references a path that doesn't exist from its location| Configuration Type | Template to Read |
|---|---|
| Root configuration | assets/templates/root/terragrunt.hcl |
| Child module | assets/templates/child/terragrunt.hcl |
| Standalone module | assets/templates/module/terragrunt.hcl |
| Stack file | assets/templates/stack/terragrunt.stack.hcl |
| Catalog unit | assets/templates/catalog/terragrunt.hcl |
Also read: references/common-patterns.md — primary source for all generation patterns.
Generation order for multi-environment projects:
Generate root.hcl first
read_terragrunt_config(find_in_parent_folders("env.hcl")) if environment-agnosticremote_state block has encrypt = trueerrors block used (not deprecated retryable_errors)Generate env.hcl files for each environment
locals block contains environment, aws_region, and module-specific varsGenerate child modules — modules with NO dependencies first
include block uses find_in_parent_folders("root.hcl")read_terragrunt_config(find_in_parent_folders("env.hcl")) presentterraform.source uses valid syntax (tfr:///, git::, or relative path)Generate dependent modules (RDS, EKS, etc.)
dependency blocks have mock_outputsmock_outputs_allowed_terraform_commands includes ["validate", "plan", "destroy"]prevent_destroy = true and/or exclude blockRun batch validation after ALL files are generated:
terragrunt hcl fmt --check # Format validation
terragrunt dag graph # Dependency graph validationInvoke devops-skills:terragrunt-validator for comprehensive validation.
If validation fails:
Follow the Presentation Requirements section below.
Every generated configuration MUST be validated.
After generating root.hcl:
cd <infrastructure-directory>
terragrunt hcl fmt --checkAfter generating each child module:
cd <module-directory>
terragrunt hcl fmt --check
# If no dependencies on other modules:
terragrunt hcl validate --inputsAfter all files are generated:
devops-skills:terragrunt-validator skillSkip validation only for: Partial snippets, documentation examples, or explicit user request.
After successful validation, present ALL of the following sections.
tree <infrastructure-directory>| File | Purpose |
|------|---------|
| root.hcl | Shared configuration for all child modules (state backend, provider) |
| dev/env.hcl | Development environment variables |
| prod/env.hcl | Production environment variables |
| dev/vpc/terragrunt.hcl | VPC module for development |
| ... | ... |## Usage Instructions
### Prerequisites
1. AWS credentials configured (`aws configure` or environment variables)
2. S3 bucket `<BUCKET_NAME>` exists for state storage
3. DynamoDB table `<TABLE_NAME>` exists for state locking
### Commands
cd <INFRASTRUCTURE_DIR>
terragrunt run --all init # Initialize all modules
cd <ENV>/vpc && terragrunt plan # Preview a specific module
terragrunt run --all plan # Preview all changes
terragrunt run --all apply # Apply changes (requires approval)
terragrunt run --all destroy # Destroy (use with extreme caution)## Environment Notes
### Required Environment Variables
| Variable | Description | Example |
|----------|-------------|---------|
| AWS_PROFILE | AWS CLI profile to use | `my-profile` |
| AWS_REGION | AWS region (or set in provider) | `us-east-1` |
### Prerequisites
- [ ] S3 bucket `<BUCKET_NAME>` must exist before first run
- [ ] DynamoDB table `<TABLE_NAME>` must exist for state locking
- [ ] IAM permissions for Terraform state management
### Production-Specific Protections
| Module | Protection | Description |
|--------|------------|-------------|
| prod/rds | `prevent_destroy = true` | Prevents accidental database deletion |
| prod/rds | `exclude { actions = ["destroy"] }` | Blocks destroy commands |Suggest what the user might want to do next (add more modules, customize configurations, etc.)
Reference ../devops-skills:terragrunt-validator/references/best_practices.md for comprehensive guidelines.
Key principles:
include blocks to inherit root configuration (DRY)encrypt = true)generate blocks for provider configuration~> 5.0, not >= 5.0) for local/Git modulesNote on Version Constraints with Registry Modules: When using Terraform Registry modules (e.g.,
tfr:///terraform-aws-modules/vpc/aws?version=5.1.0), they typically define their ownrequired_providers. Omit generatingrequired_providersinroot.hclto avoid conflicts — the module's pinned version provides the constraint.
Anti-patterns to avoid:
| Deprecated | Replacement | Reference |
|---|---|---|
skip | exclude block | Docs |
retryable_errors | errors.retry block | Docs |
run-all | run --all | Migration |
--terragrunt-* flags | Unprefixed flags | CLI Reference |
TERRAGRUNT_* env vars | TG_* env vars | CLI Reference |
| Configuration Type | Template File | When to Read |
|---|---|---|
| Root configuration | assets/templates/root/terragrunt.hcl | Before generating any root.hcl |
| Child module | assets/templates/child/terragrunt.hcl | Before generating any child module |
| Standalone module | assets/templates/module/terragrunt.hcl | Before generating standalone modules |
| Stack file | assets/templates/stack/terragrunt.stack.hcl | Before generating stacks |
| Catalog unit | assets/templates/catalog/terragrunt.hcl | Before generating catalog units |
| Reference | Content | When to Read |
|---|---|---|
references/common-patterns.md | All generation patterns with examples | Always, before generating |
references/troubleshooting.md | Common issues and fixes | When encountering errors |
../devops-skills:terragrunt-validator/references/best_practices.md | Comprehensive best practices | Always, before generating |
For troubleshooting guidance, see references/troubleshooting.md, which covers:
Install with Tessl CLI
npx tessl i pantheon-ai/terragrunt-generator