Terramate Change Detection: Run Terraform Only on Changed Stacks
Use Terramate git-aware change detection to run Terraform only on stacks modified since a git reference, skipping unchanged infrastructure.
27 Jul 2025, 11:27 UTC

The problem: Terraform runs everywhere, even where nothing changed
In a monorepo with many Terraform or OpenTofu stacks, a standard terraform apply loop touches every directory. That wastes time and increases blast radius when only one service actually changed. Terramate treats directories with a .tm.hcl file as stacks and compares the working tree against a git reference. The useful takeaway: use terramate run --changed to execute commands only in stacks with relevant modifications, skipping the rest.
How Terramate identifies changed stacks
A Terramate stack is any directory containing a .tm.hcl file with a stack block declaring a unique name. Directories without that block are ignored. When you pass --changed, Terramate compares working-tree files in each stack directory against a git commit, such as origin/main. Stacks with no detected changes are skipped by terramate run. Terramate does not manage Terraform state or replace terraform apply; it only orchestrates where commands execute.
Worked example: two stacks, one change
Assume a repository root with this layout:
infra/
networking/
.tm.hcl
main.tf
databases/
.tm.hcl
main.tf
terramate.cli.hcl
Each .tm.hcl file declares a stack:
# infra/networking/.tm.hcl
stack {
name = "networking"
}
# infra/databases/.tm.hcl
stack {
name = "databases"
}
Run these commands from the repository root in a terminal. You need read access to the git repository; no elevated permissions are required.
# Confirm the installed release; flag behavior can differ between versions
terramate version
# List only stacks with changes since a git reference
terramate show stacks --changed --git-origin
# Example with a concrete reference
terramate show stacks --changed --git-origin origin/main
# Run terraform init only in changed stacks
terramate run --changed --git-origin -- terraform init
Expected check: if you modified infra/networking/main.tf but not infra/databases/, the list command should print only networking, and the run command should execute terraform init in that stack only.
Risk: uncommitted changes in unrelated files inside a stack directory can mark that stack as changed, depending on detection settings. Review terramate show stacks --changed before running apply.
Run apply only where it matters
Once you confirm the changed list, you can scope terraform apply the same way:
terramate run --changed --git-origin -- terraform apply -auto-approve
This changes state. Do not run it in parallel across stacks that share the same remote state file; concurrent writes can corrupt state. Terramate can generate backend configuration from stack metadata, which can help keep state files separate, but verify the generated blocks match your intended buckets and regions.
Limits and common mistakes
- Git is required. Without a git repository,
--changedmay behave unexpectedly or include all stacks. - Stack names must be unique. Renaming a stack breaks references in generated outputs and dependencies.
- Uncommitted noise. Changes to files unrelated to Terraform can still flag a stack as changed.
- Shared state risk. Running
terraform applyin parallel across stacks that reference one state file can corrupt it. - Version differences. CLI flags and defaults vary between Terramate releases; verify your installed version before adopting
--changedin automation.
Practical verification
- Run
terramate versionandterramate run --helpto confirm change-detection flags exist in your release. - Create two stack directories with
.tm.hclfiles, modify a file in one, then runterramate show stacks --changed. Only the modified stack should appear. - Run
terramate run --changed -- terraform initin a test repo and confirm untouched stacks do not execute Terraform. - Inspect generated backend blocks to confirm they match stack names and regions.
There is no Terramate-specific rollback for change detection because terramate run itself does not modify Terraform state. If the commands it executes change infrastructure, roll back those resources through your normal Terraform workflow.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.