Git Expressions
Match units and stacks based on changes between Git references. This is useful for targeting infrastructure that has been modified, added, or removed between commits, branches, or tags.
Git-based expressions are written between [ and ] characters, and use the ... operator to indicate the range of changes to compare.
# Compare between two referencesterragrunt find --filter '[main...HEAD]'
# Shorthand: compare reference to HEADterragrunt find --filter '[main]'
# Compare between specific commitsterragrunt find --filter '[abc123...def456]'
# Compare between tagsterragrunt find --filter '[v1.0.0...v2.0.0]'
# Compare using relative referencesterragrunt find --filter '[HEAD~1...HEAD]'
# Compare between branchesterragrunt find --filter '[feature-branch...main]'Directory.
Directorymodified-unit <— Matched by [main…HEAD] (terragrunt.hcl was modified)
- terragrunt.hcl (modified)
Directorynew-unit <— Matched by [main…HEAD] (terragrunt.hcl was added)
- terragrunt.hcl (added)
Directoryremoved-unit <— Matched by [main…HEAD] (terragrunt.hcl was removed)
- (directory removed)
Directoryunchanged-unit
- terragrunt.hcl (unchanged)
How it works
Section titled “How it works”When evaluating a Git-based filter, Terragrunt will first generate a worktree for every reference that needs to be evaluated, and assess the diffs between Git references.
e.g. For a filter like [main...HEAD], Terragrunt will generate a worktree for main and one for HEAD in temporary directories, and use git diff to assess the diffs between the two references.
Then, for any unit that is discovered within those worktrees, Terragrunt will enqueue that unit for a run in the run queue in the worktree where it was discovered.
In the example above, the modified-unit will be discovered in a “to” temporary directory (e.g. /tmp/.../terragrunt-worktree-HEAD.../modified-unit), whereas the removed-unit would be discovered in the “from” temporary directory (e.g. /tmp/.../terragrunt-worktree-main.../removed-unit).
This is important to recognize, as it’s how destroys will be possible despite the fact that the unit is no longer present in the current working directory. As a consequence, however, you may find that paths don’t behave how you expect, as you will be performing runs in the temporary directories created for the relevant worktrees.
Interaction with the run command
Section titled “Interaction with the run command”When using Git-based expressions and the run command, you are required to use one of the plan or apply commands, and not the -destroy flag.
This is because whether or not a unit will be destroyed is determined by logic relevant to inspecting changes in Git.
When units are added or modified between two Git references, they will be planned or applied. When the units are removed between two Git references, they will be planned for destruction (with plan -destroy) or destroyed (with apply -destroy).
In the scenario above, running the following:
terragrunt run --filter '[main...HEAD]' planWill result in the following:
modified-unitwill be planned (tofu plan)new-unitwill be planned (tofu plan)removed-unitwill be planned for destruction (tofu plan -destroy)unchanged-unitwill be ignored
The --filter-affected flag
Section titled “The --filter-affected flag”For the common use case of comparing the default branch (typically main) with HEAD, you can use the --filter-affected flag as a convenient shorthand:
# Find components affected by changes between main and HEADterragrunt find --filter-affected
# Equivalent to:terragrunt find --filter '[main...HEAD]'The --filter-affected flag automatically detects your repository’s default branch and compares it with HEAD.