Skip to content
🎉 Terragrunt v1.0 is here! Read the announcement to learn more.

Active Experiments

The following experiments are available for opt-in. See the experiments overview for how to enable them.


azure-backend

Experimental support for the Azure Storage (azurerm) remote state backend.

azure-backend - What it does

Enabling this experiment turns on Terragrunt-managed lifecycle operations for the Azure Storage (azurerm) remote state backend, matching what Terragrunt already does for S3 buckets and GCS buckets:

  1. Bootstrap: creates the resource group (when allowed), storage account, and blob container backing the state, and converges blob versioning and optional soft delete on both new and pre-existing accounts.
  2. Delete: removes state blobs or entire containers, with confirmation prompts.
  3. Migrate: moves state blobs within the same storage account (cross-account migration is refused with guidance to migrate manually).

Authentication supports six methods, resolved in the following order:

  1. SAS token
  2. Storage account access key
  3. Service principal
  4. Managed identity (MSI)
  5. OIDC / workload identity
  6. Azure AD (use_azuread_auth or the default credential chain, which honors az login)

ARM_* and AZURE_* environment variable fallbacks are applied. Set environment (or ARM_ENVIRONMENT) to usgovernment for Azure Government.

Without the experiment enabled, these lifecycle operations return an error naming the experiment; normal state reading and writing is handled by the native OpenTofu/Terraform azurerm backend.

When both this experiment and dependency-fetch-output-from-state are enabled, Terragrunt can read dependency outputs directly from the Azure state blob without initializing the dependency or running tofu output/terraform output. State protected with customer_provided_key, and configurations that rely on native-only authentication, metadata_host, or timeout_seconds, continue through the native backend path. This preserves the backend’s identity, endpoint, and decryption behavior.

See the Azure Storage backend documentation for configuration keys and known limitations.

azure-backend - How to enable it

Terminal window
# Via CLI flag
terragrunt --experiment azure-backend run -- plan
# Via environment variable
export TG_EXPERIMENT=azure-backend
terragrunt run -- plan

azure-backend - How to provide feedback

Track and discuss this experiment in gruntwork-io/terragrunt#4307. When reporting issues or providing feedback, please include:

  • The Azure authentication method you are using (Azure AD, MSI, service principal, SAS, access key).
  • The cloud environment (public, government, china).
  • Any errors encountered during init, plan, or backend bootstrap.

azure-backend - Criteria for stabilization

To transition the azure-backend feature to a stable release, the following must be addressed, at a minimum:

  • internal/azurehelper package wrapping the Azure SDK with a builder pattern matching awshelper/gcphelper.
  • Bootstrap of storage accounts and blob containers, including versioning and soft delete convergence.
  • Optional RBAC role assignment for use_azuread_auth during bootstrap, via assign_blob_data_role.
  • Delete operations for state blobs and containers, with confirmation prompts, and state migration within a storage account.
  • Direct state file reads from Azure blobs for --dependency-fetch-output-from-state.
  • Documentation covering authentication methods, configuration keys, and troubleshooting.
  • End-to-end live coverage against a real subscription for container bootstrap, blob versioning convergence, backend delete, and direct dependency state reads, behind the azure build tag.
  • End-to-end live coverage for resource group and storage account creation, soft-delete retention convergence, and state migration.
  • Community feedback on real-world usage.

block-iteration

Reserves the expansion block, which will iterate a dependency, unit, or stack block over a count or for_each.

block-iteration - What it does

Terragrunt has no way to declare one block and have several components come out of it. Running the same unit in three environments means writing the unit block three times in terragrunt.stack.hcl, and depending on one unit per region means writing one dependency block per region.

This experiment gates an expansion block that will carry count and for_each, along with an enabled attribute on unit and stack blocks:

terragrunt.stack.hcl
unit "app" {
expansion {
for_each = toset(["web", "api"])
}
source = "./modules/app"
path = "app"
}

The flag is reserved, and enabling it has no behavioral effect yet. An expansion block inside a unit or stack block is ignored during stack generation, one inside a dependency block is rejected by the HCL decoder as an unsupported block type, and the enabled attribute is ignored. The iteration behavior itself is still being built, so nothing here is safe to depend on.

