---
name: stack-dependencies
since: "1.0.1"
completedSince: "1.1"
---

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
When enabled, this experiment adds support for the `autoinclude` block nested inside `unit` and `stack` blocks in `terragrunt.stack.hcl` files. 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.

This experiment enables:

- **`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
    }
  }
}
```

```bash
terragrunt run --all --experiment stack-dependencies -- plan
```

### `stack-dependencies` - How to provide feedback
Provide your feedback on the [Stack Dependencies RFC](https://github.com/gruntwork-io/terragrunt/issues/5663) GitHub Issue.

### `stack-dependencies` - Implementation roadmap

<Since version="1.0.5">

- [x] 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.
- [x] `terragrunt run --all` discovery can scan generated nested stack files without evaluating the unit `source`.
- [x] Unify strict and permissive parser into a single code path
- [x] Add integration tests and test fixtures for end-to-end validation
- [x] Add E2E validation with `stack run apply` and `stack run destroy`

</Since>

<Since version="1.0.6">

- [x] 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.
- [x] `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.
- [x] Typed errors with `Unwrap()` across the package (`FileParseError`, `FileDecodeError`, `IncludeValidationError`, `LocalEvalError`, `MalformedDependencyError`, `AutoIncludeParserStageError`) preserving `hcl.Diagnostics` for source positions.
- [x] Deterministic cycle reports in `LocalsCycleError.Names` (DFS dep iteration sorted).
- [x] `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.
- [x] Removed Unicode from `internal/hclparse` source files (ASCII-only); intentional Unicode test fixtures remain.

</Since>

<Since version="1.0.7">

- [x] 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` (with the `cas` experiment enabled) 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>
