Skip to content

Filters

The --filter flag provides a sophisticated querying syntax for targeting specific units and stacks in Terragrunt commands. This unified approach offers powerful filtering capabilities using a flexible query language.

The filter syntax allows you to target units and stacks using several different approaches. Usage of the filter flag in a command can look like this:

Terminal window
$ terragrunt find --filter './prod/** | name=web'
prod/services/web

Where the result of find above might have been:

Terminal window
$ terragrunt find
prod/services/web
prod/services/api
prod/data/db
dev/services/web
dev/services/api
dev/data/db

For the following file tree:

  • Directoryprod
    • Directoryservices
      • Directoryweb <— Matched by the filter
        • terragrunt.hcl
      • Directoryapi
        • terragrunt.hcl
    • Directorydata
      • Directorydb
        • terragrunt.hcl
  • Directorydev
    • Directoryservices
      • Directoryweb
        • terragrunt.hcl
      • Directoryapi
        • terragrunt.hcl
    • Directorydata
      • Directorydb
        • terragrunt.hcl

There are several different types of filters, and particular ways in which they can be combined to achieve different results. You can learn more about that below.

Match units and stacks by their name. This is the simplest form of filtering.

Terminal window
# Exact match
terragrunt find --filter app1
# Glob pattern
terragrunt find --filter 'app*'
  • Directoryapps
    • Directoryapp1 <— Matched by the first and second filter
      • terragrunt.hcl
    • Directoryapp2 <— Matched only by the second filter
      • terragrunt.hcl
    • Directoryother
      • terragrunt.hcl

Match units and stacks by their file system path.

Terminal window
# Relative paths
terragrunt find --filter './envs/prod/apps/app1'
terragrunt find --filter './envs/stage/**'
# Absolute paths
terragrunt find --filter '/absolute/path/to/envs/dev/apps/*'
# Wrapped paths (useful for explicitly indicating that an expression is for a path if ambiguous)
terragrunt find --filter '{./envs/prod/apps/app2}'
  • Directoryenvs
    • Directoryprod
      • Directoryapps
        • Directoryapp1 <— Matched by the first filter
          • terragrunt.hcl
        • Directoryapp2 <— Matched by the fourth filter
          • terragrunt.hcl
    • Directorystage
      • Directoryapps
        • Directoryapp1 <— Matched by the second filter
          • terragrunt.hcl
        • Directoryapp2 <— Also matched by the second filter
          • terragrunt.hcl
    • Directorydev
      • Directoryapps
        • Directoryapp1 <— Matched by the third filter
          • terragrunt.hcl
        • Directoryapp2 <— Also matched by the third filter
          • terragrunt.hcl

Match units and stacks by their configuration attributes.

Terminal window
# Filter by component type
terragrunt find --filter 'type=unit'
terragrunt find --filter 'type=stack'
# Filter by external dependency status
terragrunt find --dependencies --external --filter '*... | external=false'
terragrunt find --dependencies --external --filter '*... | external=true'
# Explicitly filter by name (useful for explicitly indicating that an expression is for a name if ambiguous)
terragrunt find --filter 'name=stack*'
  • Directory.
    • Directoryunit1 <— Selected by the first filter
      • terragrunt.hcl
    • Directorystack1 <— Selected by the second and fifth filter
      • terragrunt.stack.hcl
  • Directory..
    • Directorydependencies <— Note that this directory is sibling to the current working directory
      • Directorydependency-of-app1 <— Matched by the fourth filter, but not the third filter
        • terragrunt.hcl

Match units and stacks by their Terraform source URL or path specified in the terraform block of terragrunt.hcl files.