Without the experiment, an expansion block in any of those three block types is an error that names the flag, so a configuration written for the finished feature fails instead of quietly doing nothing:

the unit "app" block in /path/to/terragrunt.stack.hcl uses an expansion block, which requires the 'block-iteration' experiment; enable it with --experiment block-iteration

block-iteration - How to enable it

Terminal window
# Via CLI flag
terragrunt --experiment block-iteration stack generate
# Via environment variable
export TG_EXPERIMENT=block-iteration
terragrunt stack generate

block-iteration - How to provide feedback

Track and discuss this experiment in gruntwork-io/terragrunt#4504.

block-iteration - Criteria for stabilization

To transition the block-iteration feature to a stable release, the following must be addressed:

  • count and for_each expansion implemented for dependency, unit, and stack blocks.
  • The enabled attribute implemented for unit and stack blocks.
  • Naming rules for expanded components settled, so generated paths and the addresses that reference them stay predictable as an iteration source changes.
  • A cap on how many components one block may expand into, so a mistaken expression cannot generate an unusable estate.
  • References to an expanded dependency from inputs resolve the way users expect.
  • Parity checks against the same configuration written out by hand, covering terragrunt stack generate and the run queue.
  • Positive feedback from users replacing repeated blocks with iteration.

bounded-discovery

Enclose graph traversal for a --filter expression within a directory using an inline (dir) operand, instead of the Git repository root.

bounded-discovery - What it does

Graph-traversing filter expressions reach beyond the working directory. Dependent discovery (...{unit}) requires searching from the working directory of the given component up to the Git repository root (if the unit is within a Git repository). Dependency discovery ({unit}...) requires recursive parsing of dependencies to find the terminal dependency. Either way, Terragrunt has to read and parse every configuration it touches along the way for accuracy. In monorepos where sibling environments cannot be parsed independently of each other, that traversal fails or wastes work reaching into them.

When enabled, this experiment unlocks an inline (dir) boundary operand. It sits in the same operand slot as a traversal depth (e.g. 1...{vpc}):

Terminal window
cd environments/staging
terragrunt find --experiment bounded-discovery --filter '(.)...{vpc}'
# dependents of vpc, enclosed within the current environment
(.)...{vpc}
# dependencies of vpc, enclosed within the current environment
{vpc}...(.)
# independent bounds per direction
(../shared)...{vpc}...(.)

Any configuration that is discovered outside the boundary, whether a dependent or a dependency, is not read, parsed, or returned. The boundary must be an existing directory. Relative paths are resolved against the working directory, and a dependent-direction boundary must contain the working directory.

A boundary bounds discovery traversal rather than filtering results, so an in-boundary unit reachable only by passing through an out-of-boundary unit is intentionally excluded. Given a —> b —> c, if b is outside the boundary, traversal from a cannot reach c, and vice-versa.

Because the boundary operand claims ( and ), those characters are no longer read as part of a unit name or path. Wrap a name or path that contains them in braces (e.g. {./weird(name)}) to keep it literal.

The experiment also unlocks the --discovery-boundary flag (env: TG_DISCOVERY_BOUNDARY), which applies one boundary to every --filter expression on the command, in both directions:

Terminal window
cd environments/staging
terragrunt find --experiment bounded-discovery --filter '...{vpc}' --discovery-boundary .

An inline (dir) operand overrides the flag for the expression that carries it. See the --discovery-boundary reference for how the boundary is resolved.

bounded-discovery - How to provide feedback

Provide your feedback in the bounded-discovery Experiment Feedback Discussion.

bounded-discovery - Criteria for stabilization

