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)
Section titled “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
planorapply, 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
--parallelismflag), but it will always wait for a unit’s dependencies (or dependents for destroys) to complete successfully before running that unit.
Example DAG
Section titled “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 planOrder: Terragrunt would runindependentandancestor-dependencyconcurrently. Onceancestor-dependencyfinishes,dependencywould run. Oncedependencyfinishes,dependentwould run.run --all destroyOrder: Terragrunt would rundependentandindependentconcurrently. Oncedependentfinishes,dependencywould run. Oncedependencyfinishes,ancestor-dependencywould run.
Visualizing the DAG
Section titled “Visualizing the DAG”To visualize the dependency graph you can use the dag graph command (similar to the tofu/terraform graph command), or its equivalent list --format=dot --dependencies --external command.
The graph is output in DOT format. The typical program used to render this file format is GraphViz, but many web services are available that can do this as well.
terragrunt dag graph | dot -Tsvg > graph.svg# Or equivalently:terragrunt list --format=dot --dependencies --external | dot -Tsvg > graph.svgFor a stack with frontend-app, backend-app, mysql, valkey, and vpc units (where frontend-app depends on backend-app and vpc, backend-app depends on mysql/valkey/vpc, and mysql/valkey depend on vpc), the rendered graph looks like:

The arrow points from a unit to its dependency (e.g. frontend-app depends on backend-app).
For plan and apply, Terragrunt runs units in the opposite direction of the arrow (e.g. backend-app is applied before frontend-app). For destroy (and plan/apply -destroy), Terragrunt runs in the direction of the arrow (e.g. frontend-app is destroyed before backend-app).
Controlling the Queue
Section titled “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
Section titled “Include by default”By default, when using the --all flag, Terragrunt will include all units that are in the current working directory.
Using any positive filter triggers “Exclude by default” behavior, meaning that Terragrunt will no longer automatically include all units in the current working directory, and will instead selectively include units only if they match a positive filter (and don’t match any negative filters).
More on this in the Filtering Units section.
Filtering Units
Section titled “Filtering Units”You can control which units are included or excluded from the queue using the --filter flag.
Positive Filters
Section titled “Positive Filters”Any filter that doesn’t start with a ! prefix is considered a positive filter. When Terragrunt sees that any positive filter is present, it will evaluate every path it encounters while walking the directory tree, and only include units that match a positive filter.
terragrunt run --all --filter './subtree/**' -- planThis will tell Terragrunt only to run the units that match the glob pattern ./subtree/** (any directory found in the current working directory starting with subtree).
There are many more types of filters you can use, and those details are covered in the Filter feature documentation.
Negative Filters
Section titled “Negative Filters”Any filter that starts with a ! prefix is considered a negative filter. Negative filters are always evaluated after positive filters (if present).
terragrunt run --all --filter '!./subtree/**' -- planThis will tell Terragrunt to run all units in the current working directory except those that match the glob pattern ./subtree/** (any directory found in the current working directory starting with subtree).
Combining Positive and Negative Filters
Section titled “Combining Positive and Negative Filters”You can combine positive and negative filters to ensure that only the units you want are run.
terragrunt run --all --filter './subtree/**' --filter '!./subtree/dependency/**' -- planThis will tell Terragrunt to run all units in the directory subtree except those that match the glob pattern ./subtree/dependency/** (any directory found in the current working directory starting with subtree/dependency).
Modifying Order and Error Handling
Section titled “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 ofrunusing discovery commands, likefindandlist.e.g.
terragrunt list --queue-construct-as destroyThis 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: Run units in the queue concurrently without respecting the dependency order.e.g.
terragrunt run --all plan --queue-ignore-dag-orderRun
planonancestor-dependency,subtree/dependency,subtree/dependent, andindependentall 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-errorsIf
ancestor-dependency’s plan fails, Terragrunt will still attempt to runplanforsubtree/dependency, thensubtree/dependent, and also forindependent. -
--fail-fast: Fail the run if any unit fails, stopping all remaining units immediately.e.g.
terragrunt run --all plan --fail-fastIf
independent’s plan fails, Terragrunt will stop running any more units and fail the run, even ifancestor-dependency’s plan succeeds.
Limiting run parallelism
Section titled “Limiting run parallelism”By default, Terragrunt does not impose a limit on the number of units it executes when it traverses the dependency graph. If it finds 5 units without dependencies, it runs OpenTofu/Terraform 5 times in parallel, once in each unit.
This can create problems when a graph has many units, like hitting a cloud provider’s rate limit.
Use the --parallelism [number] flag to cap the maximum number of unit executions at any given time:
terragrunt run --all --parallelism 4 -- applyLimiting stack output parallelism
Section titled “Limiting stack output parallelism”terragrunt stack output reads unit outputs in parallel. Use the same --parallelism flag to lower concurrency if a large stack hits resource limits (for example, file descriptors or cloud-provider rate limits):
terragrunt stack output --parallelism 4Saving OpenTofu/Terraform plan output
Section titled “Saving OpenTofu/Terraform plan output”A powerful feature of OpenTofu/Terraform is the ability to save the result of a plan as a binary file using the -out flag.
Terragrunt provides special tooling in run --all execution to ensure that the saved plan for a run --all against a stack has a corresponding entry for each unit in the stack in a directory structure that mirrors the stack structure.
To save every plan generated when running a stack, use the --out-dir flag (or TG_OUT_DIR environment variable) as demonstrated below:
$ terragrunt run --all --out-dir /tmp/tfplan -- planDirectoryapp1
- tfplan.tfplan
Directoryapp2
- tfplan.tfplan
Directoryapp3
- tfplan.tfplan
Directoryproject-2
Directoryproject-2-app1
- tfplan.tfplan
This integration also exists for the apply command, where the generated plan will be used when performing the apply.
$ terragrunt run --all --out-dir /tmp/tfplan -- applyFor planning a destroy operation, use the following commands:
terragrunt run --all --out-dir /tmp/tfplan -- plan -destroyterragrunt run --all --out-dir /tmp/tfplan -- applyTo save plans in json format use the --json-out-dir flag:
terragrunt run --all --json-out-dir /tmp/json -- planDirectoryapp1
- tfplan.json
Directoryapp2
- tfplan.json
Directoryapp3
- tfplan.json
Directoryproject-2
Directoryproject-2-app1
- tfplan.json
terragrunt run --all --out-dir /tmp/all --json-out-dir /tmp/all -- planDirectoryapp1
- tfplan.json
- tfplan.tfplan
Directoryapp2
- tfplan.json
- tfplan.tfplan
Directoryapp3
- tfplan.json
- tfplan.tfplan
Directoryproject-2
Directoryproject-2-app1
- tfplan.json
- tfplan.tfplan