Change Detection β
When working with multiple stacks, a common challenge is to execute commands in stacks that contain changes only to preserve a small blast radius and fast execution run times.
That's why Terramate CLI comes with a change detection feature that can detect stacks containing changes in a commit, branch, or Pull Request.
Introduction β
The change detection is enabled by providing the --changed option to commands such as run or list and can be configured to use a specific branch as a reference.
E.g., to list all stacks that contain changes:
terramate list --changedSince v0.11.0 untracked and uncommitted files are also considered changes.
INFO
Untracked file is a file which isn't tracked by the Git index
Uncommitted file is a file tracked by the Git index, but its latest changes are not committed to Git yet
The change detection behavior can be customized in the configuration or by command-line flags.
Example:
terramate {
config {
change_detection {
git {
# valid options: true, "on", false, "off"
untracked = "off"
uncommitted = "off"
}
}
}
}Use --enable-change-detection=<options> and --disable-change-detection=<options> to override the default settings and configuration. These flags are supported in the commands listed below (refer to their documentation for usage):
Dependency Filters β
When using change detection, you can expand or narrow the selection of stacks by including or excluding their dependencies and dependents. This is particularly useful when working with stacks that have data dependencies (e.g., via outputs sharing or Terragrunt dependency blocks).
Dependency filters work with both:
- Terramate dependencies: Stacks that provide outputs consumed by other stacks via
input.from_stack_id - Terragrunt dependencies: Stacks referenced in Terragrunt
dependencyblocks
Understanding Dependencies and Dependents β
- Dependencies: Stacks that the selected stacks depend on (what they need to run)
- Dependents: Stacks that depend on the selected stacks (what needs them to run)
- Direct: Only immediate dependencies/dependents
- All (Transitive): Direct dependencies/dependents plus all their dependencies/dependents recursively
Important: What Counts as a Dependency?
Dependency filters only consider data dependenciesβstacks that actually share data with each other. They do not consider ordering-only relationships.
What IS included:
- Terramate output sharing: Stacks that provide outputs consumed by other stacks via
input.from_stack_id - Terragrunt data dependencies: Stacks referenced in Terragrunt
dependencyblocks that share data
What is NOT included:
- Forced execution relationships: Stacks defined in
stack.wantsandstack.wanted_by(used to force stacks to run together) are not considered dependencies for filtering - Execution order relationships: Stacks defined in
stack.beforeandstack.afterattributes are used only for controlling execution order, not for dependency filtering - Terragrunt ordering-only dependencies: Terragrunt
dependencies.paths(used for ordering) are not considered dependencies for filtering purposes
This distinction ensures that dependency filters only widen the scope to stacks that actually need to be included due to data dependencies, not execution order or forced-execution requirements.
Dependency Filter Flags β
Default behavior: When no dependency filter flags are used, the selection is left unchangedβonly the stacks that match your other filters (e.g. --changed, --tags) are selected. Dependencies and dependents are neither automatically included nor excluded. You must pass one of the flags below to expand or narrow the selection based on dependencies.
The following flags are supported by terramate list, terramate run, and terramate script run:
Include Dependencies β
--include-all-dependencies: Add all stacks that the selected stacks depend on (direct + transitive) to the selection--include-direct-dependencies: Add stacks that the selected stacks directly depend on to the selection
Replace with Dependencies β
--only-all-dependencies: Replace selection with only all stacks that the selected stacks depend on (direct + transitive)--only-direct-dependencies: Replace selection with only stacks that the selected stacks directly depend on
Exclude Dependencies β
--exclude-all-dependencies: Remove all stacks that the selected stacks depend on from the selection
Include Dependents β
--include-all-dependents: Add all stacks that depend on the selected stacks (direct + transitive) to the selection--include-direct-dependents: Add stacks that directly depend on the selected stacks to the selection
Replace with Dependents β
--only-all-dependents: Replace selection with only all stacks that depend on the selected stacks (direct + transitive)--only-direct-dependents: Replace selection with only stacks that directly depend on the selected stacks
Exclude Dependents β
--exclude-all-dependents: Remove all dependent stacks from the selection
Examples β
List changed stacks and their dependencies:
terramate list --changed --include-all-dependenciesRun commands only on stacks that depend on changed stacks:
terramate run --changed --only-all-dependents -- terraform planRun commands on changed stacks but exclude their dependencies:
terramate run --changed --exclude-all-dependencies -- terraform applyINFO
Only one of --only-all-dependencies, --only-direct-dependencies, --only-direct-dependents, or --only-all-dependents can be used at a time, as they replace the selection.
Integrations β
Detecting changed stacks that contain changes only is based on a Git integration.
Several other integrations exist to cover specific use cases. For example, the Terraform integration allows to mark stacks as changed even if they reference local Terraform modules that have changed but are located outside of a stack directory.