To transition the bounded-discovery feature to a stable release, the following must be addressed:

  • Confirm a single directory boundary covers the common isolation layouts (per-environment directories, shared parent configuration).
  • Decide whether a boundary should also accept a glob, or remain directory-only.
  • Decide whether path-restricting filter intersections (e.g. ...{unit} | ./**) should narrow the boundary automatically, making the explicit boundary unnecessary for most uses.
  • Decide whether and how the boundary should apply to Git-based filter expressions (e.g. [main...HEAD]).
  • Positive feedback from users relying on the operand and the flag in repositories with isolated environments.

browse-tui

Adds the terragrunt browse command, which browses the discovered infrastructure estate in an interactive terminal user interface (TUI).

browse-tui - What it does

With the experiment enabled, terragrunt browse opens a yazi-style, three-column browser of the discovered estate. See the browse command documentation for usage and keybindings.

Running terragrunt browse without the experiment enabled is an error.

browse-tui - How to provide feedback

Provide your feedback on the browse-tui GitHub Discussion.

browse-tui - Criteria for stabilization

To transition the browse-tui feature to a stable release, the following must be addressed:

  • The browser renders large estates without noticeable latency.
  • Actions for running commands against a highlighted unit or stack are implemented.
  • The same TUI is shared with the catalog scaffolding experience.
  • Positive feedback from users browsing real infrastructure estates.
  • Integration tests covering the core browsing workflow.

catalog-format

Non-interactive output formats for the catalog command.

catalog-format - What it does

The catalog command renders an interactive terminal user interface, which leaves scripts, CI jobs, and agents with no way to read what it discovers. This experiment adds a --format flag that writes results to standard output instead: jsonl emits one JSON object per catalog entry, and md emits a Markdown document.

Both formats render progressively, as entries are discovered, so a consumer that only needs the first few can stop reading before discovery finishes. Entries appear in discovery order, which is not stable between runs.

The jsonl records follow a published JSON schema, so consumers can validate what they read.

Interactivity stays in the terminal user interface. Scaffolding a module and copying a unit or stack are not available in the non-interactive formats, which report the command to run instead.

catalog-format - How to provide feedback

Track and discuss this experiment in gruntwork-io/terragrunt#6579. When reporting issues or providing feedback, please include:

  • How you consume catalog output (shell script, CI job, agent tooling).
  • The format you are using, and any entry fields you need that are missing.
  • Whether you depend on reading output before the command exits.

catalog-format - Criteria for stabilization

To transition the catalog-format feature to a stable release, the following must be addressed, at a minimum:

  • A --format flag on catalog accepting jsonl and md.
  • Progressive rendering of both formats, so output is usable before discovery completes.
  • A published JSON schema for jsonl records.
  • A default format derived from what the output stream supports, so piping catalog does not require passing --format.
  • Documentation covering each format and the stability guarantees of the record structure.
  • Integration test coverage for each format.
  • Community feedback on real-world usage.

deep-merge

Support for the deep_merge HCL function.

deep-merge - What it does

When enabled, Terragrunt exposes a deep_merge(map1, map2, ...) HCL function for combining map or object values.

For overlapping keys, values from later arguments override earlier arguments. Nested maps are merged recursively, lists are appended, and null arguments are ignored.

This is useful when building inputs from multiple JSON, YAML, or HCL-derived maps without having to rely on include block merge behavior.

Terminal window
terragrunt run --all --experiment deep-merge -- plan

deep-merge - How to provide feedback

Provide your feedback in the deep-merge GitHub Discussion.

deep-merge - Criteria for stabilization

To transition the deep-merge feature to a stable release, the following must be addressed:

  • Confirm the merge semantics are useful for common configuration layering workflows.
  • Confirm type handling for decoded JSON/YAML and native HCL objects matches user expectations.
  • Positive feedback from users relying on the function in production pipelines.

dependency-fetch-output-from-state

Support for fetching dependency outputs directly from state files.

dependency-fetch-output-from-state - What it does

By default, Terragrunt retrieves dependency outputs by running tofu output or terraform output commands, which requires initializing the dependency unit and can be slow. When this experiment is enabled, Terragrunt will attempt to fetch dependency outputs directly from the remote state file, bypassing the need to initialize the dependency and significantly speeding up dependency processing.

Current Backend Support:

  • S3 and GCS backends: Direct state reads are supported
  • Azure Storage (azurerm) backend: Direct state reads are supported when the azure-backend experiment is also enabled
  • Other backends: Falls back to the normal method (using tofu/terraform output)

Azure state protected with customer_provided_key, and Azure configurations that rely on native-only authentication, metadata_host, or timeout_seconds, also use the normal method.

GCS configurations that rely on backend-only credential environment variables, inline credentials or relative credential-file paths, service-account impersonation, custom storage endpoints, custom universe domains, or competing credential sources with different precedence also use the normal method. This preserves the native backend’s authentication and endpoint behavior.

Known Limitations:

This experiment is not compatible with OpenTofu state encryption. When OpenTofu’s client-side state encryption is enabled, the state file is encrypted before upload. Since this experiment reads the raw state object directly through the backend’s cloud storage API, it cannot decrypt the state and will fail with a JSON parsing error. If you are using OpenTofu state encryption, you must disable this experiment using the --no-dependency-fetch-output-from-state flag.

Disabling the feature:

You can disable the dependency-fetch-output-from-state feature using the --no-dependency-fetch-output-from-state flag, even when the experiment is enabled:

Terminal window
terragrunt run --all --experiment-mode --no-dependency-fetch-output-from-state -- plan

dependency-fetch-output-from-state - How to provide feedback

Provide your feedback in the dedicated GitHub discussion page. When reporting issues or providing feedback, please include:

  • The backend type you’re using
  • Any performance improvements you’ve observed
  • Any issues or edge cases you’ve encountered

dependency-fetch-output-from-state - Criteria for stabilization

To transition the dependency-fetch-output-from-state feature to a stable release, the following must be addressed, at a minimum:

  • Add support for additional backends (GCS and Azure Storage)
  • Live direct-state-read integration coverage for S3, GCS, and Azure Storage
  • Comprehensive integration testing across backend authentication, encryption, workspace, and error scenarios
  • Performance benchmarking to validate speed improvements
  • Error handling and edge case testing
  • Documentation of supported backends and limitations
  • Handle OpenTofu state encryption gracefully (fallback or explicit error message)
  • Community feedback on real-world usage

hook-context-env

Expose additional TG_CTX_* environment variables to hook scripts.

hook-context-env - What it does

When enabled, Terragrunt sets three additional environment variables on the process running every before_hook, after_hook, and error_hook:

  • TG_CTX_HOOK_TYPEbefore_hook, after_hook, or error_hook, depending on which lifecycle phase is executing the hook.
  • TG_CTX_SOURCE — the resolved terraform source URL for the current unit, matching the precedence Terragrunt uses for the actual download: the --source CLI override if set, otherwise the evaluated terraform.source (with --source-map applied), otherwise ..
  • TG_CTX_TERRAGRUNT_DIR — the directory containing the current Terragrunt config (equivalent to get_terragrunt_dir()).

These variables make it easier for hook scripts to branch on lifecycle phase, to know whether the unit pulls remote source, and to locate the config directory without having to thread that information through hook arguments.

Terminal window
terragrunt run --all --experiment hook-context-env -- apply

Example hook script:

#!/usr/bin/env bash
case "$TG_CTX_HOOK_TYPE" in
before_hook) echo "preparing $TG_CTX_TERRAGRUNT_DIR" ;;
after_hook) echo "cleaning up $TG_CTX_TERRAGRUNT_DIR" ;;
error_hook) echo "failure in $TG_CTX_TERRAGRUNT_DIR" ;;
esac
if [ "$TG_CTX_SOURCE" != "." ]; then
echo "unit uses source: $TG_CTX_SOURCE"
fi

hook-context-env - How to provide feedback

Provide your feedback in the hook-context-env GitHub Discussion.

hook-context-env - Criteria for stabilization

To transition the hook-context-env feature to a stable release, the following must be addressed:

  • Confirm the three new variables cover the most common hook scripting needs.
  • Confirm the chosen variable names and values (before_hook/after_hook/error_hook) match user expectations.
  • Positive feedback from users relying on the variables in production hook scripts.

iac-engine

Support for Terragrunt IaC engines.

iac-engine - What it does

Enables usage of Terragrunt IaC engines for running IaC operations. This allows Terragrunt to use pluggable engines to execute Terraform/OpenTofu commands, providing enhanced functionality and extensibility.

IaC engines are still experimental, as the API is unstable and may change in future minor versions of Terragrunt.

You can disable engine usage on a per-command basis using the --no-engine flag, even when the experiment is enabled globally.

iac-engine - How to provide feedback

Provide your feedback on the Terragrunt IaC Engines GitHub discussion.

iac-engine - Criteria for stabilization

To transition the iac-engine feature to a stable release, the following must be addressed, at a minimum:

  • API stability and backward compatibility guarantees
  • Comprehensive integration testing across all supported operations
  • Documentation of engine development and integration process
  • Performance benchmarks and optimization
  • Security review of engine execution and isolation mechanisms
  • Community feedback on real-world usage and edge cases

mutable-generate

Deduplicate the files produced by generate blocks through content-addressable storage, with a mutable attribute to opt out.

mutable-generate - What it does

With the experiment enabled, the contents a generate block produces are stored in the CAS, and the file written at path is a read-only link to that stored copy rather than a file of its own. The link is read-only because the stored copy is shared: an edit through one path would otherwise change what every later reader of that content sees.

Because the stored copy is addressed by the hash of its contents, anything generating identical contents links to the same copy instead of writing its own. That matters most for a generate block declared in a parent configuration, which writes the same content into every unit that includes it. A provider or backend block shared across a few hundred units used to mean a few hundred copies in .terragrunt-cache, and now means one.

The experiment also adds a mutable attribute to the generate block, for cases where a shared read-only file does not work:

generate "provider" {
path = "provider.tf"
if_exists = "overwrite"
mutable = true
contents = <<EOF
provider "aws" {
region = "us-east-1"
}
EOF
}

mutable = true gives the block a writable file of its own. Use it when something rewrites the generated file in place, such as a hook that patches it before tofu/terraform runs. Terragrunt regenerates the file rather than editing it, and tofu/terraform only read it, so most generate blocks do not need it.

Setting mutable without the experiment enabled is an error, because older Terragrunt versions reject the attribute outright. The CAS is required, so --no-cas writes generated files directly and mutable has no effect.

mutable-generate - How to enable it

Terminal window
# Via CLI flag
terragrunt --experiment mutable-generate run --all -- apply
# Via environment variable
export TG_EXPERIMENT=mutable-generate
terragrunt run --all -- apply

mutable-generate - How to provide feedback

Track and discuss this experiment in gruntwork-io/terragrunt#6559. When reporting issues or providing feedback, please include:

  • Whether anything in your pipeline writes to a generated file after Terragrunt creates it.
  • The generate blocks involved, and how many units share them.
  • The disk usage of .terragrunt-cache before and after enabling the experiment.

mutable-generate - Criteria for stabilization

To transition the mutable-generate feature to a stable release, the following must be addressed, at a minimum:

  • A mutable attribute on the generate block, parsed from both the block and attribute forms.
  • Deduplication of non-mutable generated files through the CAS store, materialized as read-only hard links.
  • Confirmation that read-only generated files break no established workflow, including hooks and IaC engines.
  • A decision on whether remote_state.generate should participate, given its per-unit backend keys rarely repeat.
  • Community feedback on the disk savings actually observed at scale.

oci

Experimental support for downloading modules from OCI Distribution registries using oci:// sources.

oci - What it does

OpenTofu 1.10 can download modules from an OCI Distribution registry using an oci:// source. This experiment gates Terragrunt’s native support for the same sources, so a single source string works the same way in both tofu and Terragrunt against registries such as Amazon ECR, GitHub Container Registry, Azure Container Registry, Google Artifact Registry, and self-hosted or air-gapped registries.

With the experiment enabled, Terragrunt accepts oci:// source URLs in terraform { source = "..." } blocks, and in the unit and stack blocks of a terragrunt.stack.hcl. For example:

terraform {
source = "oci://ghcr.io/acme/terraform-modules/vpc?tag=1.0.0"
}
unit "vpc" {
source = "oci://ghcr.io/acme/terragrunt-units/vpc?tag=1.0.0"
path = "vpc"
}

Specify either tag or digest; omitting both selects the latest tag. //subdir selectors are supported.

Credentials come from OpenTofu’s CLI config, in the oci_credentials and oci_default_credentials blocks. Terragrunt reads the file named by TF_CLI_CONFIG_FILE or TERRAFORM_CONFIG, otherwise the first of ~/.tofurc and ~/.terraformrc that exists (on Windows, %APPDATA%\tofu.rc and %APPDATA%\terraform.rc). Unless one of those environment variables is set, it also merges the *.tfrc and *.tfrc.json files in OpenTofu’s config directory. Terragrunt also reads ambient Docker and containers auth files (~/.docker/config.json and containers auth.json), following the containers-auth search order OpenTofu uses as of OpenTofu 1.12. Set docker_style_config_files in oci_default_credentials to replace those default search paths, or an empty list to disable ambient discovery entirely.

Terragrunt ranks every matching CLI-config and ambient credential together by how much of the repository path each one matches, and uses the single best match. A CLI-config entry wins only when both candidates match equally closely. The oci_default_credentials helper is the global fallback, and Terragrunt pulls anonymously when nothing matches. Set discover_ambient_credentials = false in the oci_default_credentials block to use CLI config only.

Credential helpers configured in either place (credHelpers and credsStore in the Docker config, or a block’s docker_credentials_helper, such as ecr-login) are invoked when selected as the credential source, so ECR and other helper-backed registries work without a baked-in login. When the experiment is disabled, oci:// sources remain unsupported.

oci - How to enable it

Terminal window
# Via CLI flag
terragrunt --experiment oci run -- plan
# Via environment variable
export TG_EXPERIMENT=oci
terragrunt run -- plan

oci - How to provide feedback

Track and discuss this experiment in gruntwork-io/terragrunt#4555. When reporting issues or providing feedback, please include:

  • The registry you are using (ECR, GHCR, ACR, GAR, self-hosted).
  • The authentication method (an OpenTofu CLI-config oci_credentials block, ambient Docker config, or a credential helper such as ecr-login), and the CLI config file in use.
  • The full oci:// source string, and whether you pin by tag or digest.
  • Any errors encountered during module download.

oci - Criteria for stabilization

To transition the oci feature to a stable release, the following must be addressed, at a minimum:

  • A getter that resolves oci:// sources, selecting the application/vnd.opentofu.modulepkg artifact and its archive/zip layer, with blob digest verification.
  • OpenTofu CLI-config and ambient Docker-config credential discovery matching OpenTofu’s search order.
  • Credential-helper support (docker-credential-*, ecr-login) so ECR and other helper-backed registries work through the configured helper.
  • Content-addressable caching keyed on the resolved manifest digest, with correct re-resolution of mutable tags.
  • A portability guarantee that one source string produces an identical module via tofu and Terragrunt.
  • Documentation covering the source syntax, authentication tiers, and publishing contract.
  • Integration test coverage driving the full download chain against a local OCI Distribution registry.
  • Gated CI coverage against hosted registries (GHCR, ECR) with real credentials.
  • Community feedback on real-world usage.

optional-dependency-outputs

Support for skipping all dependency output resolution during a run.

optional-dependency-outputs - What it does

When enabled, users can pass --no-dependency-outputs to skip all dependency output resolution globally. dependency blocks will not call tofu/terraform output, mirroring the existing skip_outputs = true attribute on individual dependency blocks.

Terminal window
terragrunt run --experiment optional-dependency-outputs --no-dependency-outputs -- init

This is useful when you want to run commands that do not need dependency outputs (such as init or validate) without paying the cost of resolving them, or when the dependencies have not been applied yet.

optional-dependency-outputs - How to enable it

Terminal window
# Via CLI flag
terragrunt --experiment optional-dependency-outputs run --no-dependency-outputs -- init
# Via environment variable
export TG_EXPERIMENT=optional-dependency-outputs
terragrunt run --no-dependency-outputs -- init

optional-dependency-outputs - Criteria for stabilization

To transition the optional-dependency-outputs feature to a stable release, the following must be addressed, at a minimum:

  • Validate behavior with single-unit and queue-based runs.
  • Gather community feedback on the flag name and scope.
  • Confirm the interaction with commands that require dependency outputs (such as plan, apply, or destroy).

optional-hooks

Support for disabling Terragrunt hooks during run.

optional-hooks - What it does

When enabled, users can pass --no-hooks to terragrunt run to skip configured before_hook, after_hook, and error_hook blocks.

Terminal window
terragrunt run --experiment optional-hooks --no-hooks -- plan

This is useful when a run needs to bypass hook automation temporarily, such as when debugging faulty hooks or OpenTofu/Terraform modules.

optional-hooks - How to provide feedback

Track and discuss this experiment in gruntwork-io/terragrunt#6078.

optional-hooks - Criteria for stabilization

To transition the optional-hooks feature to a stable release, the following must be addressed:

  • Validate behavior with single-unit and queue-based runs.
  • Gather community feedback on whether all hook types should be skipped.
  • Confirm the flag name leaves room for more granular hook controls in the future.

otel-logs

Export Terragrunt’s logs as an OpenTelemetry logs signal.

otel-logs - What it does

When enabled, Terragrunt emits its log output as OpenTelemetry log records in addition to the existing traces and metrics signals. The exporter is selected with TG_TELEMETRY_LOGS_EXPORTER:

  • none - no log exporting (the default).
  • console - write log records to the console as JSON.
  • otlpHttp - export logs to an OpenTelemetry collector over HTTP.
  • otlpGrpc - export logs to an OpenTelemetry collector over gRPC.

The OTLP exporters read their endpoint from the standard OTEL_EXPORTER_OTLP_ENDPOINT environment variable. Set TG_TELEMETRY_LOGS_EXPORTER_INSECURE_ENDPOINT=true to disable TLS and send logs over an insecure connection. Only use this for local collection.

Terminal window
TG_TELEMETRY_LOGS_EXPORTER=otlpHttp terragrunt run --all --experiment otel-logs -- apply

Records emitted while a unit’s span is active carry that span’s trace and span IDs, so a failed unit’s logs link back to its span in the backend: clicking a unit’s span in the trace view surfaces exactly the logs it produced. Run-level records emitted outside any span are exported without correlation IDs. Without the experiment enabled, the logs exporter stays inert regardless of TG_TELEMETRY_LOGS_EXPORTER.

otel-logs - How to provide feedback

Provide your feedback in the OpenTelemetry logs integration issue.

otel-logs - Criteria for stabilization

To transition the otel-logs feature to a stable release, the following must be addressed:

  • Confirm the exporter types and configuration cover common collector setups.
  • Validate log volume and batching behavior on large stacks.
  • Confirm trace/span correlation is reliable across the run lifecycle, including run-level logs emitted outside a unit span.
  • Settle on the dependency stability story for the OpenTelemetry logs SDK, which is still pre-1.0.

profiling

Collect CPU profiles, memory (heap) profiles, and goroutine profiles for Terragrunt.

profiling - What it does

When enabled, Terragrunt allows collecting runtime profiles using CLI flags (or the corresponding TG_PROFILE_* environment variables):

  • --profile-cpu / TG_PROFILE_CPU: write a CPU profile
  • --profile-mem / TG_PROFILE_MEM: write a heap memory profile
  • --profile-goroutine / TG_PROFILE_GOROUTINE: write a goroutine profile (stack traces of all goroutines)
  • --profile-dir / TG_PROFILE_DIR: collect all of the above into a single directory using conventional filenames

Example:

Terminal window
terragrunt --experiment=profiling --profile-dir /tmp/profiles run --all -- plan

This is primarily intended for performance investigation and debugging of Terragrunt itself.

The experiment can also be enabled with TG_EXPERIMENT=profiling, which is convenient when driving profiling entirely through environment variables.

profiling - How to provide feedback

Provide feedback on the Terragrunt GitHub Discussions or by opening an issue.

profiling - Criteria for stabilization

To transition the profiling experiment to a stable release, the following should be addressed:

  • Validate that profiling reliably covers Terragrunt runs across different invocation styles.
  • Ensure documentation (CLI flags + env vars) is complete and accurate.
  • Gather feedback on the chosen flag names (--profile-*).
  • Decide whether additional profile types (block, mutex, etc.) should be exposed.
  • Confirm the interaction with --experiment-mode and TG_EXPERIMENT is ergonomic.

slow-task-reporting

Progress reporting for long-running Terragrunt operations.

slow-task-reporting - What it does

When enabled, Terragrunt displays animated progress spinners for operations that take longer than 1 second (e.g., Git worktree creation). Once the operation completes, the spinner is replaced with an INFO log line showing the operation result and elapsed time.

This provides visual feedback during operations that would otherwise show no output:

  • Git worktree creation for --filter with Git references
  • Catalog repository cloning (terragrunt catalog)
  • OpenTofu/Terraform source downloads via go-getter

In non-interactive environments (CI/CD, piped output), spinners are suppressed and INFO log lines are emitted instead. To prevent CI systems (e.g., CircleCI) from killing jobs due to prolonged output silence, periodic keepalive log lines are emitted every 30 seconds while the operation is in progress.

Terminal window
terragrunt run --all --experiment slow-task-reporting -- plan

slow-task-reporting - How to provide feedback

Provide your feedback on the slow-task-reporting GitHub Discussion.

slow-task-reporting - Criteria for stabilization

To transition the slow-task-reporting feature to a stable release, the following must be addressed:

  • Validate spinner rendering across common terminal emulators (iTerm2, Terminal.app, Windows Terminal, GNOME Terminal)
  • Extend progress reporting to additional slow operations (e.g., provider caching)
  • Community feedback on usefulness and threshold tuning
  • Ensure no interference with structured log output when using --log-format json

Support symlink resolution for Terragrunt units.

By default, Terragrunt will ignore symlinks when determining which units it should run. By enabling this experiment, Terragrunt will resolve symlinks and add them to the list of units being run.

Provide your feedback on the Experiment: Symlinks discussion.

To stabilize this feature, the following need to be resolved, at a minimum:

  • Ensure that symlink support continues to work for users referencing symlinks in flags. See #3622.
    • Add integration tests for all filesystem flags to confirm support with symlinks (or document the fact that they cannot be supported).
  • Ensure that MacOS integration tests still work. See #3616.
    • Add integration tests for MacOS in CI.

version-attribute

Support for a version attribute on the terraform block that resolves a registry module from a version constraint.

version-attribute - What it does

When enabled, the terraform block accepts an optional version attribute holding a version constraint for a tfr:// registry module, such as ~> 3.3 or >= 1.0.0, < 2.0.0:

terraform {
source = "tfr://registry.opentofu.org/terraform-aws-modules/vpc/aws"
version = "~> 3.3"
}

Terragrunt resolves the constraint against the registry’s list-versions endpoint before the download begins, then fetches the highest published version that satisfies it. This brings the terraform block to parity with the version argument on OpenTofu and Terraform module blocks, so you no longer have to pin an exact version in the source URL.

The constraint lives only in the version attribute. By the time the module is downloaded and cached, it has been resolved to an exact version, so the --source override and the cache key still carry a concrete pin.

version-attribute - How to enable it

Terminal window
# Via CLI flag
terragrunt --experiment version-attribute run -- plan
# Via environment variable
export TG_EXPERIMENT=version-attribute
terragrunt run -- plan

version-attribute - How to provide feedback

Track and discuss this experiment in gruntwork-io/terragrunt#1930. When reporting issues or providing feedback, please include:

  • The tfr:// source and the version constraint you set.
  • The version you expected Terragrunt to resolve, and the version it resolved.
  • Whether you rely on prereleases, and how you upgrade across newly published versions.

version-attribute - Criteria for stabilization

To transition the version-attribute feature to a stable release, the following must be addressed, at a minimum:

  • Decide and document the cache invalidation policy. A constraint resolves once and is cached by source URL, so a newly published match is only picked up after --source-update. Confirm this is the right default, or re-resolve on every run.
  • Decide and document the prerelease policy. A constraint that names a prerelease (for example >= 1.0.0-rc1) opts into prereleases, matching OpenTofu and Terraform.
  • Decide whether --source and TG_SOURCE should keep accepting exact pins only, or also accept constraints.
  • Community feedback on real-world usage.