Terminal window
# Filter by exact source match
terragrunt find --filter 'source=github.com/acme/foo'
terragrunt find --filter 'source=gitlab.com/example/baz'
terragrunt find --filter 'source=./module'
# Filter by source using glob patterns
terragrunt find --filter 'source=*github.com**acme/*'
terragrunt find --filter 'source=git::git@github.com:acme/**'
terragrunt find --filter 'source=**github.com**'
terragrunt find --filter 'source=gitlab.com/**'
  • Directory.
    • Directorygithub-acme-foo <— Matched by source=github.com/acme/foo and source=github.com**acme/
      • terragrunt.hcl (source: github.com/acme/foo)
    • Directorygithub-acme-bar <— Matched by source=github.com**acme/ and source=git::git@github.com:acme/**
      • terragrunt.hcl (source: git::git@github.com:acme/bar)
    • Directorygitlab-example-baz <— Matched by source=gitlab.com/example/baz and source=gitlab.com/**
      • terragrunt.hcl (source: gitlab.com/example/baz)
    • Directorylocal-module <— Matched by source=./module
      • terragrunt.hcl (source: ./module)
      • Directorymodule
        • main.tf
    • Directoryother-unit
      • terragrunt.hcl (source: s3://bucket/module)

Exclude units and stacks using the ! prefix.

Terminal window
# Exclude by name
terragrunt find --filter '!app1'
# Exclude by path
terragrunt find --filter '!./prod/**'
# Exclude by type
terragrunt find --filter '!type=stack'
  • Directoryenvs
    • Directoryprod
      • Directoryapps
        • Directoryapp1 <— Excluded by both the first and second filter
          • terragrunt.hcl
        • Directoryapp2 <— Matched by all filters except the second filter
          • terragrunt.hcl
      • Directorystacks
        • Directorystack1 <— Excluded by both the second and third filter
          • terragrunt.stack.hcl
    • Directorystage
      • Directoryapps
        • Directoryapp1 <— Matched by all filters except the first filter
          • terragrunt.hcl
        • Directoryapp2 <— Matched by all filters
          • terragrunt.hcl
      • Directorystacks
        • Directorystack1 <— Matched by all filters except the third filter
          • terragrunt.stack.hcl

Use the | operator to refine results. The right side of the operator is applied to the results from the left side.

Terminal window
# Find all components in ./prod/** that are also units
terragrunt find --filter './prod/** | type=unit'
# Find all components in ./prod/** that are not units
terragrunt find --filter './prod/** | !type=unit'
# You can chain as many filters as you want to further refine the results
terragrunt find --filter './dev/** | type=unit | !name=unit1'
  • Directoryprod
    • Directoryunits
      • Directoryunit1 <— Matched by first filter
        • terragrunt.hcl
      • Directoryunit2 <— Matched by first filter
        • terragrunt.hcl
    • Directorystacks
      • Directorystack1 <— Matched by second filter
        • terragrunt.stack.hcl
      • Directorystack2 <— Matched by second filter
        • terragrunt.stack.hcl
  • Directorydev
    • Directoryunits
      • Directoryunit1
        • terragrunt.hcl
      • Directoryunit2 <— Matched by third filter
        • terragrunt.hcl
    • Directorystacks
      • Directorystack1
        • terragrunt.stack.hcl
      • Directorystack2
        • terragrunt.stack.hcl

Filter units and stacks based on their dependency relationships using graph traversal operators. This allows you to find components that depend on a target, or components that a target depends on.

Graph-based filtering uses the ellipsis (...) operator to indicate graph traversal direction and the caret (^) operator to exclude the target from results.

Use foo... to include the target and all of its dependencies:

Terminal window
# Find 'service' and everything it depends on
terragrunt find --filter 'service...'
  • Directory.
    • Directoryservice <— Matched (target)
      • terragrunt.hcl (depends on: db, cache, vpc)
    • Directorydb <— Matched (dependency of service)
      • terragrunt.hcl (depends on: vpc)
    • Directorycache <— Matched (dependency of service)
      • terragrunt.hcl (depends on: vpc)
    • Directoryvpc <— Matched (dependency of service, db, cache)
      • terragrunt.hcl

Use ...foo to include the target and all components that depend on it:

Terminal window
# Find 'vpc' and everything that depends on it
terragrunt find --filter '...vpc'
  • Directory.
    • Directoryvpc <— Matched (target)
      • terragrunt.hcl
    • Directorydb <— Matched (depends on vpc)
      • terragrunt.hcl (depends on: vpc)
    • Directorycache <— Matched (depends on vpc)
      • terragrunt.hcl (depends on: vpc)
    • Directoryservice <— Matched (depends on vpc via db and cache)
      • terragrunt.hcl (depends on: db, cache)

Use ...foo... to include the target, all its dependencies, and all its dependents:

Terminal window
# Find 'db' and its complete dependency graph
terragrunt find --filter '...db...'
  • Directory.
    • Directoryvpc <— Matched (dependency of db)
      • terragrunt.hcl
    • Directorydb <— Matched (target)
      • terragrunt.hcl (depends on: vpc)
    • Directoryservice <— Matched (depends on db)
      • terragrunt.hcl (depends on: db, cache)

Use ^ to exclude the target component from results. This is useful when you want only the dependencies or dependents, but not the component itself:

Terminal window
# Find all dependents of 'vpc' but exclude 'vpc' itself
terragrunt find --filter '...^vpc'
  • Directory.
    • Directoryvpc <— Not matched by ’…^vpc’ (would be matched if …vpc was used)
      • terragrunt.hcl
    • Directorydb <— Matched by ’…^vpc’ (dependent on vpc)
      • terragrunt.hcl
    • Directorycache <— Matched by ’…^vpc’ (dependent on vpc)
      • terragrunt.hcl
    • Directoryservice <— Excluded by ’…^vpc’ (dependent on vpc)
      • terragrunt.hcl

Graph expressions work with path filters, attribute filters, and other filter types:

Terminal window
# Graph traversal with path filter
terragrunt find --filter '{./service}...'
# Graph traversal with attribute filter
terragrunt find --filter '...type=unit'
# Graph traversal with name filter using glob
terragrunt find --filter '...app*...'

Use the | operator to refine graph traversal results:

Terminal window
# Find all dependencies of 'service', but filter out all the database's dependencies.
terragrunt find --filter 'service... | !^db...'
# Find all dependents of 'vpc' in the prod environment
terragrunt find --filter './prod/** | ...vpc'

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

Terminal window
# Find components named 'unit1' OR 'stack1'
terragrunt find --filter unit1 --filter stack1
# Find components in ./envs/prod/* OR ./envs/stage/*
terragrunt find --filter './envs/prod/*' --filter './envs/stage/*'
# Find components named 'stack2' _except_ those in ./envs/prod/* and ./envs/stage/*
terragrunt find --filter stack2 --filter '!./envs/prod/**' --filter '!./envs/stage/**'
  • Directoryenvs
    • Directoryprod
      • Directoryunit1 <— Matched by the first filter and the second filter
        • terragrunt.hcl
      • Directoryunit2 <— Matched by the second filter
        • terragrunt.hcl
      • Directorystack1 <— Matched by the first filter and the second filter
        • terragrunt.stack.hcl
      • Directorystack2 <— Matched by the second filter
        • terragrunt.stack.hcl
    • Directorystage
      • Directoryunit1 <— Matched by the first filter and the second filter
        • terragrunt.hcl
      • Directoryunit2 <— Matched by the second filter
        • terragrunt.hcl
      • Directorystack1 <— Matched by the first filter and the second filter
        • terragrunt.stack.hcl
      • Directorystack2 <— Matched by the second filter
        • terragrunt.stack.hcl
    • Directorydev
      • Directoryunit1 <— Matched by the first filter
        • terragrunt.hcl
      • Directoryunit2
        • terragrunt.hcl
      • Directorystack1 <— Matched by the first filter
        • terragrunt.stack.hcl
      • Directorystack2 <— Matched by the third filter
        • terragrunt.stack.hcl

The following commands all support the --filter flag, and use it to filter results in the same way:

This flag is intended to be a flexible way to target specific infrastructure that allows you to dry-run infrastructure targeting using discovery commands (like find and list) before running a command that actually affects infrastructure (like run).

The --filter flag provides a unified alternative to multiple queue control flags:

Legacy FlagFilter Equivalent
--queue-include-dir--filter './path/*'
--queue-exclude-dir--filter '!./path/*'
--queue-exclude-external--filter '!external=true'
--queue-include-external--filter 'external=true'

Certain commands have special interactions with the --filter flag that are worth noting.

Unlike when used for most commands, the --filter flag is used to filter on individual HCL files when used with the hcl fmt.

All other commands use --filter to filter on units and/or stacks (which are directories). As a result, only path-based filter expressions are supported. Attribute-based filters like type=unit or name=my-app are not applicable to file-level operations.

Example:

Terminal window
# Supported: Path-based filtering
terragrunt hcl fmt --filter './prod/**/*.hcl'
# Not supported: Attribute-based filtering
terragrunt hcl fmt --filter 'type=unit' # This will not work

When using --filter with stack generate, filter expressions will only be recognized if they explicitly target stacks. This is to ensure that filters are not over-applied, preventing any stack generation from occurring.

Terminal window
# Supported: Only generate the stacks that match the filter, as we are explicitly indicating that we are targeting stacks.
terragrunt stack generate --filter 'name=prod | type=stack'
# Not supported: This filter will be ignored, as we are not explicitly indicating that we are targeting stacks.
terragrunt stack generate --filter 'name=prod' # This will not work

The reason for this is that stack generation can also be done automatically as part of other commands, like run, and thus we need to make it clear that we’re trying to control stack generation rather than run behavior.

Terminal window
# This will run any unit named 'vpc'
terragrunt run --all --filter 'vpc' -- plan
# This will run any unit named 'vpc', and prevent stack generation in any stack not named 'dev' (including any stacks named 'vpc')
terragrunt stack run --filter 'vpc' --filter 'name=dev | type=stack' -- apply