Skip to content
🎉 Terragrunt v1.0 is here! Read the announcement to learn more.

graph

Usage

Print a visual representation of the Terragrunt dependency graph in DOT language format.

This command analyzes your Terragrunt configuration and outputs a directed acyclic graph (DAG) showing the relationships and dependencies between your Terraform modules.

**Note:** This command is an alias for `list --format=dot`. Both commands produce identical output.

Examples

Graph all dependencies in the graph as a DotViz graph.

Terminal window
$ terragrunt dag graph
digraph {
"alb" ;
"ecs" ;
"ecs" -> "alb";
}

Graph all dependencies in visual diagram.

Terminal window
$ terragrunt dag graph | dot -Tpng > graph.png

Flags

--filter

Filter configurations using a flexible query language

The --filter flag provides a sophisticated querying syntax for targeting specific units and stacks in Terragrunt commands.

Usage

Terminal window
terragrunt find --filter 'app*'
terragrunt list --filter './prod/** | type=unit'
terragrunt run --all --filter './prod/**' -- plan
terragrunt hcl fmt --filter './prod/**'
terragrunt hcl validate --filter 'type=unit'

Name-Based Filtering

Match configurations by their name using exact matches or glob patterns:

Terminal window
# Exact match
terragrunt find --filter app1
# Glob pattern
terragrunt find --filter 'app*'

Path-Based Filtering

Match configurations by their file system path:

Terminal window
# Relative paths with globs
terragrunt find --filter './envs/prod/**'
# Absolute paths
terragrunt find --filter '/absolute/path/to/envs/dev/apps/*'

Attribute-Based Filtering

Match configurations by their configuration attributes:

Terminal window
# Filter by type
terragrunt find --filter 'type=unit'
terragrunt find --filter 'type=stack'
# Filter by external dependency status
terragrunt find --filter 'external=false'
# Filter by files read
terragrunt find --filter 'reading=shared.hcl'
terragrunt find --filter 'reading=common/*.hcl' # Globs supported!
terragrunt find --filter 'reading=config/**' # Double-wildcard globs are required filtering on files nested in subdirectories.
terragrunt find --filter 'reading=config/vars.tfvars'

Negation

Exclude configurations using the ! prefix:

Terminal window
# Exclude by name
terragrunt find --filter '!app1'
# Exclude by path
terragrunt find --filter '!./prod/**'

Intersection (Refinement)

Use the | operator to refine results:

Terminal window
# Find all units in prod directory
terragrunt find --filter './prod/** | type=unit'
# Chain multiple filters
terragrunt find --filter './dev/** | type=unit | !name=unit1'

Git-Based Filtering

Filter configurations based on changes between Git references. For the common use case of comparing the default branch with HEAD, you can use the --filter-affected flag as a convenient shorthand:

Terminal window
# Find components affected by changes between main and HEAD
terragrunt find --filter-affected

For more control, use Git-based filter expressions directly:

Terminal window
# Compare between two references
terragrunt find --filter '[main...HEAD]'
# Shorthand: compare reference to HEAD
terragrunt find --filter '[main]'
# Compare between specific commits
terragrunt find --filter '[abc123...def456]'

For more details and examples, see the Filters feature documentation.

Graph-Based Filtering

Filter configurations based on dependency relationships using graph traversal. Use ellipsis (...) to traverse the dependency graph and caret (^) to exclude the target from results.

Syntax variants:

  • foo... - Include target and all dependencies (things it depends on)
  • ...foo - Include target and all dependents (things that depend on it)
  • ...foo... - Include target, dependencies, and dependents
  • ^foo... - Include only dependencies (exclude target)
  • ...^foo - Include only dependents (exclude target)
  • ...^foo... - Include dependencies and dependents (exclude target)
Terminal window
# Find 'service' and everything it depends on
terragrunt find --filter 'service...'
# Find 'vpc' and everything that depends on it
terragrunt find --filter '...vpc'
# Find complete dependency graph for 'db'
terragrunt find --filter '...db...'
# Find dependencies of 'service' but exclude 'service' itself
terragrunt find --filter '^service...'
# Combine graph traversal with path filters (note the use of braces to escape the path)
terragrunt find --filter '{./apps/service}...'
# Combine graph traversal with attribute filters
terragrunt find --filter '...type=unit'
# Refine graph results with intersection
terragrunt find --filter 'service... | external=false'

Union (Multiple Filters)

Specify multiple --filter flags to combine results using OR logic:

Terminal window
# Find components named 'unit1' OR 'stack1'
terragrunt find --filter unit1 --filter stack1

The filters file

Instead of specifying filters on the command line, you can store filter queries in a file. By default, Terragrunt automatically reads filter queries from the .terragrunt-filters file in your current working directory if it exists.

