Run Queue
Terragrunt’s “Run Queue” is the mechanism it uses to manage the run order and concurrency when running OpenTofu/Terraform commands across multiple Terragrunt units. This is particularly relevant when using the run --all
or run --graph
commands.
How it Works: The Dependency Graph (DAG)
At its core, the Run Queue relies on a Directed Acyclic Graph (DAG) built from the dependencies defined between your Terragrunt units. These dependencies are typically established using dependency
or dependencies
blocks in your terragrunt.hcl
files.
Terragrunt analyzes these dependencies to determine the correct order of operations:
- Discovery: Terragrunt discovers configurations that might be relevant to a run based on the current working directory.
- Constructing the Queue: Based on the command being run, Terragrunt creates an ordered queue.
- For commands like
plan
orapply
, dependencies are run before the units that depend on them. - For commands like
destroy
, dependent units are run before their dependencies.
- For commands like
- Runs: Terragrunt dequeues the units in the queue and runs them, respecting the queue order. By default, it runs units concurrently up to a certain limit (controlled by the
--parallelism
flag), but it will always wait for a unit’s dependencies (or dependents for destroys) to complete successfully before running that unit.
Example DAG
Consider a setup where:
- Unit “dependent” depends on unit “dependency”.
- Unit “dependency” depends on unit “ancestor-dependency”.
- Unit “independent” has no dependencies nor dependents.
Directoryroot
Directorysubtree
Directorydependent
- terragrunt.hcl
Directorydependency
- terragrunt.hcl
Directoryancestor-dependency
- terragrunt.hcl
Directoryindependent
- terragrunt.hcl
Assuming a current working directory of the root
directory, Terragrunt would run units in the following order:
run --all plan
Order: Terragrunt would runindependent
andancestor-dependency
concurrently. Onceancestor-dependency
finishes,dependency
would run. Oncedependency
finishes,dependent
would run.run --all destroy
Order: Terragrunt would rundependent
andindependent
concurrently. Oncedependent
finishes,dependency
would run. Oncedependency
finishes,ancestor-dependency
would run.
Controlling the Queue
Several flags allow you to customize how Terragrunt builds and executes the run queue. By default, Terragrunt will include all units that are in the current working directory.
Include by default
By default, when using the --all
flag, Terragrunt will include all units that are in the current working directory, and any external dependencies.
Certain flags trigger “Exclude by default” behavior, meaning that Terragrunt will no longer automatically include all units in the current working directory, and will instead rely on discovering configurations based on the provided queue control flags.
Those flags will be discussed in the next section.
Filtering Units
You can control which units are included or excluded from the queue:
-
--queue-include-dir
: Specify glob patterns for directories to include. Can be used multiple times.e.g.
terragrunt run --all plan --queue-include-dir "subtree/*"
Include units within the
subtree
directory (along with their dependencies), i.e.,subtree/dependent
,subtree/dependency
andancestor-dependency
. -
--queue-exclude-dir
: Specify glob patterns for directories to exclude. Can be specified multiple times.e.g.
terragrunt run --all plan --queue-exclude-dir "independent"
Exclude the
independent
unit.ancestor-dependency
,subtree/dependency
, andsubtree/dependent
would still be processed according to their dependencies. -
--queue-excludes-file
: Provide a file containing a list of directories to exclude.e.g.
terragrunt run --all plan --queue-excludes-file ".tg-excludes"
.tg-excludes independentsubtree/dependencyExclude
independent
andsubtree/dependency
from the run, only runningsubtree/dependent
andancestor-dependency
. -
--queue-strict-include
: Only include units matching--queue-include-dir
.e.g.
terragrunt run --all plan --queue-include-dir "subtree/dependency" --queue-strict-include
Only include the
subtree/dependency
unit. Its dependency,ancestor-dependency
, will be excluded because it does not match the include and strict mode is enabled. -
--queue-include-external
: Include external dependencies (those outside the current working directory) by default.e.g.
terragrunt run --all plan --working-dir subtree --queue-include-external
Include
ancestor-dependency
in addition to thesubtree/dependent
andsubtree/dependency
units. -
--queue-exclude-external
: Exclude external dependencies.e.g.
terragrunt run --all plan --working-dir subtree --queue-exclude-external
Exclude
ancestor-dependency
from the run. Only runsubtree/dependent
andsubtree/dependency
. -
--queue-include-units-reading
: Include units that read a specific file (via includes or HCL functions likemark_as_read
).e.g.
terragrunt run --all plan --queue-include-units-reading "subtree/common.hcl"
dependency "dep" {config_path = "../dependency"skip_outputs = true}include "common" {path = find_in_parent_folders("common.hcl")}dependency "dep" {config_path = "../../ancestor-dependency"skip_outputs = true}include "common" {path = find_in_parent_folders("common.hcl")}# Intentionally emptyInclude
subtree/dependent
andsubtree/dependency
(the units that readsubtree/common.hcl
) in the run.
Modifying Order and Error Handling
-
--queue-construct-as
(--as
): Build the run queue as if a particular command was run. Useful for performing dry-runs ofrun
using discovery commands, likefind
andlist
.e.g.
terragrunt list --queue-construct-as destroy
This lists the units in the order they’d be processed for
run --all destroy
:Terminal window $ terragrunt list --as destroy -lType Pathunit independentunit subtree/dependentunit subtree/dependencyunit ancestor-dependencyTerminal window $ terragrunt list --as plan -lType Pathunit ancestor-dependencyunit independentunit subtree/dependencyunit subtree/dependent -
--queue-ignore-dag-order
: Execute units concurrently without respecting the dependency order.e.g.
terragrunt run --all plan --queue-ignore-dag-order
Run
plan
onancestor-dependency
,subtree/dependency
,subtree/dependent
, andindependent
all concurrently, without waiting for their defined dependencies. For instance,subtree/dependent
’s plan would not wait forsubtree/dependency
’s plan to complete). -
--queue-ignore-errors
: Continue processing the queue even if some units fail.e.g.
terragrunt run --all plan --queue-ignore-errors
If
ancestor-dependency
’s plan fails, Terragrunt will still attempt to runplan
forsubtree/dependency
, thensubtree/dependent
, and also forindependent
.