--- name: terragrunt-generator description: Generate/create/scaffold Terragrunt HCL files — root.hcl, terragrunt.hcl, child modules, stacks, multi-env layouts. --- # Terragrunt Generator ## Overview Generate production-ready Terragrunt configurations following current best practices, naming conventions, and security standards. All generated configurations are automatically validated. ## Trigger Phrases Use this skill when the user asks for: - A new `root.hcl`, `terragrunt.hcl`, or `terragrunt.stack.hcl` - Multi-environment Terragrunt layouts (`dev/staging/prod`) - Terragrunt dependency wiring (`dependency` or `dependencies` blocks) - Terragrunt module source setup (local, Git, Terraform Registry via `tfr:///`) - Stack catalog unit generation under `catalog/units/*` **Terragrunt 2025 Features Supported:** - [Stacks](https://terragrunt.gruntwork.io/docs/features/stacks/) - Infrastructure blueprints with `terragrunt.stack.hcl` (GA since v0.78.0) - [Feature Flags](https://terragrunt.gruntwork.io/docs/features/feature-flags/) - Runtime control via `feature` blocks - [Exclude Blocks](https://terragrunt.gruntwork.io/docs/reference/config-blocks-and-attributes/#exclude) - Fine-grained execution control (replaces deprecated `skip`) - [Errors Blocks](https://terragrunt.gruntwork.io/docs/reference/config-blocks-and-attributes/#errors) - Advanced error handling (replaces deprecated `retryable_errors`) - [OpenTofu Engine](https://terragrunt.gruntwork.io/docs/features/engine/) - Alternative IaC engine support ## Root Configuration Naming > **RECOMMENDED**: Use `root.hcl` instead of `terragrunt.hcl` for root files per [migration guide](https://terragrunt.gruntwork.io/docs/migrate/migrating-from-root-terragrunt-hcl). | Approach | Root File | Include Syntax | |----------|-----------|----------------| | **Modern** | `root.hcl` | `find_in_parent_folders("root.hcl")` | | **Legacy** | `terragrunt.hcl` | `find_in_parent_folders()` | **Include standard:** Default to `find_in_parent_folders("root.hcl")` in all new examples and generated configs. Use `find_in_parent_folders()` only when explicitly targeting a legacy root file named `terragrunt.hcl`. ## Architecture Patterns > **CRITICAL:** Before generating ANY configuration, you MUST determine the architecture pattern and understand its constraints. ### Pattern A: Multi-Environment with Environment-Agnostic Root **Use when:** Managing multiple environments (dev/staging/prod) with shared root configuration. **Key principle:** `root.hcl` is **environment-agnostic** - it does NOT read environment-specific files. ``` infrastructure/ ├── root.hcl # Environment-AGNOSTIC (no env.hcl references) ├── dev/ │ ├── env.hcl # Environment variables (locals block) │ ├── vpc/terragrunt.hcl │ └── rds/terragrunt.hcl └── prod/ ├── env.hcl # Environment variables (locals block) ├── vpc/terragrunt.hcl └── rds/terragrunt.hcl ``` **Root.hcl constraints:** - ❌ CANNOT use `read_terragrunt_config(find_in_parent_folders("env.hcl"))` - env.hcl doesn't exist at root level - ❌ CANNOT reference `local.environment` or `local.aws_region` that come from env.hcl - ✅ CAN use static values or `get_env()` for runtime configuration - ✅ CAN use `${path_relative_to_include()}` for state keys (this works dynamically) **Child modules read env.hcl:** ```hcl # dev/vpc/terragrunt.hcl 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" # Works: env.hcl exists in dev/ } ``` ### Pattern B: Single Environment or Environment-Aware Root **Use when:** Single environment OR all environments share the same root with environment detection. ``` infrastructure/ ├── root.hcl # Can be environment-aware via get_env() or directory parsing ├── account.hcl # Account-level config (optional) ├── region.hcl # Region-level config (optional) └── vpc/ └── terragrunt.hcl ``` **Root.hcl can detect environment:** ```hcl # root.hcl - environment detection via directory path locals { # Parse environment from path (e.g., "prod/vpc" -> "prod") path_parts = split("/", path_relative_to_include()) environment = local.path_parts[0] # OR use environment variable environment = get_env("TG_ENVIRONMENT", "dev") } ``` ### Pattern C: Shared Environment Variables (_env directory) **Use when:** Centralizing environment variables with symlinks or direct references. ``` infrastructure/ ├── root.hcl # Environment-AGNOSTIC ├── _env/ # Centralized environment definitions │ ├── prod.hcl │ ├── staging.hcl │ └── dev.hcl ├── prod/ │ ├── env.hcl # Reads from _env/prod.hcl │ └── vpc/terragrunt.hcl └── dev/ ├── env.hcl # Reads from _env/dev.hcl └── vpc/terragrunt.hcl ``` **env.hcl reads from _env:** ```hcl # prod/env.hcl locals { env_vars = read_terragrunt_config("${get_repo_root()}/_env/prod.hcl") # Re-export for child modules environment = local.env_vars.locals.environment aws_region = local.env_vars.locals.aws_region vpc_cidr = local.env_vars.locals.vpc_cidr # ... other variables } ``` ### Architecture Pattern Selection Checklist (Canonical) > **MANDATORY:** Before writing any files, you MUST complete this checklist and OUTPUT it to the user with checkmarks filled in. This is not optional. **Output this completed checklist before generating any files:** ``` ## 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 ``` **Example completed checklist:** ``` ## Architecture Pattern Selection [x] Identified architecture pattern: Pattern A (Multi-Environment with Environment-Agnostic Root) [x] Root.hcl scope: [x] environment-agnostic OR [ ] environment-aware [x] env.hcl location: dev/env.hcl, prod/env.hcl (one per environment) [x] Child modules access env via: read_terragrunt_config(find_in_parent_folders("env.hcl")) [x] Verified: No file references a path that doesn't exist from its location ``` ## Quick Variable Definition Examples Use these starter files for Pattern B and account/region-aware setups. **env.hcl** ```hcl locals { environment = "dev" aws_region = "us-east-1" project = "platform" } ``` **account.hcl** ```hcl locals { account_id = "123456789012" account_name = "shared-services" } ``` **region.hcl** ```hcl locals { aws_region = "us-east-1" } ``` ## When to Use - Creating new Terragrunt projects or configurations - Setting up multi-environment infrastructure (dev/staging/prod) - Implementing DRY Terraform configurations - Managing complex infrastructure with dependencies - Working with custom Terraform providers or modules ## Core Capabilities ### 1. Generate Root Configuration Create root-level `root.hcl` or `terragrunt.hcl` with remote state, provider config, and common variables. > **MANDATORY:** Before generating, READ the template file: > ``` > Read: assets/templates/root/terragrunt.hcl > ``` **Template:** `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_SOURCE]`, `[PROVIDER_VERSION]` - `[ENVIRONMENT]`, `[PROJECT_NAME]` **Root.hcl Design Principles:** 1. **Environment-agnostic by default** - Don't assume env.hcl exists at root level 2. **Use static values for provider/backend region** - Or use `get_env()` for runtime config 3. **State key uses `path_relative_to_include()`** - This automatically includes environment path 4. **Provider tags can be static** - Environment-specific tags go in child modules ### 2. Generate Child Module Configuration Create child modules with dependencies, mock outputs, and proper includes. > **MANDATORY:** Before generating, READ the template file: > ``` > Read: assets/templates/child/terragrunt.hcl > ``` **Template:** `assets/templates/child/terragrunt.hcl` **Patterns:** `references/common-patterns.md` → Child Module Patterns **Module source options:** - Local: `"../../modules/vpc"` - Git: `"git::https://github.com/org/repo.git//path?ref=v1.0.0"` - Registry: `"tfr:///terraform-aws-modules/vpc/aws?version=5.1.0"` ### 3. Generate Standalone Module Self-contained modules without root dependency. > **MANDATORY:** Before generating, READ the template file: > ``` > Read: assets/templates/module/terragrunt.hcl > ``` **Template:** `assets/templates/module/terragrunt.hcl` ### Canonical Placeholder Replacement Map Use this map for every generated output: | Placeholder | Meaning | Example Replacement | Notes | |-------------|---------|---------------------|-------| | `[AWS_REGION]` | AWS region | `us-east-1` | Canonical region placeholder in all templates | | `[ENVIRONMENT]` | Environment name | `dev` | Keep lowercase for directory naming | | `[PROJECT_NAME]` | Project/application name | `payments-platform` | Use the same value in tags and names | | `[BUCKET_NAME]` | Remote state S3 bucket | `acme-tfstate-prod` | Bucket must exist before first apply | | `[DYNAMODB_TABLE]` | State lock table | `acme-terraform-locks` | Table must exist before first apply | | `[PROVIDER_SOURCE]` | Terraform provider source | `hashicorp/aws` | Use fully qualified source | | `[TERRAFORM_VERSION]` | Required Terraform/OpenTofu version | `1.8.5` | Used in both `terraform_version_constraint` and `required_version`. Keep compatible with module constraints. | **Legacy alias normalization:** If you see `[REGION]` in older examples, treat it as `[AWS_REGION]` and replace it before validation. ### 4. Generate Multi-Environment Infrastructure Complete directory structures for dev/staging/prod. > **MANDATORY:** Before generating: > 1. Determine architecture pattern (see Architecture Patterns section) > 2. Read relevant templates for root, env, and child modules > 3. Verify env.hcl placement and access patterns: > ``` > Read: assets/templates/env/env.hcl > ``` **Patterns:** `references/common-patterns.md` → Environment-Specific Patterns **Typical structure (Pattern A - Environment-Agnostic Root):** ``` infrastructure/ ├── root.hcl # Environment-AGNOSTIC root config ├── dev/ │ ├── env.hcl # Dev environment variables │ └── vpc/terragrunt.hcl └── prod/ ├── env.hcl # Prod environment variables └── vpc/terragrunt.hcl ``` ### 5. Generate Terragrunt Stacks (2025) Infrastructure blueprints using `terragrunt.stack.hcl`. > **MANDATORY:** Before generating, READ the template files: > ``` > Read: assets/templates/stack/terragrunt.stack.hcl > Read: assets/templates/catalog/terragrunt.hcl > ``` **Docs:** [Stacks Documentation](https://terragrunt.gruntwork.io/docs/features/stacks/) **Template:** `assets/templates/stack/terragrunt.stack.hcl` **Catalog Template:** `assets/templates/catalog/terragrunt.hcl` **Patterns:** `references/common-patterns.md` → Stacks Patterns **Stack path rule:** Keep `no_dot_terragrunt_stack` mode consistent across dependent units. Do not mix direct-path and `.terragrunt-stack` generation in the same dependency chain. **Commands:** ```bash 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 directories ``` ### 6. Generate Feature Flags (2025) Runtime control without code changes. **Docs:** [Feature Flags Documentation](https://terragrunt.gruntwork.io/docs/features/feature-flags/) **Patterns:** `references/common-patterns.md` → Feature Flags Patterns > **CRITICAL:** Feature flag `default` values MUST be static (boolean, string, number). > They CANNOT reference `local.*` values. Use static defaults and override via CLI/env vars. **Correct:** ```hcl feature "enable_monitoring" { default = false # Static value - OK } ``` **Incorrect:** ```hcl feature "enable_monitoring" { default = local.env.locals.enable_monitoring # Dynamic reference - FAILS } ``` **Usage:** ```bash terragrunt apply --feature enable_monitoring=true # or export TG_FEATURE="enable_monitoring=true" ``` **Environment-specific defaults:** Use different static defaults per environment file, not dynamic references. ### 7. Generate Exclude Blocks (2025) Fine-grained execution control (replaces deprecated `skip`). **Docs:** [Exclude Block Reference](https://terragrunt.gruntwork.io/docs/reference/config-blocks-and-attributes/#exclude) **Patterns:** `references/common-patterns.md` → Exclude Block Patterns **Actions:** `"plan"`, `"apply"`, `"destroy"`, `"all"`, `"all_except_output"` **Production Recommendation:** For critical production resources, add exclude blocks to prevent accidental destruction: ```hcl # Protect production databases from accidental destroy exclude { if = true actions = ["destroy"] exclude_dependencies = false } # Also use prevent_destroy for critical resources prevent_destroy = true ``` ### 8. Generate Errors Blocks (2025) Advanced error handling (replaces deprecated `retryable_errors`). **Docs:** [Errors Block Reference](https://terragrunt.gruntwork.io/docs/reference/config-blocks-and-attributes/#errors) **Patterns:** `references/common-patterns.md` → Errors Block Patterns ### 9. Generate OpenTofu Engine Configuration (2025) Use OpenTofu as the IaC engine. **Docs:** [Engine Documentation](https://terragrunt.gruntwork.io/docs/features/engine/) **Patterns:** `references/common-patterns.md` → OpenTofu Engine Patterns ### 10. Handling Custom Providers/Modules When generating configs with custom providers: 1. **Identify** the provider name, source, and version 2. **Search** using WebSearch: `"[provider] terraform provider [version] documentation"` 3. **Or use Context7 MCP** if available for structured docs 4. **Generate** with proper `required_providers` block 5. **Document** authentication requirements in comments ## Generation Workflow > **CRITICAL:** Follow this workflow for EVERY generation task. Skipping steps leads to validation errors. ### Step 1: Understand Requirements - What type of configuration? (root, child, standalone, stack) - Single or multi-environment? - What dependencies exist between modules? - What providers/modules will be used? ### Step 2: Determine Architecture Pattern > **MANDATORY:** Select and document the pattern BEFORE writing any files. | 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 | Complete the **Architecture Pattern Selection Checklist (Canonical)** above and include it in output before file generation. ### Step 3: Read Required Templates > **MANDATORY:** Read the relevant template file(s) BEFORE generating each configuration type. | Configuration Type | Template to Read | Purpose | |-------------------|------------------|---------| | Root configuration | `assets/templates/root/terragrunt.hcl` | Shared state backend, providers, and common inputs | | Environment variables | `assets/templates/env/env.hcl` | Per-environment locals read by child modules (Pattern A) | | Child module | `assets/templates/child/terragrunt.hcl` | Environment module wired to root include | | Standalone module | `assets/templates/module/terragrunt.hcl` | Independent Terragrunt module without root include | | Stack file | `assets/templates/stack/terragrunt.stack.hcl` | Blueprint that generates multiple units | | Catalog unit | `assets/templates/catalog/terragrunt.hcl` | Reusable unit template consumed by stacks | **Also read:** - `references/common-patterns.md` - Primary source for generation patterns ### Step 4: Generate with Validation > **Validation Strategy:** Use a combination of inline checks during generation and batch validation at the end. **Generation order for multi-environment projects:** 1. **Generate root.hcl first** - **Inline checks (during generation):** - [ ] No `read_terragrunt_config(find_in_parent_folders("env.hcl"))` if environment-agnostic - [ ] `remote_state` block has `encrypt = true` - [ ] `errors` block used (not deprecated `retryable_errors`) 2. **Generate env.hcl files for each environment** - **Inline checks (during generation):** - [ ] `locals` block contains environment, aws_region, and module-specific vars - [ ] No references to files that don't exist at that directory level 3. **Generate child modules (VPC, etc.) - modules with NO dependencies first** - **Inline checks (during generation):** - [ ] `include` block uses `find_in_parent_folders("root.hcl")` - [ ] `read_terragrunt_config(find_in_parent_folders("env.hcl"))` present - [ ] `terraform.source` uses valid syntax (`tfr:///`, `git::`, or relative path) 4. **Generate dependent modules (RDS, EKS, etc.)** - **Inline checks (during generation):** - [ ] `dependency` blocks have `mock_outputs` - [ ] `mock_outputs_allowed_terraform_commands` includes `["validate", "plan", "destroy"]` - [ ] Production modules have `prevent_destroy = true` and/or `exclude` block 5. **Run batch validation after ALL files are generated** > **Note:** Full CLI validation (`terragrunt hcl fmt`, `terragrunt dag graph`) requires all files to exist, so these are batched at the end. ```bash # Batch validation commands (run after all files exist): terragrunt hcl fmt --check # Format validation terragrunt dag graph # Dependency graph validation ``` - Invoke `Skill(devops-skills:terragrunt-validator)` for comprehensive validation ### Step 5: Fix and Re-Validate If validation fails: 1. Analyze errors (path resolution, missing variables, syntax errors) 2. Fix issues in the specific file(s) 3. Re-validate the fixed file(s) 4. Repeat until ALL errors are resolved ### Step 6: Present Results Follow "Presentation Requirements" section below. ## Validation Workflow **CRITICAL:** Every generated configuration MUST be validated. ### Incremental Validation Checks **After generating root.hcl:** ```bash cd terragrunt hcl fmt --check ``` **After generating each child module:** ```bash cd terragrunt hcl fmt --check # If no dependencies on other modules: terragrunt hcl validate --inputs ``` ### Full Validation After all files are generated: 1. **Invoke validation skill:** ``` Invoke: Skill(devops-skills:terragrunt-validator) ``` 2. **If validation fails:** - Analyze errors (missing placeholders, invalid syntax, wrong paths) - Fix issues - **Re-validate** (repeat until ALL errors are resolved) 3. **If validation succeeds:** Present configurations with usage instructions **Skip validation only for:** Partial snippets, documentation examples, or explicit user request ### Validation Fallbacks (Environment Constraints) If the normal validation path is unavailable, use this fallback order and report what was skipped: 1. If `terragrunt` is unavailable: - Run static checks: ```bash rg -n "\[[A-Z0-9_]+\]" . rg -n "find_in_parent_folders\\(\"env\\.hcl\"\\)" . ``` - Report that runtime Terragrunt validation is pending. 2. If validator skill execution is unavailable: - Run direct Terragrunt checks instead: ```bash terragrunt hcl fmt --check terragrunt dag graph ``` 3. If `tree` is unavailable for presentation: - Use: ```bash find . -maxdepth 4 -type f | sort ``` ## Presentation Requirements > **MANDATORY:** After successful validation, you MUST present ALL of the following sections. Incomplete presentation is not acceptable. Copy and fill in the templates below. ### 1. Directory Structure Summary (MANDATORY) ```bash # Show the generated structure tree ``` ### 2. Files Generated (MANDATORY) **Output this table with all generated files:** ```markdown | 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 | | ... | ... | ``` ### 3. Usage Instructions (MANDATORY) > **You MUST include this section.** Copy the template below and fill in the actual values: ```markdown ## Usage Instructions ### Prerequisites Before running Terragrunt commands, ensure: 1. AWS credentials are configured (`aws configure` or environment variables) 2. S3 bucket `` exists for state storage 3. DynamoDB table `` exists for state locking ### Commands # Navigate to infrastructure directory cd # Initialize all modules terragrunt run --all init # Preview changes for a specific environment cd /vpc && terragrunt plan # Preview all changes terragrunt run --all plan # Apply changes (requires approval) terragrunt run --all apply # Destroy (use with extreme caution) terragrunt run --all destroy ``` ### 4. Placeholder Replacement and Secrets Check (MANDATORY) > **You MUST include this section.** Copy the template below and fill in the actual values: ```markdown ## Placeholder and Secrets Check ### Placeholder Replacement - [ ] All placeholders (`[AWS_REGION]`, `[BUCKET_NAME]`, `[DYNAMODB_TABLE]`, etc.) replaced with real values - [ ] No legacy placeholder aliases left (for example `[REGION]`) - [ ] `terraform.source` values point to real module sources and pinned versions ### Secrets Safety - [ ] No plaintext credentials or access keys in `terragrunt.hcl`, `root.hcl`, `env.hcl`, `account.hcl`, or `region.hcl` - [ ] Sensitive values sourced via environment variables, secret managers, or CI variables - [ ] Example values kept non-sensitive and clearly marked as placeholders ``` ### 5. Environment-Specific Notes (MANDATORY) > **You MUST include this section.** Copy the template below and fill in the actual values: ```markdown ## 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 `` must exist before first run - [ ] DynamoDB table `` 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 | ``` ### 6. Next Steps (Optional) Suggest what the user might want to do next (add more modules, customize configurations, etc.) ## Best Practices Reference `../terragrunt-validator/references/best_practices.md` for comprehensive guidelines. **Key principles:** - Use `include` blocks to inherit root configuration (DRY) - Always provide mock outputs for dependencies - Enable state encryption (`encrypt = true`) - Use `generate` blocks for provider configuration - Specify bounded version constraints (`~> 5.0`, not `>= 5.0`) for local/Git modules - Never hardcode credentials or secrets - Configure retry logic for transient errors > **Note 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 own `required_providers`. In this case, you may omit generating `required_providers` in `root.hcl` to avoid conflicts. The module's pinned version (`?version=X.X.X`) provides the version constraint. See "Common Issues → Provider Conflict with Registry Modules" for details. **Anti-patterns to avoid:** - Hardcoded account IDs, regions, or environment names - Missing mock outputs for dependencies - Duplicated configuration across modules - Unencrypted state storage - Missing or loose version constraints (except when using registry modules that define their own) - Root.hcl trying to read env.hcl that doesn't exist at root level ## Deprecated Attributes | Deprecated | Replacement | Reference | |------------|-------------|-----------| | `skip` | `exclude` block | [Docs](https://terragrunt.gruntwork.io/docs/reference/config-blocks-and-attributes/#exclude) | | `retryable_errors` | `errors.retry` block | [Docs](https://terragrunt.gruntwork.io/docs/reference/config-blocks-and-attributes/#errors) | | `run-all` | `run --all` | [Migration](https://terragrunt.gruntwork.io/docs/migrate/migrating-from-run-all/) | | `--terragrunt-*` flags | Unprefixed flags | [CLI Reference](https://terragrunt.gruntwork.io/docs/reference/cli-options/) | | `TERRAGRUNT_*` env vars | `TG_*` env vars | [CLI Reference](https://terragrunt.gruntwork.io/docs/reference/cli-options/) | ## Resources ### Templates - MUST Read Before Generating | Configuration Type | Template File | Purpose | When to Read | |-------------------|---------------|---------|--------------| | Root configuration | `assets/templates/root/terragrunt.hcl` | Shared backend, provider, and common inputs | Before generating any root.hcl | | Environment variables | `assets/templates/env/env.hcl` | Per-environment locals (environment, region, sizing, feature toggles) | Before generating any env.hcl (Pattern A) | | Child module | `assets/templates/child/terragrunt.hcl` | Module include, source, and optional dependency scaffolding | Before generating any child module | | Standalone module | `assets/templates/module/terragrunt.hcl` | Module config without root inheritance | Before generating standalone modules | | Stack file | `assets/templates/stack/terragrunt.stack.hcl` | Stack blueprint and unit generation | Before generating stacks | | Catalog unit | `assets/templates/catalog/terragrunt.hcl` | Reusable unit consumed by stack definitions | Before generating catalog units | ### References | Reference | Content | Purpose | When to Read | |-----------|---------|---------|--------------| | `references/common-patterns.md` | All generation patterns with examples | Pick a compatible pattern before writing files | Always, before generating | | `../terragrunt-validator/references/best_practices.md` | Comprehensive best practices | Final quality and safety checks | Always, before generating | ### Official Documentation - [Terragrunt Docs](https://terragrunt.gruntwork.io/docs/) - [Configuration Reference](https://terragrunt.gruntwork.io/docs/reference/config-blocks-and-attributes/) - [CLI Reference](https://terragrunt.gruntwork.io/docs/reference/cli-options/) - [Stacks](https://terragrunt.gruntwork.io/docs/features/stacks/) - [Feature Flags](https://terragrunt.gruntwork.io/docs/features/feature-flags/) - [Engine](https://terragrunt.gruntwork.io/docs/features/engine/) - [Migration Guides](https://terragrunt.gruntwork.io/docs/migrate/) ## Common Issues ### Root.hcl Cannot Find env.hcl **Symptom:** ``` Error: Attempt to get attribute from null value on ./root.hcl line X: This value is null, so it does not have any attributes. ``` **Cause:** Root.hcl is trying to read `env.hcl` via `find_in_parent_folders("env.hcl")`, but env.hcl doesn't exist at the root level. **Solution:** Make root.hcl environment-agnostic: ```hcl # DON'T do this in root.hcl for multi-environment setups: locals { env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) # FAILS } # DO use static values or get_env(): generate "provider" { path = "provider.tf" if_exists = "overwrite_terragrunt" contents = <