Gruntwork Release Notes
158 release notes curated from 2 sources by the Releasebot Team. Last updated: Aug 28, 2026
Gruntwork Products
- Aug 27, 2026
- Date parsed from source:Aug 27, 2026
- First seen by Releasebot:Aug 28, 2026
v1.1.4
Terragrunt ships interactive scaffold prompts, stricter dependency label checks, faster startup, and a wide set of fixes across CAS, provider caching, rendering, HCL validation, and security hardening. It also adds experiment updates for direct state reads and dependency expansion previews.
โจ New Features
duplicate-dependency-labels strict control
Declaring two dependency blocks with the same label in one terragrunt.hcl configuration file parsed without error, and then quietly resolved every reference to that label to whichever block came last. The blocks before it were silently overridden:
dependency "vpc" { config_path = "../vpc-us-east-1" } dependency "vpc" { config_path = "../vpc-us-west-2" } inputs = { # Reads ../vpc-us-west-2. vpc_id = dependency.vpc.outputs.vpc_id }Terragrunt now warns when it finds this. With the new duplicate-dependency-labels strict control enabled, the warning becomes an error naming the address the blocks share:
terragrunt run plan --strict-control duplicate-dependency-labels /path/to/terragrunt.hcl: dependency vpc is declared more than once; every dependency needs an address of its ownGive each block a label of its own. A configuration that was relying on the shadowing to pick the last block should keep only that block.
scaffold asks for values interactively
Scaffolding from the command line wrote # TODO placeholders for every input and left you to fill them in by hand, while scaffolding the same component from the Catalog TUI opened a form and collected them. terragrunt scaffold now opens that same form:
terragrunt scaffold github.com/gruntwork-io/terragrunt-infrastructure-modules-example//modules/mysqlFor a module or a template it lists the source's variables; for a unit or a stack it lists the values.* references its configuration makes, which are written to terragrunt.values.hcl. Dismissing the form with esc writes nothing.
The form is skipped, and the placeholders written as before, when you pass --non-interactive, when stdin is not a terminal, or when the source asks for nothing. A scaffold in a CI job, or one run by another program, therefore behaves exactly as it did.
See Scaffold for the full behavior, and the form's keybindings for driving it.
๐๏ธ Performance Improvements
Faster startup when --tf-path is not set
When you don't set --tf-path, Terragrunt picks the binary it wraps by looking for tofu on your PATH and falling back to terraform when it isn't there. Terragrunt used to make that choice by running tofu -version, which meant launching a process at the start of every command, including commands like find and list that never run the binary. That process launch is gone, and a terragrunt --version benchmark runs roughly 1.7x faster as a result.
This changes what happens when tofu is on your PATH but can't run: Terragrunt now selects it and reports the failure rather than silently falling back to terraform. Set --tf-path or TG_TF_PATH to pick the binary yourself.
๐ Bug Fixes
Autoinclude dependency overrides no longer evaluate replaced paths
Terragrunt used to evaluate a dependency's original config_path before applying a sibling autoinclude override. This could prevent a unit from being parsed when the original path referenced a value that the unit no longer supplied, even though the autoinclude replaced that path. Terragrunt now leaves replaced dependency blocks undecoded, then applies the autoinclude override. Dependency blocks without an autoinclude override are still validated.
Blocks that use expansion are still decoded, because a bare autoinclude label does not name their instances. If the autoinclude also declares the same label without expansion, Terragrunt reports a dependency label collision.
Fixed Git sources with a depth query parameter
A terraform.source (or stack source) URL carrying the go-getter depth query parameter, such as ...vpc.git?depth=1&ref=v5.21.0, failed to download since v1.1.0, when the CAS became the default path for Git sources. Terragrunt lifted ref out of the URL but left depth in place, so git received ...vpc.git?depth=1 and rejected it as an invalid repository name. A URL with depth and no ref hit the same failure.
Terragrunt now strips depth, with or without a ref, before invoking git, so these sources download again. The clone depth itself always comes from --cas-clone-depth, which defaults to 1; a depth on a source URL is never applied for CAS clones.
CAS handles local sources that have already been initialized
With CAS enabled, reading a local source that had already been initialized failed and fell back to the slower standard copy. Generating a stack from such a unit logged CAS processing failed ... source escapes repository root.
Provider caching was the cause. Both the Provider Cache Server and the Automatic Provider Cache Dir leave the plugins under .terraform pointing into a shared cache outside the source. CAS read those links as the source reaching outside itself and refused to copy the link for safety.
CAS now leaves .terraform and .terragrunt-cache out of local sources, keeping .terraform.lock.hcl and everything else. OpenTofu, Terraform, and Terragrunt rebuild both directories on demand, so units and stacks no longer receive a stale copy of either. Running tofu init in a source directory no longer changes that source's CAS key.
Fixed the signal sent to a running command during shutdown
On Windows, when a failure rather than Ctrl+C cancelled a run, Terragrunt crashed with a nil pointer panic instead of stopping the command it had started. It now terminates the command, which is the closest thing Windows offers to an interrupt.
On every platform, when a command exited on its own during the grace period after Ctrl+C, Terragrunt could still send it the signal and then log a forwarding error against a process that was already gone.
terraform_binary respected when reading dependency outputs
Reading a dependency block's outputs ignored the terraform_binary of the unit being read and fell back to the auto-detected binary, which is OpenTofu whenever tofu is on your PATH. With terraform_binary = "terraform", a unit ran through Terraform while the dependency it consumed was read through OpenTofu. A run --all over units that each worked on their own then failed with a backend initialization error, followed by a misleading There is no variable named "dependency".
Dependency outputs are now read through the binary the dependency itself configures, so a unit's terraform_binary applies wherever its state is read. --tf-path and TG_TF_PATH still take precedence over the config value.
Numbers with extreme exponents fail fast instead of stalling
A number literal such as 9E9999999 in inputs, locals, or a dependency block's mock_outputs used to cost over a minute of CPU on a single unit. Written out in decimal that number is ten million digits long, and terragrunt render --format=json produced every digit before failing with a ten megabyte error message.
Terragrunt now rejects numbers larger than 1e4096, and non-zero numbers smaller than 1e-4096, before it tries to write them out, and names the attribute holding the value:
count: number is outside the supported range of 1e-4096 to 1e4096Numbers inside that range are unaffected.
Registry credentials are no longer copied into the generated CLI config
When the Provider Cache Server is enabled, Terragrunt writes a CLI config for OpenTofu/Terraform into each unit's working directory, based on your own CLI config. That generated file used to include a copy of every credentials block from your config, including the ones for registries Terragrunt routes through the cache server.
Those copies were never read. For a routed registry, Terragrunt sets the matching TF_TOKEN_<hostname> environment variable, which takes precedence over a credentials block, and the cache server presents your real credentials when it contacts the registry on your behalf. The generated file now leaves the block out for those registries, so your token stays in the CLI config you put it in instead of being duplicated somewhere it had no effect.
Credentials for hosts the cache server does not route are unchanged, since OpenTofu/Terraform contacts those directly and still reads them from the generated config.
Upgrading does not rewrite the files an earlier version already generated. Each is named .terraformrc and sits in a unit's working directory, which is under .terragrunt-cache for remote sources. Delete those files, or clear the cache, to get the copied credentials off disk.
Generated files are readable only by the user who ran Terragrunt
Terragrunt created several files and directories that other users on the same machine could read:
The CLI config Terragrunt writes for OpenTofu/Terraform when the Provider Cache Server is enabled, and the directory holding it.
The JSON plan files written to --json-out-dir, and that directory.
The directories holding the plan files written to --out-dir.
The config written by render --write, which holds the resolved values of inputs, locals, and dependency outputs.Terragrunt now creates those files as 0600 and those directories as 0700.
hcl fmt --stdin honors --check and --diff
terragrunt hcl fmt --stdin ignored --check and --diff. It printed the reformatted HCL and exited 0 whether or not the input needed formatting.
--check now exits with status code 1 when the input needs formatting, and --diff prints a unified diff labeled old/stdin and new/stdin. Neither flag prints the formatted content, so getting that content back means running --stdin without them.
hcl validate no longer crashes on errors that carry no source location
terragrunt hcl validate crashed while formatting its output when one of the errors it found had no position in the configuration. Terragrunt now prints that error's summary and detail, without a location line.
Fixed the deprecated environment variables for hcl validate
TG_HCLVALIDATE_STRICT_VALIDATE, the deprecated name for --strict, also turned on --show-config-path. --strict only takes effect alongside --inputs, and --show-config-path cannot be combined with --inputs. With that variable set, terragrunt hcl validate --inputs failed with specifying both -show-config-path and -inputs is invalid.
TG_HCLVALIDATE_SHOW_CONFIG_PATH, the deprecated name for --show-config-path, was not recognized at all.
TG_HCLVALIDATE_STRICT_VALIDATE now sets only --strict, and TG_HCLVALIDATE_SHOW_CONFIG_PATH sets --show-config-path. TG_STRICT_VALIDATE, TERRAGRUNT_STRICT_VALIDATE, and TERRAGRUNT_HCLVALIDATE_SHOW_CONFIG_PATH are unchanged.
Fixed panic on invalid if_disabled value with include block
A generate block with an invalid if_disabled value combined with an include block caused a nil pointer panic instead of a descriptive error. Terragrunt now returns an error naming the generate block and the invalid value, consistent with if_exists validation.
OCI sources reject Docker-style :tag suffixes instead of fetching latest
An oci:// source that pinned a version with a Docker-style suffix, like oci://ghcr.io/acme/modules/vpc:1.0.0, silently ignored the suffix and resolved the latest tag, so a run could fetch a different module version than the one pinned. Terragrunt now validates the registry and repository the same way OpenTofu does and rejects such sources with an error that shows the source rewritten in the supported ?tag=/?digest= form, for example oci://ghcr.io/acme/modules/vpc?tag=1.0.0. Repository names that violate the OCI reference grammar are also rejected before any registry is contacted.
Prompts accept a piped answer that has no trailing newline
Piping an answer to a confirmation prompt, as in printf yes | terragrunt run --all destroy, failed with an EOF error because Terragrunt discarded a final answer that ended without a newline. Terragrunt now reads that final answer, and only a prompt that gets no input at all reports EOF.
Provider cache supports signed provider download URLs
When a provider mirror returned a signed download URL, the Provider Cache Server used the entire URL, including its query string, as the archive filename. Long authentication parameters could exceed filesystem filename limits and fail with file name too long.
Terragrunt now derives the archive filename only from the URL path while preserving the query string when downloading it. Signed provider URLs, including archives in nested object paths and relative mirror URLs, now download and cache correctly.
find and list reject a --queue-construct-as value that holds no command
A value made only of shell punctuation, such as terragrunt find --queue-construct-as=';', ended the run with a crash report. A value that quotes an empty command, such as --queue-construct-as='""', was accepted even though it names no command.
find and list now exit with an error that repeats the value you passed and shows what --queue-construct-as expects instead.
render --write picks a default filename without a format flag
terragrunt render --write failed with is a directory unless it was paired with --format or --json. Only those flags set the default filename, so a bare --write had no output path and Terragrunt tried to write to the unit directory itself.
The default now follows the format in use. terragrunt render --write writes terragrunt.rendered.hcl next to the unit configuration, and --json or --format=json writes terragrunt.rendered.json. An explicit --out still takes precedence.
sops_decrypt_file now uses the credentials your auth provider supplies
When a run obtained credentials from --auth-provider-cmd, sops_decrypt_file ignored them for any variable already set in the environment Terragrunt started with. The rest of the run honored the auth provider, and correctly overrode any ambient environment variables. OpenTofu/Terraform received those credentials, and so did the AWS calls Terragrunt makes on a unit's behalf, such as get_aws_account_id.
Decryption now runs as the identity Terragrunt resolved for the unit, the same one the rest of the run uses, regardless of ambient environment variables.
info strict list <name> now honors --all
Passing a control name to info strict list shows that control's subcontrols. Unlike the top-level listing, it ignored the --all flag and always included completed subcontrols.
Terragrunt now applies the same rule when you name a control.
String inputs reach modules with ${...} intact
Passing a string input that contains ${...} to a variable declared with a type other than string used to fail with Variables not allowed, because OpenTofu/Terraform parse those values as HCL expressions and read ${...} as an interpolation. Reading a JSON or YAML file into an input hit this whenever the file happened to contain that sequence:
inputs = { config = file("./config.json") }Terragrunt now escapes interpolation sequences in string inputs when the module declares the variable with a type that makes the value parse as HCL, so ${...} arrives as literal text instead of failing the run. Variables declared as string, and variables declared with no type at all, are read verbatim by OpenTofu/Terraform, and their values are still passed through untouched.
๐งช Experiments Updated
Read dependency outputs directly from Azure state
The dependency-fetch-output-from-state experiment can now read dependency outputs directly from Azure Storage (azurerm) state, in addition to S3. This avoids initializing the dependency and running tofu output or terraform output.
Azure direct reads require the azure-backend experiment as well. Unsupported configurations requiring native-only authentication, endpoint, timeout, or customer-provided-key behavior continue to use the native output path.
When a dependency has no state yet, Terragrunt uses that dependency block's mock_outputs, as it already does for S3. When Azure direct reads resolve a storage account key through Azure Resource Manager, which is the case unless access_key, sas_token, or use_azuread_auth is set, a resource_group_name, storage_account_name, or subscription_id naming a resource that does not exist fails with an error naming those keys rather than substituting mock outputs.
Read dependency outputs directly from GCS state
The dependency-fetch-output-from-state experiment can now read dependency outputs directly from GCS state, in addition to S3. This avoids initializing the dependency and running tofu output or terraform output.
Unsupported GCS configurations continue to use the native output path. When a dependency has no state yet, Terragrunt uses that dependency block's mock_outputs, as it already does for S3.
Thanks to @joshmyers for the original GCS implementation.
render previews what an expanded dependency block expanded to
With the block-iteration experiment enabled, a dependency block that carries an expansion block now renders as it was written, followed by the elements it expanded into, commented out and with their bodies resolved:
$ terragrunt render --experiment block-iteration dependency "aurora" { expansion { for_each = toset(["web", "api"]) } config_path = "../aurora-${each.key}" } # Expands to: # # dependency "aurora" { # config_path = "../aurora-api" # } # # dependency "aurora" { # config_path = "../aurora-web" # }The elements are comments because they aren't valid Terragrunt HCL configurations (you are not allowed to use the same dependency label twice in Terragrunt configurations), the previews are there to help you understand how expansion will resolve.
โ๏ธ Process Updates
Go bumped to v1.27
The version of Golang used to compile the Terragrunt binary has been updated from v1.26.6 to v1.27.0.
If you build Terragrunt from source, or import it as a Go module, you now need a Go 1.27 toolchain.
OpenTelemetry SDK updated to v1.45.0
Terragrunt's OpenTelemetry tracing and metrics dependencies have been updated from v1.44.0 to v1.45.0. The logging packages and exporters have also been updated to their compatible releases, and Terragrunt now uses the v1.43.0 semantic conventions.
Telemetry behavior is unchanged.
Pull Requests
โจ Features
- feat: Adding interactive scaffold form by @yhakbar in #6615
- feat(azure): End to end Azure CICD by @denis256 in #6574
- feat: Adding bare enabled to unit and stack blocks by @yhakbar in #6714
- feat: Keying stack output addresses by iteration key by @yhakbar in #6715
- feat: Adding render preview for expansion by @yhakbar in #6737
- feat: remote state reading for GCP and Azure by @denis256 in #6710
๐ Bug Fixes
- fix: Strip credentials before local CLI config write by @yhakbar in #6678
- fix: Tightening file permissions for generated files by @yhakbar in #6675
- fix: Reject oci:// sources with docker-style name suffixes instead of resolving latest by @denis256 in #6696
- fix: Escape interpolation in string inputs when type is verified by @yhakbar in #6685
- fix: Fixing local copies when symlinks exist from provider caching by @yhakbar in #6684
- fix(provider-cache): fixed handling arguments in urls by @denis256 in #6680
- fix(cas): strip go-getter depth query parameter before invoking git by @HalisCz in #6513
- fix(cas): use venvtest helper in depth query param tests by @denis256 in #6712
- fix(test): fix for failing test TestNewSignalsForwarderMultipleUnix by @denis256 in #6713
- fix: prevent nil pointer panic on invalid if_disabled by @denis256 in #6718
- fix: Fixing --queue-construct-as resulting in empty tokenization by @yhakbar in #6720
- fix: Fixing render --write when no --format is supplied by @yhakbar in #6724
- fix: Preventing extremely small or large float exponents from crashing Terragrunt by @yhakbar in #6727
- fix: Handling situation when diagnostics contain nil range by @yhakbar in #6729
- fix: Addressing nil Range and Snippet in SourceSnippets by @yhakbar in #6731
- fix: Propagating flag parse errors instead of swallowing them by @yhakbar in #6732
- fix: Use the appropriate absolute path to unit config file, not basename when checking version constraints by @yhakbar in #6728
- fix(security): upgrade Go to 1.27 by @denis256 in #6736
- fix(test): pass config fixture to setupTest by @denis256 in #6738
- fix: Fixing info strict list without --all by @yhakbar in #6725
- fix: Fixing deprecated TG_HCLVALIDATE_STRICT_VALIDATE env var by @yhakbar in #6730
- fix: Fixing hcl fmt with --stdin combined with --check and/or --diff by @yhakbar in #6726
- fix: autoinclude config path fixes by @denis256 in #6711
- fix: Normalize paths using ToSlash to hande old/new prefix appropriately by @yhakbar in #6744
- fix: Fixing tofu/terraform binary selection for run --all usage by @yhakbar in #6753
- fix: Updating render --write file permissions by @yhakbar in #6756
๐๏ธ Performance
- perf: Refactor default --tf-path resolution by @yhakbar in #6651
๐ Documentation
- docs: give each environment its own state backup path in the Terralith guide by @yhakbar in #6683
- docs: serve the Google tag container first-party by @ZachGoldberg in #6699
- docs: proxy CORS-less GTM tags so they load under Partytown by @ZachGoldberg in #6704
- docs: Clean-up for v1.1.4 changelog by @yhakbar in #6747
โ Tests
- test(ci): validate OCI registry authentication by @denis256 in #6662
๐ค CI
- ci: Add weekly security scans by @denis256 in #6691
- ci(coverage): added support for test suppressions in weekly test report by @denis256 in #6752
๐งน Chores
- chore: tests coverage increase by @denis256 in #6668
- chore(deps): update aws-sdk-go-v2 by @denis256 in #6655
- chore: runner pool test coverage by @denis256 in #6647
- chore: A lot more venv plumbing by @yhakbar in #6644
- chore(deps): bump @astrojs/vercel from 11.0.0 to 11.0.3 in /docs by @dependabot[bot] in #6658
- chore: docs sync by @denis256 in #6676
- chore: venv plumbing for cloud SDKs by @yhakbar in #6645
- chore: Plumbing venv into cloud getters by @yhakbar in #6650
- chore(deps): update OpenTelemetry SDK to v1.45.0 by @denis256 in #6686
- chore: Resolve env var defined flags from venv by @yhakbar in #6652
- chore: Increasing discovery boundary test coverage by @yhakbar in #6671
- chore: Wire expansion into dependency parse by @yhakbar in #6679
- chore: Virtualizing util.file.go functions by @yhakbar in #6653
- chore: Upgrading go to 1.26.6 by @yhakbar in #6697
- chore: Nesting the dependency cty map by iteration key by @yhakbar in #6689
- chore(deps): bump github.com/moby/go-archive from 0.2.0 to 0.3.0 by @dependabot[bot] in #6705
- chore: Increasing venv coverage further by @yhakbar in #6677
- chore: Adding integration coverage for expanded dependencies by @yhakbar in #6693
- chore: Use local catalog for TestCatalogWithLocalDefaultTemplate by @yhakbar in #6700
- chore: Updating TestNewSignalsForwarderMultipleUnix to actually check for the signal by @yhakbar in #6701
- chore: Use an injectable cap in TestPartialEval_DeeplyNestedExpressionReturnsTypedError by @yhakbar in #6702
- chore: Moving the TestDiscovery_GraphConcurrentConfigAccessWithRacing in-memory by @yhakbar in #6703
- chore: Wiring expansion into the unit and stack parse by @yhakbar in #6694
- chore: Completing venv abstraction by @yhakbar in #6698
- chore: addressing PR #6736 comemtns by @denis256 in #6741
- chore: Adding sandboxed unit tests in CI by @yhakbar in #6742
- chore: Isolate TestDependencyOutputSkipDependencyOutputsFlag fixtures by @yhakbar in #6740
- chore: Preventing flakes from TestNewSignalsForwarderMultipleUnix by @yhakbar in #6750
- chore: Adding FS sandboxed unit tests in CI by @yhakbar in #6754
- chore: Running go fix ./... by @yhakbar in #6758
- Aug 13, 2026
- Date parsed from source:Aug 13, 2026
- First seen by Releasebot:Aug 13, 2026
v1.1.3
Terragrunt ships a broad release with major bug fixes, new experiments, and smoother workflows. It improves dependency mocks, scaffold behavior, provider caching, filtering, and hooks, while adding browse-tui, bounded discovery, mutable generate output, and OCI source support.
๐ Bug Fixes
Fixed Unsupported attribute errors for values.* inputs that autoinclude overrides
A unit input referencing a values.* key that the unit's values file doesn't define no longer fails with Unsupported attribute when an autoinclude block supplies that input. The autoinclude value is applied as intended.
# stacks/terragrunt.stack.hcl unit "subnet" { source = "../units/subnet" path = "subnet" autoinclude { dependency "vpc" { config_path = unit.vpc.path mock_outputs = { vpc_id = "mock" } } inputs = { vpc_id = dependency.vpc.outputs.vpc_id } } values = { cidr_block = "10.0.0.0/24" } } # units/subnet/terragrunt.hcl inputs = { vpc_id = values.vpc_id # supplied by autoinclude, not the values file cidr_block = values.cidr_block # still resolves from values file }Fixed overwrite_terragrunt and remove_terragrunt on files with no trailing newline
generate blocks using if_exists = "overwrite_terragrunt" or if_disabled = "remove_terragrunt" failed to properly handle existing files when the file at the target path had no newline after its first line, empty files included.
Terragrunt now properly handles files like this, so a file carrying the Terragrunt signature is overwritten or removed as configured, and a file without it produces the usual error naming the path Terragrunt would not touch.
Dependency mock_outputs apply when the state bucket doesn't exist yet
When reading a dependency's outputs directly from remote state (--dependency-fetch-output-from-state), Terragrunt fell back to mock_outputs only when the state object was missing, not when the S3 bucket itself didn't exist. A dependency on an environment that hadn't been bootstrapped yet would fail instead of using its mocks.
A missing bucket is now treated the same as a missing state object, so commands like plan and validate can resolve mocks before the dependency's backend has been created.
Source permissions preserved on hidden directories copied by include_in_copy
With the fast-copy strict control enabled, a hidden directory that Terragrunt copied due to include_in_copy matching something within it took the permissions of the first file generated within it, instead of the permissions it had in the source.
Those directories now keep their source permissions, matching the copy Terragrunt performs with the control disabled.
Applied the positive half of a filter that begins with a negation
When a --filter query began with a negation, Terragrunt treated the whole query as an exclusion. The expressions chained after the negation stopped restricting the selection and only narrowed what got subtracted, so components matching none of them came back in the results. Those expressions are now applied.
$ terragrunt list bar baz foo $ terragrunt list --filter '!name=foo | name=bar' bar baz foo $ terragrunt list --filter '!name=foo | name=bar' barThis follows the left-to-right refinement that | has everywhere else: each expression narrows what the one before it selected. A query is only treated as an exclusion when every one of its expressions is negated, such as '!name=foo' or '!name=foo | !name=bar'.
See Combining Expressions for how negation, intersection and union interact.
Fixed a race condition that left cached provider archives in the working directory
With the provider cache server enabled via --provider-cache, a race let the server start responding to requests before it had finished preparing the directories it caches into. A provider requested in that window had its archive and lock file written relative to the working directory instead of into the cache, leaving zip files behind in your project.
That race condition has been fixed. Providers now always download into the cache directory.
Fixed a race condition between concurrent Terragrunt runs downloading providers
A race condition in the logic used to synchronize provider downloads meant that two Terragrunt runs on the same machine could interfere with each other while caching the same provider. Each run staged its downloads at the same path, so a run that finished first could delete an archive another run was still unpacking, failing that run with failed to open zip archive.
That race condition is now fixed. Two runs can cache the same provider at the same time.
Fixed space-delimited flag values in providers lock
The space-delimited form, providers lock -platform linux_amd64, now reaches OpenTofu and Terraform intact. Previously it was the attached form, -platform=linux_amd64, that worked: given the value as a separate argument, Terragrunt moved it to the end of the command, where it was read as a provider address and the run failed with Invalid provider type "linux_amd64".
-fs-mirror and -net-mirror were moved the same way, and now keep their values too.
With --provider-cache enabled, platforms are also split correctly across the per-platform providers lock runs used to warm the cache.
Fixed scaffold on units and stacks
terragrunt scaffold read every source as an OpenTofu/Terraform module. Given a unit or a stack, which are Terragrunt configurations rather than OpenTofu/Terraform modules, it exited successfully having written an invalid terragrunt.hcl file.
Units and stacks are now scaffolded the way the Catalog TUI scaffolds them: their files are copied into the working directory for you to edit in place, along with a terragrunt.values.hcl listing every values.* reference the configuration makes.
terragrunt scaffold 'github.com/gruntwork-io/terragrunt-scale-catalog//units/aws/oidc/iam-oidc-role'Copying refuses to overwrite: a file that would land on an existing path stops the command before anything is written. Modules and templates are unaffected and are still scaffolded from their variables.
See Scaffold for what gets copied and how the values file is filled in.
Answered every prompt when input is piped in
A run that asks for confirmation more than once, such as terragrunt backend delete prompting for both the lock table entry and the state object, used to read only the first answer when the answers were piped in rather than typed. The remaining answers were discarded while reading ahead, and the next prompt failed with an end-of-input error. Every prompt in a run now reads from the same input, so piping yes for each one works.
Stack dependencies honor mock_outputs with --dependency-fetch-output-from-state
A dependency block that reads outputs from a stack (its config_path points at a terragrunt.stack.hcl directory) used to fail when a unit in that stack had no state yet, even when the dependency declared mock_outputs. This blocked commands like plan and validate against a stack that hadn't been applied.
Such a dependency now falls back to mock_outputs for the units that have no state yet. In a partially applied stack, applied units resolve to their real outputs while the rest use their mocks.
Mocks for a stack dependency are keyed by unit name, so mock_outputs has to be a map or object. Declaring it as any other type now reports that directly, instead of leaving the units it can't cover out of the stack outputs.
Fixed --config= being ignored by the tflint hook
The built-in tflint hook reads the configuration file out of the arguments you give it, then uses that path for tflint init and for the lint run. It only recognized the space-separated --config spelling, so a hook written as:
before_hook "tflint" { commands = ["plan"] execute = ["tflint", "--config=custom.tflint.hcl"] }was treated as though no configuration file had been named at all. Terragrunt searched the unit directory and its parents for a .tflint.hcl file instead, and either failed with a config-not-found error or ran tflint init against whatever unrelated configuration the search turned up. Terragrunt now recognizes --config , --config=, -c , and -c=.
The hook also builds --var arguments from the unit's inputs and from TF_VAR_ entries in extra_arguments blocks. Those arguments came out in a different order on every run, which made the logged command line, and anything comparing it between runs, needlessly unstable. They are now ordered by variable name.
๐งช Experiments Added
block-iteration experiment reserves the expansion block
The block-iteration experiment has been added as the gate for iterating a dependency, unit, or stack block over a count or for_each, declared through a nested expansion block, along with an enabled attribute on unit and stack blocks.
In this release the flag is reserved only, and enabling it has no behavioral effect. Writing an expansion block without the experiment now reports an error naming the flag, rather than leaving the block to be silently discarded:
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-iterationTrack progress and share feedback in #4504.
bounded-discovery โ Added a directory boundary for graph traversal
Filter expressions that traverse the dependency graph reach beyond the working directory: dependents (--filter '...{unit}') by walking up to the Git repository root, dependencies (--filter '{unit}...') by following declared paths. Either way, Terragrunt reads and parses every configuration it touches. In monorepos with isolated environments, that traversal can fail or do wasted work reading sibling environments.
Enable the new bounded-discovery experiment to set a boundary for that traversal. The --discovery-boundary flag (env: TG_DISCOVERY_BOUNDARY) replaces the Git repository root as the enclosure for a whole run:
cd environments/staging terragrunt run --all plan --experiment bounded-discovery --filter '...{vpc}' --discovery-boundary .The experiment also unlocks an inline (dir) boundary operand, which bounds a single expression and overrides the flag. It occupies the same slot as a traversal depth, so it bounds discovery by location the way a number bounds it by graph hops:
cd environments/staging terragrunt run --all plan --experiment bounded-discovery --filter '(.)...{vpc}'Any configuration that resolves outside the boundary, whether a dependent or a dependency, is not read, parsed, or returned: find does not list it and run --all does not run it. Configurations inside the boundary are discovered as usual.
The boundary must be an existing directory, and relative paths are resolved against the working directory. Dependent traversal searches upward from the working directory, so filters that use it also need the boundary to be the working directory or one of its parents. Dependency traversal follows declared paths from the units a filter matched, so dependency-only filters accept any directory, including one below the working directory:
# From the repository root, follow app's dependencies but keep them within prod terragrunt find --experiment bounded-discovery --filter '{./prod/app}...' --discovery-boundary ./prodReserving ( and ) for the boundary operand changes how --filter reads those characters everywhere, not only when the experiment is enabled. An expression such as --filter '1...(foo | bar)' previously matched a unit literally named (foo or bar); it is now rejected as a malformed boundary. Wrap a name or path containing parentheses in braces (e.g. --filter '{./weird(name)}') to keep it literal.
browse-tui โ Added an interactive browser for your estate
The new browse-tui experiment adds the terragrunt browse command. With the experiment enabled, terragrunt browse opens a three-column Terminal User Interface (TUI) browser of your infrastructure estate: the parent directory on the left, the current directory in the middle, and a detail pane on the right showing metadata for the highlighted unit, stack, or directory. The browser opens immediately and fills in metadata as discovery completes in the background.
Enable it with --experiment browse-tui or TG_EXPERIMENT=browse-tui. See the experiment documentation for the keybindings, search, and the criteria for stabilization.
mutable-generate โ Deduplicated generate block output
The mutable-generate experiment has been added. With it enabled, the contents a generate block produces are stored in the Content Addressable Store (CAS), and the file written at path is a read-only link to that stored copy rather than a file of its own.
Since the stored copy is addressed by the hash of its contents, anything generating identical contents links to the same copy. A generate block inherited by several hundred units therefore costs one copy in .terragrunt-cache rather than several hundred.
The link is read-only because that copy is shared. Where a generated file does need to be edited in place, a new mutable attribute on the generate block gives it a writable file of its own:
generate "provider" { path = "provider.tf" if_exists = "overwrite" mutable = true contents = "..." }Setting mutable without the experiment enabled is an error, since earlier Terragrunt versions reject the attribute. The CAS is required, so --no-cas writes generated files directly and mutable has no effect.
For details, see the experiment documentation.
optional-dependency-outputs โ Added --no-dependency-outputs flag to skip dependency output resolution
Added a --no-dependency-outputs flag that skips all dependency output resolution globally, mirroring the existing skip_outputs = true attribute on individual dependency blocks.
The feature is gated behind the optional-dependency-outputs experiment:
TG_EXPERIMENT=optional-dependency-outputs terragrunt run --no-dependency-outputs -- initUsing --no-dependency-outputs without enabling the optional-dependency-outputs experiment will return an error.
Thanks to @pjrm for contributing this feature!
๐งช Experiments Updated
catalog-format โ Added reading the catalog as JSON Lines
The catalog command draws a terminal user interface, and refuses to start where there is no terminal to draw it on. With the catalog-format experiment enabled, --format=jsonl writes the same discovery to standard output instead, as one JSON object per line:
terragrunt catalog --experiment=catalog-format --format=jsonl | jq -c '{kind, title, component_source}'Entries are written as they are discovered rather than collected first, so output is readable while the remaining repositories are still loading, and a reader that stops early ends the command quietly:
terragrunt catalog --experiment=catalog-format --format=jsonl | head -5Note
Closing the pipeIn this example, the head program exits after reading in five lines, and Terragrunt detects the SIGPIPE signal from the OS, and shuts down cleanly.
Entries appear in discovery order, which interleaves the repositories being loaded and differs between runs. Every entry carries the complete body of the component's README in the doc field. Combine usage of Terragrunt with other tools like jq to drop it.
terragrunt catalog --experiment=catalog-format --format=jsonl | jq -c 'del(.doc)'Entries follow a published JSON schema. For the fields and their meanings, see Non-interactive catalog.
--format=tui is the default, and leaves the terminal user interface exactly as it was.
catalog-format โ Added reading the catalog as Markdown
The catalog-format experiment gains a second non-interactive format. Where --format=jsonl writes a record per catalog entry for a program to parse, --format=md writes one Markdown document for a person or an agent to read:
terragrunt catalog --experiment=catalog-format --format=md > catalog.mdEach entry becomes a section holding the metadata the catalog user interface shows for it, the source the component is scaffolded from, and the component's README. Sections are written as entries are discovered, so the document is readable while the remaining repositories are still loading.
READMEs are reproduced inside fenced blocks, so the headings one carries are not read as sections of the catalog document. The document closes with a table naming every component it holds and a count of what was discovered, which is how a reader tells a complete document from one that was cut short by a consumer that stopped reading.
For the fields each section carries, see Non-interactive catalog.
oci โ Added OCI sources for stack units and stacks
terragrunt.stack.hcl now accepts oci:// sources in unit and stack blocks, so a stack can pull its components straight from an OCI registry. Without the oci experiment enabled, such a source fails with a clear error instead of an unsupported-scheme failure.
oci โ Added OpenTofu CLI-config credentials for OCI module sources
oci:// module downloads now read OpenTofu's CLI-config credentials, so one configuration serves both OpenTofu and Terragrunt.
Terragrunt honors the oci_credentials "[/]" blocks (username and password, OAuth tokens, or a docker_credentials_helper, which like tofu may only be set on a whole registry) and the oci_default_credentials fallback helper. A TF_CLI_CONFIG_FILE or TERRAFORM_CONFIG value selects the config file outright; otherwise Terragrunt reads the first of ~/.tofurc and ~/.terraformrc that exists, and merges the *.tfrc and *.tfrc.json files in OpenTofu's config directory.
Terragrunt picks the most specific matching source across CLI config and ambient Docker config; an explicit CLI-config entry wins when both match equally. Set discover_ambient_credentials = false in the oci_default_credentials block to use CLI config only.
โ๏ธ Process Updates
Go bumped to v1.26.5
The version of Golang used to compile the Terragrunt binary has been updated from v1.26.0 to v1.26.5.
Thanks to @apoiget for contributing this upgrade!
Pull Requests
โจ Features
- feat: Adding graph boundary via () syntax by @yhakbar in #6365
- feat: Adding --discovery-boundary flag by @yhakbar in #6355
- feat(getter): OpenTofu CLI-config credentials for oci:// sources by @denis256 in #6531
- feat: Adding browse by @yhakbar in #6219
- feat: Adding mutable attribute to the generate block by @yhakbar in #6563
- feat: Adding md format for catalog by @yhakbar in #6608
- feat: Add --skip-dependency-outputs flag to skip dependency output resolution by @pjrm in #6422
๐ Bug Fixes
- fix(providercache): log -lockfile=readonly skip at debug level by @bryanhorstmann in #6577
- fix: Fixing handling of EOF in generate blocks by @yhakbar in #6592
- fix: Fixing the --config= form of flags used in the tflint hook by @yhakbar in #6591
- fix: Fixing fast-copy ancestor directory permissions by @yhakbar in #6593
- fix: Addressing providers lock -platform usage with space delimited values by @yhakbar in #6597
- fix: Fixing bug with negation | positive expression in the same query. by @yhakbar in #6598
- fix: Fixing provider cache server archive dir race by @yhakbar in #6620
- fix: Fixing scaffold on units and stacks by @yhakbar in #6607
- fix: Addressing feedback from #6565 and #6605 by @yhakbar in #6628
- fix: autoinclude values override for inputs by @denis256 in #6626
- fix: Fixing md format catalog escaping by @yhakbar in #6638
- fix: Plumbing through evalCtx for discovery boundary by @yhakbar in #6632
- fix: Fixing stack dependency mock outputs by @yhakbar in #6530
- fix: Fixing issue where dependency mock outputs aren't used when bootstrapping hasn't run yet. by @yhakbar in #6534
๐๏ธ Performance
- perf: Reducing allocations in tree parse by @yhakbar in #6648
๐ Documentation
- docs: Add call out for terragrunt scale in quick start by @yhakbar in #6583
- docs: document oci module sources, authentication, and caching by @denis256 in #6636
- docs: Cleaning up changelog for v1.1.3 by @yhakbar in #6669
- docs: Cleaning up experiment docs by @yhakbar in #6627
- docs: address review feedback on the oci and autoinclude docs by @denis256 in #6643
โ Tests
- test(getter): integration tests against a local OCI distribution registry by @denis256 in #6614
- test: prove oci module portability between tofu and terragrunt by @denis256 in #6629
- test(git): add unit coverage for internal/git command wrappers and parsers by @denis256 in #6661
๐งน Chores
- chore: Pin exact provider versions for terralith to terragrunt guide by @yhakbar in #6578
- chore: Using vfs handle for ParseFromFile by @yhakbar in #6561
- chore: Walk in discovery with vfs by @yhakbar in #6564
- chore: Registring catalog-format experiment by @yhakbar in #6582
- chore(deps): update AWS, Azure, GCP SDKs by @denis256 in #6590
- chore: Continuing clean-up of go test ./... on a fresh clone of the repo by @yhakbar in #6553
- chore: Fixing usage of deprecated aws sdk by @yhakbar in #6600
- chore: Cleaning up profile tests per feedback in #6553 by @yhakbar in #6599
- chore: Clean-up by @yhakbar in #6584
- chore: Addressing feedback from #6365 and #6355 by @yhakbar in #6603
- chore: Register the block-iteration experiment by @yhakbar in #6562
- chore: address review feedback from #6531 by @denis256 in #6609
- chore: Addressing flake in TestCatalogJSONLFormatCleansUpOnEarlyExit by @yhakbar in #6613
- chore: updated TestDiscovery_GraphConcurrentConfigAccessWithRacing to use VFS by @denis256 in #6622
- chore: Adding expansion detection and internal expansion logic by @yhakbar in #6565
- chore: Adding expansion blocks to the configs that accept expansion by @yhakbar in #6605
- chore: Threading venv through getters and hcl fmt by @yhakbar in #6621
- chore: Addressing feedback from #6621 by @yhakbar in #6633
- chore: Fixing experiment tag in sidebar by @yhakbar in #6635
- chore: Updating mem exec so that it fails closed by @yhakbar in #6634
- chore: Gate real hg usage test behind the exec build flag by @yhakbar in #6637
- chore: Replacing aws provider with null provider in init-cache fixture by @yhakbar in #6639
- chore: Cleaning up NewParsingContext constructor by passing in venv as a param by @yhakbar in #6630
- chore: Addressing lint finding by @yhakbar in #6649
- chore: Refactoring markdown deps into internal/md by @yhakbar in #6640
- chore: Adding unit tests for internal packages by @denis256 in #6660
- chore: Bumping Go to 1.26.5 (#6664) by @apoiget in #6666
- chore: Dropping stale tree parse test case by @yhakbar in #6672
All of your release notes in one feed
Join Releasebot and get updates from Gruntwork and hundreds of other software products.
- Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 13, 2026
modules/teststructure/v2.0.0-beta.2
Terratest ships v2 lockstep release v2.0.0-beta.2.
v2 lockstep release v2.0.0-beta.2
Original source - Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 13, 2026
modules/terragrunt/v2.0.0-beta.2
Terratest ships the v2.0.0-beta.2 lockstep release.
v2 lockstep release v2.0.0-beta.2
Original source - Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 13, 2026
modules/terraform/v2.0.0-beta.2
Terratest ships v2 lockstep release v2.0.0-beta.2.
v2 lockstep release v2.0.0-beta.2
Original source Similar to Gruntwork with recent updates:
- Google release notes2054 release notes ยท Latest Sep 11, 2026
- Semrush release notes32 release notes ยท Latest Jun 17, 2026
- Asana release notes17 release notes ยท Latest Feb 1, 2026
- Anthropic release notes809 release notes ยท Latest Sep 12, 2026
- Anydesk release notes89 release notes ยท Latest Aug 17, 2026
- Atlassian release notes241 release notes ยท Latest Sep 10, 2026
- Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 13, 2026
modules/ssh/v2.0.0-beta.2
Terratest ships v2 lockstep release v2.0.0-beta.2.
v2 lockstep release v2.0.0-beta.2
Original source - Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 13, 2026
modules/packer/v2.0.0-beta.2
Terratest ships v2 lockstep release v2.0.0-beta.2.
v2 lockstep release v2.0.0-beta.2
Original source - Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 13, 2026
modules/opa/v2.0.0-beta.2
Terratest releases v2 lockstep beta 2.
v2 lockstep release v2.0.0-beta.2
Original source - Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 13, 2026
modules/k8s/v2.0.0-beta.2
Terratest ships v2 lockstep release v2.0.0-beta.2.
v2 lockstep release v2.0.0-beta.2
Original source - Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 13, 2026
modules/httphelper/v2.0.0-beta.2
Terratest ships v2 lockstep release v2.0.0-beta.2.
v2 lockstep release v2.0.0-beta.2
Original source - Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 13, 2026
modules/helm/v2.0.0-beta.2
Terratest releases v2 lockstep release v2.0.0-beta.2.
v2 lockstep release v2.0.0-beta.2
Original source - Aug 10, 2026
- Date parsed from source:Aug 10, 2026
- First seen by Releasebot:Aug 13, 2026
modules/gcp/v2.0.0-beta.2
Terratest releases v2 lockstep release v2.0.0-beta.2
v2 lockstep release v2.0.0-beta.2
Original source - Jul 29, 2026
- Date parsed from source:Jul 29, 2026
- First seen by Releasebot:Jul 30, 2026
v1.1.2
Terragrunt releases faster parent-folder lookups, a new ctrl+d scaffold flow in the catalog README view, and several reliability fixes for roles, local sources, logging, feature defaults, and provider cache downloads. It also adds experimental OpenTelemetry logs, profiling, OCI source support, and Azure remote state management.
โจ New Features
Scaffold straight from the catalog README view with ctrl+d
In the terragrunt catalog TUI, pressing ctrl+d while reading a component's README now scaffolds it immediately, skipping the interactive form. Module and template inputs are written as # TODO placeholders, and unit/stack copies get a fully placeholder terragrunt.values.hcl. The hint bar at the bottom of the README view advertises the new key.
๐๏ธ Performance Improvements
Fewer filesystem checks when resolving find_in_parent_folders()
find_in_parent_folders() walks up from a unit toward the filesystem root, checking each directory for the configuration file it was asked to find. Even when the call named a file, as in find_in_parent_folders("root.hcl"), each directory along the way was also checked for the default configuration filenames. Units sharing a parent chain then repeated every check their siblings had already made.
Terragrunt now checks only the filename the call names, and reuses what it already learned about a directory for the rest of the command. Deeply nested estates benefit most, since every level between a unit and its root configuration used to be re-checked once per unit.
In micro-benchmarks, resolving the root configuration for 100 units nested eight directories deep went from 4.8ms to 0.49ms. Across the benchmarked shapes the lookups run between 7x and 10x faster, and the time saved grows with both the number of units and how deeply they sit below their root configuration.
๐ Bug Fixes
Fixed roles assuming themselves for backend operations
A regression in v1.1.1 broke setups that provide static AWS credentials and configure a role via the iam_role attribute, the --iam-assume-role flag, or TG_IAM_ASSUME_ROLE.
In those setups, Terragrunt assumes the role once at the start of a run, and every later AWS call uses that role session. In v1.1.1, backend operations like bootstrapping the state bucket started performing an extra role assumption of their own. Since the run was already using the role session at that point, the role tried to assume itself, and AWS rejected the call with an AccessDenied error unless the role's trust policy happened to include the role itself.
Backend operations now reuse the role session from the start of the run, as they did before v1.1.1.
This does not affect the assume_role attribute of the remote_state block. Roles configured there are backend-specific and are still assumed on top of the supplied credentials, so the cross-account role assumption should continue to work as expected.
Local sources no longer re-init when uncopied files change
For units with a local source, Terragrunt decides whether the cached copy is stale by hashing the source directory. That hash previously covered every file in the directory, including hidden files and exclude_from_copy matches that are never copied into the cache. Creating or touching such a file (an editor swap file, a scratch note) changed the hash, forcing a needless re-copy and auto-init on the next run.
The hash now covers only the files a copy would deliver, honoring the default hidden-file rule along with include_in_copy and exclude_from_copy. Files that never reach the cache no longer trigger re-initialization.
Fixed width truncation of colored and multi-byte log content
The width option in a custom log format sizes a column to a fixed number of visible characters. When the content held color codes or multi-byte characters and was longer than the column, truncation cut the raw bytes: it could slice through the middle of a color code, leaving color bleeding into the rest of the line, or split a multi-byte character into invalid output, and it dropped more visible text than the configured width.
width now measures and cuts by visible characters. Color codes are preserved intact, multi-byte characters are never split, and the column keeps exactly the requested number of visible characters.
Provider cache downloads now require a secret URL
The Provider Cache Server now hardens the download endpoint that fetches provider archives on the caller's behalf. That endpoint attaches whatever registry credentials are configured for the upstream host, and it was the only one on the server that did not require the token generated for the run, so any other process on the machine could use a running cache server to pull artifacts from a private registry with the credentials of whoever started the run.
The download URLs handed to OpenTofu and Terraform now carry a secret path segment, generated fresh each time the cache server starts and redacted from the server's own logs. Requests that omit the segment get a 404.
Run report no longer mangles the names of paths that share a prefix with the working directory
When a run's path shared a string prefix with the working directory without being nested under it, the run report shortened its name by shearing off the prefix mid-segment. A working directory of /repo/project alongside a run at /repo/project-staging/unit produced the name -staging/unit.
The report now shortens a path only when it is genuinely nested under the working directory. Sibling paths keep their full name.
Feature flag defaults no longer leak between units in run --all
A feature block's default was recorded once per run and shared by every unit. During run --all, the first unit to be parsed set the value for a flag name, so a unit defining default = false could evaluate feature.toggle.value as true because a sibling unit was parsed first. Which unit won depended on parsing order, making the result vary between runs.
Defaults are now resolved per unit, including defaults inherited through include. Overrides passed with --feature or TG_FEATURE continue to apply to every unit in the run.
Thanks to @dhotcolorado for reporting and fixing this!
Fixed S3 source downloads under EKS Pod Identity
Downloading unit sources from private S3 buckets (s3::https://...) now works when EKS Pod Identity is the only credential source. Previously, the bundled aws-sdk-go v1 rejected the Pod Identity Agent endpoint (169.254.170.23) because it only allowed loopback hosts. Terragrunt now uses aws-sdk-go v1.55.6, which allows the EKS and ECS container credential endpoints.
๐งช Experiments Added
otel-logs experiment exports logs to OpenTelemetry
Terragrunt previously emitted only traces and metrics, so there was no way to ship its log output to an OpenTelemetry backend or correlate log lines with the spans of a failed run.
Enable the new otel-logs experiment to add an OpenTelemetry logs signal, configured 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.
TG_TELEMETRY_LOGS_EXPORTER=otlpHttp terragrunt run --all --experiment otel-logs -- applyThe OTLP exporters read the endpoint from the standard OTEL_EXPORTER_OTLP_ENDPOINT environment variable. Set TG_TELEMETRY_LOGS_EXPORTER_INSECURE_ENDPOINT=true to disable TLS when collecting locally. Records emitted while a span is active carry its trace and span IDs, so a failed unit's logs link to its span in the backend. Without the experiment enabled, the logs exporter stays inert regardless of TG_TELEMETRY_LOGS_EXPORTER.
profiling experiment adds pprof collection for Terragrunt runs
Enable the new profiling experiment to collect CPU profiles, memory (heap) profiles, and goroutine profiles (stack traces of all goroutines) using CLI flags. Profiling is intended for debugging the performance of Terragrunt itself, and for exploring ways to optimize Terragrunt as an application; it will not help with improving the performance of the infrastructure Terragrunt manages.
Example:
terragrunt --experiment=profiling --profile-cpu cpu.prof --profile-mem mem.prof --profile-goroutine goroutine.prof run -- planUse --profile-dir to collect all profiles into a single directory with conventional names (terragrunt_cpu.prof, terragrunt_mem.prof, terragrunt_goroutine.prof):
terragrunt --experiment=profiling --profile-dir /tmp/profiles run --all -- planThe same behavior is available via environment variables when the profiling experiment is enabled:
- TG_PROFILE_CPU
- TG_PROFILE_MEM
- TG_PROFILE_GOROUTINE
- TG_PROFILE_DIR
When using --profile-dir or TG_PROFILE_DIR, Terragrunt also sets TOFU_CPU_PROFILE for each unit so downstream OpenTofu processes (OpenTofu 1.11 or later) write their own CPU profiles into unit-specific subdirectories. An explicitly set TOFU_CPU_PROFILE is never overridden.
๐งช Experiments Updated
azure-backend now manages Azure Storage remote state
The azure-backend experiment now enables functional Terragrunt support for the Azure Storage (azurerm) remote-state backend.
When the experiment is enabled, Terragrunt can bootstrap the resource group, storage account, and blob container used by remote_state { backend = "azurerm" }, detect whether the backend needs bootstrapping, converge blob versioning and soft-delete settings, delete state blobs or containers, and migrate state blobs within the same storage account.
Terragrunt-only settings such as location, the storage account SKU options, the skip_* flags, enable_soft_delete, soft_delete_retention_days, and msi_resource_id are consumed by Terragrunt and removed before it runs OpenTofu/Terraform with init -backend-config, so the underlying azurerm backend receives only keys it understands. msi_resource_id is not bootstrap-only: it also selects the managed identity used for delete and migrate.
This remains opt-in while the experiment is active:
terragrunt --experiment azure-backend run -- planThanks to @omattsson for driving this support forward.
oci - Credential helpers for OCI module sources
oci:// module downloads now use the Docker credential helpers you already have configured, so registries like Amazon ECR authenticate automatically with no extra setup.
oci - Content-addressable caching for OCI module sources
oci:// module sources now integrate with Content Addressable Storage. When the oci experiment is enabled, downloads are cached by their manifest digest, so a repeated fetch of the same tag or digest is served from the local store instead of re-downloaded from the registry.
Mutable tags stay correct: every fetch re-resolves the tag to its current manifest digest at download time, so re-pushing a module under the same tag invalidates the cache and pulls the new content rather than serving a stale copy. A digest-pinned source (?digest=sha256:...) skips registry resolution and keys the cache directly.
oci - Downloading modules from OCI registries
The oci experiment now downloads source code (including OpenTofu modules) from OCI Distribution registries. When enabled, Terragrunt accepts oci:// source URLs in Terragrunt configurations (including terraform.source attributes). Specify either tag or digest; omitting both selects the latest tag. //subdir selectors are supported. Artifacts follow the same publishing contract OpenTofu 1.10 consumes natively.
Authentication covers static credentials via interim TG_TMP_OCI_* environment variables and read-only ambient discovery of Docker and containers auth files. Static credentials can be limited to one registry with TG_TMP_OCI_REGISTRY; without it, the configured token or username and password may be offered to any registry the process contacts. Credential helpers (such as ecr-login) are not invoked yet, so registries that need per-run token minting only work while an externally obtained login is present in an ambient file.
When the experiment is disabled, oci:// sources remain unsupported.
For setup steps, see the experiment documentation.
Pull Requests
โจ Features
feat(getter): implement OCIGetter.Get with fake-store unit tests by @denis256 in #6479
feat: Add otel-logs experiment by @yhakbar in #6279
feat(getter): add static and ambient OCI credential discovery by @denis256 in #6483
feat(getter): add WithOCI and gate oci sources behind the oci experiment by @denis256 in #6486
feat(getter): add OCI digest CAS resolver with tag re-resolution by @denis256 in #6503
feat: Adding earlier catalog bail by @yhakbar in #6493
feat(profiling): add automatic pprof collection by @denis256 in #5711
feat(getter): credential helpers for oci:// module sources by @denis256 in #6508
feat: add experimental azurerm remote state backend by @denis256 in #6428๐ Bug Fixes
fix: Fixing docs TF_TOKEN_* rendering by @yhakbar in #6509
fix: Preventing spurious re-inits by @yhakbar in #6504
fix: Fixing log truncation by @yhakbar in #6526
fix: support EKS Pod Identity for S3 source downloads by @denis256 in #6532
fix: Isolate feature defaults per unit in run --all by @dhotcolorado in #5995
fix: Adding random URL segment to download URI by @yhakbar in #6547
fix: Fixing report path prefix trim by @yhakbar in #6527
fix: Fixing self-chained role assumption by @yhakbar in #6521
fix: prevent auto-init env vars from leaking into main command by @yapret in #6576๐๏ธ Performance
perf: Memoize find_in_parent_folders() by @yhakbar in #6545
๐ Documentation
docs: Adding CLI flag precedence rule by @yhakbar in #6524
docs: Adding changelog entry for #5995 by @yhakbar in #6548
docs: Re-organizing content related to the run queue out of stack documentation by @yhakbar in #6114
docs: Adding search telemetry by @yhakbar in #6555
docs: Improving docs by addressing frequently asked questions by @yhakbar in #6560๐งน Chores
chore: Log Windows console mode retrieval failures at debug level (#6374) by @AgustinSabalza in #6376
Original source
chore: Fixing code fences on /reference/hcl/blocks/ by @yhakbar in #6485
chore: Avoid package-level module resolution for version attribute by @yhakbar in #6482
chore: AWS dependencies bump by @denis256 in #6502
chore: Running fd -tf -e go -x golines -w to avoid run-on lines by @yhakbar in #6484
chore: Adding some integration testing for the version attribute by @yhakbar in #6487
chore: Unify Venv struct by dropping cas.Venv by @yhakbar in #6488
chore: Adding vsops by @yhakbar in #6506
chore: speed up slowest tests with unit-level coverage and hermetic fixtures by @denis256 in #6436
chore: lint fixes by @denis256 in #6518
chore(deps): bump astro from 7.0.4 to 7.1.0 in /docs by @dependabot[bot] in #6515
chore: Fixing panic in Windows test by @yhakbar in #6536
chore: Update grpc, x/mod, go-shellwords deps by @denis256 in #6543
chore: Adding more tests for build metadata by @yhakbar in #6538
chore: Adding vhttp client to abstract away HTTP client connections by @yhakbar in #6121
chore: Cleaning up tests for #6547 by @yhakbar in #6549
chore: Refactor for network isolation in tests by @yhakbar in #6507
chore: fixed failed lint tests by @denis256 in #6550
chore: Fixing pprof venv access by @yhakbar in #6556
chore: Updating Kapa integration by @yhakbar in #6558
chore: coverage report fixes by @denis256 in #6557
chore: Reducing race in vexec testing by @yhakbar in #6551 - Jul 21, 2026
- Date parsed from source:Jul 21, 2026
- First seen by Releasebot:Jul 22, 2026
modules/teststructure/v2.0.0-beta.1
Terratest enters v2 beta with test structure updates.
v2 beta teststructure
Original source - Jul 21, 2026
- Date parsed from source:Jul 21, 2026
- First seen by Releasebot:Jul 22, 2026
modules/terragrunt/v2.0.0-beta.1
Terratest adds v2 beta for Terragrunt.
v2 beta terragrunt
Original source
Curated by the Releasebot team
Releasebot is an aggregator of official release notes from hundreds of software vendors and thousands of sources.
Our editorial process involves the manual review and audit of release notes procured with the help of automated systems.