Terminal window
# Automatically reads .terragrunt-filters (no flag needed)
terragrunt find
# Use a custom filters file
terragrunt find --filters-file custom-filters.txt
# Disable automatic file reading
terragrunt find --no-filters-file

The filters file should contain one filter query per line. Empty lines and lines starting with # are ignored:

# Production environment filters
type=unit
./prod/**
# Exclude test units
!name=test-*

Supported Commands

Learn More

For comprehensive examples and advanced usage patterns, see the Filters feature documentation.

Type: list(string)

--filter-affected

Filter components affected by changes between the default branch and HEAD

The --filter-affected flag is a convenient shorthand for filtering components that have been modified, added, or removed between the default branch (typically main) and HEAD. It is equivalent to using --filter '[main...HEAD]' (or --filter '[<defaultBranch>...HEAD]' if your repository uses a different default branch).

Usage

Terminal window
# Find all components affected by changes between main and HEAD
terragrunt find --filter-affected
# List affected components
terragrunt list --filter-affected
# Run plan on affected components
terragrunt run --all --filter-affected -- plan
# Run apply on affected components
terragrunt run --all --filter-affected -- apply

Default Branch Detection

The flag automatically detects your repository’s default branch. It checks:

  1. Your Git configuration for init.defaultBranch
  2. Falls back to main if not configured

To use a different branch for comparison, use the --filter flag directly with a Git-based filter expression:

Terminal window
# Compare against a specific branch
terragrunt find --filter '[develop...HEAD]'
# Compare between two specific references
terragrunt find --filter '[v1.0.0...v2.0.0]'

Uncommitted Changes Warning

If you have uncommitted changes in your working directory, Terragrunt will display a warning:

Warning: You have uncommitted changes. The --filter-affected flag may not include all your local modifications.

This is because --filter-affected compares Git references, not your working directory. To include uncommitted changes, you would need to commit them first or use a different filtering approach.

Equivalent Filter Expression

The --filter-affected flag is equivalent to:

Terminal window
terragrunt find --filter '[main...HEAD]'

Or, if your default branch is different:

Terminal window
terragrunt find --filter '[<defaultBranch>...HEAD]'

Learn More

For more information about Git-based filtering and advanced usage patterns, see the Filters feature documentation.

Type: bool

--discovery-boundary

Directory that encloses graph discovery for filters, instead of the git repository root

Filter expressions that traverse the dependency graph reach beyond the working directory. Dependents (...{unit}) can live anywhere, so Terragrunt searches from the working directory up to the git repository root; dependencies ({unit}...) are declared by path and can point anywhere.

The --discovery-boundary flag is a single enclosure for that traversal: it replaces the git repository root as the outer limit, and a configuration that traversal reaches outside it is not returned, so find does not list it and run --all does not run it. Configurations inside the boundary are discovered as usual.

The boundary decides which configurations a command acts on, not which ones Terragrunt may read. A unit inside the boundary can declare a dependency outside it, and that dependency is still read and parsed: Terragrunt needs its configuration to fetch the outputs the dependent unit consumes, and it needs the dependency edge to order the units that do run. What the boundary withholds is the unit itself, which is left for a separate run to apply, the same way a dependency outside the working directory is treated today.

This matters in monorepos where environments are isolated from each other. When sibling environments cannot be parsed independently, the default search fails or wastes work reaching into them:

environments/
staging/
production/
test/
root.hcl

Bounding the traversal to the current environment keeps discovery inside it:

Terminal window
cd environments/staging
terragrunt find --experiment bounded-discovery --filter '...{vpc}' --discovery-boundary .

Usage

Terminal window
# Enclose discovery within the working directory
terragrunt find --filter '...{vpc}' --discovery-boundary .
# Enclose discovery within a parent directory
terragrunt run --all plan --filter '...{vpc}' --discovery-boundary ..
# Equivalent, via environment variable
TG_DISCOVERY_BOUNDARY=. terragrunt find --filter '...{vpc}'
# From the repository root, keep app's dependencies within prod
terragrunt find --filter '{./prod/app}...' --discovery-boundary ./prod

The boundary must be an existing directory. Relative paths are resolved against the working directory.

The boundary applies to what traversal reaches, so a command that names no filter keeps every configuration under the working directory even when the boundary sits below it. Narrow the working directory itself, with --working-dir, to change where discovery starts.

Where the boundary may sit depends on the directions the filters traverse. Dependent traversal searches upward from the working directory, so a boundary that excludes the working directory could never take effect; filters that traverse dependents require the boundary to be the working directory or one of its parents. Dependency traversal follows declared paths outward from the units a filter matched and never consults the working directory, so filters that traverse only dependencies accept any directory, including one below the working directory. That is the same rule the inline (dir) operand follows.

Type: string

Environment Variables:

  • TG_DISCOVERY_BOUNDARY