Running Many Units at Once
The idea in one sentence
Section titled “The idea in one sentence”terragrunt run --all plan and terragrunt run --all apply operate on every unit under the current directory tree at once, in the dependency order established by their dependency blocks.
run —all is the current command
Section titled “run —all is the current command”terragrunt run --all planterragrunt run --all applyrun --all discovers every unit under the current working directory, builds the dependency graph from their dependency blocks — covered in the previous lesson — and runs the given command against each one in the correct order. vpc applies before ec2 automatically; nobody has to remember or hard-code that sequencing.
A word about older syntax you will see in older material
Section titled “A word about older syntax you will see in older material”Terragrunt’s multi-unit command surface has changed, and a lot of existing blog posts and answers online still describe the old one. Two generations of history are worth knowing so stale advice does not trip you up:
terragrunt plan-all and terragrunt apply-all (along with destroy-all, output-all, and validate-all) have been completely removed from current Terragrunt. They do not exist anymore and will simply fail — do not use them, and treat any tutorial that leans on them as written for a much older version:
# Removed entirely — these commands no longer exist in current Terragruntterragrunt plan-allterragrunt apply-allterragrunt run-all <command> still runs today but is deprecated — it is being replaced by run --all, the syntax this course teaches:
# Deprecated — being replaced by run --all; avoid in new configurationterragrunt run-all planScoping a run —all, and running non-interactively
Section titled “Scoping a run —all, and running non-interactively”Sometimes you do not want every unit in the tree, only a subset — say, everything under one region while leaving the rest of the tree untouched. The --filter flag does that, matching units by a path glob. Flags placed before the command need a -- separator so Terragrunt knows where its own flags end and the per-unit command begins:
# Only plan units under ./networking (and anything depending on them)terragrunt run --all --filter './networking/**' -- planFor CI, prompting for a manual confirmation on every unit is not an option — --non-interactive skips those prompts so an apply can run unattended:
terragrunt run --all --non-interactive -- applybefore_hook and after_hook
Section titled “before_hook and after_hook”A terraform block inside a unit’s terragrunt.hcl can define before_hook and after_hook entries — arbitrary shell commands Terragrunt runs immediately before or after a given operation on that specific unit:
terraform { before_hook "validate_before_plan" { commands = ["plan"] execute = ["./scripts/validate-tags.sh"] }
after_hook "notify_slack" { commands = ["apply"] execute = ["./scripts/notify-slack.sh"] run_on_error = false }}commands lists which Terragrunt commands trigger the hook, execute is the actual command Terragrunt runs — as an argument list, not a shell string — and run_on_error controls whether an after_hook still fires if the operation it is attached to failed. During a run --all apply across many units, each unit’s own hooks fire around that unit’s own apply — the Slack notification above fires once per unit that successfully applies, not once for the whole run.
flowchart LR cmd["terragrunt run --all apply"] --> vpc["vpc unit applies first"] vpc --> ec2["ec2 unit applies (depends on vpc)"] vpc --> rds["rds unit applies (depends on vpc)"] vpc -->|after_hook| slack["notify-slack.sh"]