Back to Terragrunt

Stack Dependencies

docs/src/data/experiments/stack-dependencies.mdx

1.1.05.8 KB
Original Source

import Since from '@components/Since.astro'; import Before from '@components/Before.astro'; import { Aside } from '@astrojs/starlight/components';

Support for the autoinclude block in terragrunt.stack.hcl files, enabling dependency relationships and configuration overrides during stack generation.

stack-dependencies - What it does

<Before version="1.1.0"> When enabled, this experiment adds support for the `autoinclude` block nested inside `unit` and `stack` blocks in `terragrunt.stack.hcl` files. </Before> <Since version="1.1.0"> This experiment flag is no longer needed, as the `autoinclude` block is now available by default. The block nests inside `unit` and `stack` blocks in `terragrunt.stack.hcl` files. </Since>

The autoinclude block allows users to define dependency blocks and arbitrary configuration that gets generated into an autoinclude file during stack generation. This file is automatically merged into the unit/stack configuration when parsed.

The generated filename depends on the component kind:

  • Unit autoincludes are written as terragrunt.autoinclude.hcl next to the unit's terragrunt.hcl.
  • Stack autoincludes are written as terragrunt.autoinclude.stack.hcl next to the nested stack's terragrunt.stack.hcl. The .stack.hcl suffix mirrors terragrunt.stack.hcl so tooling (LSP, read_terragrunt_config(), indexers) can identify the file's purpose from its name alone.

The feature also includes:

  • unit.<name>.path and stack.<name>.path variables for referencing sibling component paths, both inside autoinclude blocks and in a unit or stack block's values (so a parent stack can pass a component path down to a child stack)
  • dependency blocks targeting stack directories: aggregated outputs from all units in the stack (dependency.stack_name.outputs.unit_name.output_key)
  • Automatic shallow merge of terragrunt.autoinclude.hcl into unit configurations, using the same default merge strategy as a regular include (on conflicting top-level keys, the autoinclude wins and replaces the unit's value)
  • Stack dependency expansion in the run queue: depending on a stack waits until all its units complete

Unit-to-unit dependencies within a stack

hcl
# terragrunt.stack.hcl
unit "vpc" {
  source = "../catalog/units/vpc"
  path   = "vpc"
}

unit "app" {
  source = "../catalog/units/app"
  path   = "app"

  autoinclude {
    dependency "vpc" {
      config_path = unit.vpc.path
    }

    inputs = {
      vpc_id = dependency.vpc.outputs.vpc_id
    }
  }
}

Dependencies on entire stacks

hcl
# terragrunt.stack.hcl
stack "infra" {
  source = "../catalog/stacks/infra"
  path   = "infra"
}

unit "app" {
  source = "../catalog/units/app"
  path   = "app"

  autoinclude {
    dependency "infra" {
      config_path = stack.infra.path
    }

    inputs = {
      vpc_id = dependency.infra.outputs.vpc.vpc_id
    }
  }
}
<Before version="1.1.0">
bash
terragrunt run --all --experiment stack-dependencies -- plan
</Before>

stack-dependencies - How to provide feedback

<Before version="1.1.0"> Provide your feedback on the [Stack Dependencies RFC](https://github.com/gruntwork-io/terragrunt/issues/5663) GitHub Issue. </Before> <Since version="1.1.0"> Now that the `stack-dependencies` experiment is complete, please provide feedback in the form of standard [GitHub issues](https://github.com/gruntwork-io/terragrunt/issues). </Since>

stack-dependencies - Implementation roadmap

<Since version="1.0.5">
  • Phased parser for terragrunt.stack.hcl: parse the file body, evaluate locals and values, apply include merges, then decode unit/stack blocks and resolve autoinclude. This lets unit/stack blocks use local.*, values.*, and Terragrunt functions.
  • terragrunt run --all discovery can scan generated nested stack files without evaluating the unit source.
  • Unify strict and permissive parser into a single code path
  • Add integration tests and test fixtures for end-to-end validation
  • Add E2E validation with stack run apply and stack run destroy
</Since> <Since version="1.0.6">
  • Catalog source preservation across stack copy: nested stack files copied into .terragrunt-stack/<name>/ get a .terragrunt-stack-origin marker file, so bare relative ../../units/... paths resolve against the original catalog, not the copy. Only applies to local stack sources; remote and CAS-fetched stacks are unchanged.
  • PartialEval depth guard (maxPartialEvalDepth = 10000) and IsWhollyKnown / IsNull checks on the fast path and traversal/template/conditional/parens branches, preventing crashes on unknown values or pathological nesting.
  • Typed errors with Unwrap() across the package (FileParseError, FileDecodeError, IncludeValidationError, LocalEvalError, MalformedDependencyError, AutoIncludeParserStageError) preserving hcl.Diagnostics for source positions.
  • Deterministic cycle reports in LocalsCycleError.Names (DFS dep iteration sorted).
  • resolveStackFilePath returns (string, bool): callers branch on isStackCandidate instead of a sentinel empty string. Backed by a two-arg fuzz that exercises raw/target independently.
  • Removed Unicode from internal/hclparse source files (ASCII-only); intentional Unicode test fixtures remain.
</Since> <Since version="1.0.7">
  • The .terragrunt-stack-origin marker file is no longer written when nested stack files are copied into .terragrunt-stack/<name>/. Use update_source_with_cas = true <Before version="1.1.0">(with the cas experiment enabled) </Before>on unit and stack blocks to keep relative source paths working in catalog stack files; relative attributes are rewritten to cas:: references at generation time so the generated tree is self-contained.
  • Community feedback on autoinclude syntax and merge behavior
  • Validate performance at scale
</Since>