Shape
Shape

Run Queue

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:

  1. Discovery: Terragrunt discovers configurations that might be relevant to a run based on the current working directory.
  2. Constructing the Queue: Based on the command being run, Terragrunt creates an ordered queue.
    • For commands like plan or apply, dependencies are run before the units that depend on them.
    • For commands like destroy, dependent units are run before their dependencies.
  3. 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 B depends on Unit A, and Unit C depends on Unit B. Unit D has no dependencies.

Example DAG

  • run --all plan Order: Terragrunt would run C and D concurrently. Once C finishes, B would run. Once B finishes, A would run.
  • run --all destroy Order: Terragrunt would run A and D concurrently. Once A finishes, B would run. Once B finishes, C would run.

Controlling the Queue

Several flags allow you to customize how Terragrunt builds and executes the run queue:

Filtering Units

You can control which units are included or excluded from the queue:

Modifying Order and Error Handling

  • --queue-construct-as (--as): Build the dependency queue as if running a particular command. Useful for performing dry-runs of run using discovery commands, like find and list.
  • --queue-ignore-dag-order: Execute units concurrently without respecting the dependency order. Useful for read-only commands like validate or plan across independent units, but dangerous for commands that modify state (apply, destroy).
  • --queue-ignore-errors: Continue processing the queue even if some units fail. Useful for identifying all errors at once, but can lead to inconsistent state if used with apply or destroy.

Important Considerations

  • When using run --all plan with units that have dependencies (e.g. via dependency or dependencies blocks), the command will fail if those dependencies have never been deployed. This is because Terragrunt cannot resolve dependency outputs without existing state.

    To work around this issue, use mock outputs in dependency blocks.

  • Do not set TF_PLUGIN_CACHE_DIR when using run --all (unless using OpenTofu >= 1.10).

    This can cause concurrent access issues with the provider cache. Instead, use Terragrunt’s built-in Provider Cache Server.

  • When using run --all with apply or destroy, Terragrunt automatically adds the -auto-approve flag due to limitations with shared stdin making individual approvals impossible. Use --no-auto-approve to override this, but be aware you might need alternative approval workflows.