Gruntwork Release Notes
131 release notes curated from 2 sources by the Releasebot Team. Last updated: Jun 11, 2026
Gruntwork Products
- Jun 10, 2026
- Date parsed from source:Jun 10, 2026
- First seen by Releasebot:Jun 11, 2026
v1.0.8
Terragrunt releases a broad update with faster file tracking, sharper error messages, and expanded support across CAS, catalogs, autoinclude, and S3 sources. It also adds new experiments for hooks and telemetry, plus documentation improvements including clean Markdown for every docs page.
ποΈ Performance Improvements
Faster read-file tracking with the mark-many-as-read experiment
With the mark-many-as-read experiment enabled, Terragrunt records every module file it marks as read during parsing. The bookkeeping for that record scaled quadratically: each new path was checked against every path recorded so far, which got expensive for units with large local module sources, and monorepos paid that cost again for every unit and every command.
Recording a path now takes constant time no matter how many paths came before it, and re-marking already-recorded files is cheaper still. The reading lists reported by find and list are unchanged.
π Bug Fixes
assume_role: preserve commas inside list expressions
Terragrunt previously failed to correctly parse assume_role attributes containing list values such as transitive_tag_keys or policy_arns. Commas inside nested list expressions were incorrectly treated as top-level separators, causing generated configurations to fail with parsing errors.
assume_role = { role_arn = "arn:aws:iam::123456789012:role/test-role" transitive_tag_keys = ["Project", "Projects"] }This resulted in errors similar to:
Missing item separator; Expected a comma to mark the beginning of the next item.
Terragrunt now preserves commas inside nested list and object expressions when parsing assume_role blocks, allowing configurations containing array attributes to be processed correctly.
Thanks to @Rahul-Kumar-prog for contributing this fix!
Completed experiments now evaluate as permanently enabled
Features gated behind a completed experiment were treated as disabled instead of permanently enabled, so functionality that graduated out of experiment status could silently stop working.
The one affected code path was hcl validate --inputs with a git filter expression such as --filter '[HEAD~1...HEAD]': after the filter-flag experiment completed, the command stopped preparing git worktrees for the filter. Git filter expressions now work with hcl validate --inputs again, matching find, list, and the other commands that accept filters.
Exposed-include resolution errors now name the include block, file, and failing field
When resolving an include block with expose = true, Terragrunt surfaced low-level parsing or conversion errors with no indication of which include block, file, or field was at fault. This was especially hard to debug for errors that carry no source location, such as:
unsuitable value: a bool is required
The error is now annotated with the include block name, the included (parent) file path, and a single dotted locator for the failing field β the top-level config field (dependency, inputs, locals, or feature) plus the attribute path within it when go-cty can determine one:
exposed include "root" (/path/to/root.hcl): dependency.outputs["enabled"]: unsuitable value: a bool is required
When go-cty cannot resolve a precise attribute path, the locator degrades to just the field name:
exposed include "root" (/path/to/root.hcl): dependency: unsuitable value: a bool is required
Errors that originate in HCL parsing already carry a source range (file:line:column) and are preserved unchanged. This narrows the search from the entire configuration tree to a specific file and field.
Intersecting a graph traversal with another filter no longer drops the traversed components
A graph traversal combined with an intersected filter dropped the components reached in discovery.
e.g., ...a-dependent | type=unit (the dependents of a-dependent, intersected with type of units) returned only a-dependent itself instead of its dependents, and git-change traversals such as ...[HEAD~1...HEAD] | type=unit lost the dependents of the changed units.
A component that matched both a graph expression target and a positive filesystem or git filter was classified as discovered before the graph traversal ran, so the traversal never expanded from it. Terragrunt now checks graph expression targets first, so intersecting a traversal with another filter keeps the dependencies and dependents it reaches.
generate blocks now honor hcl_fmt
Terragrunt now accepts hcl_fmt on generate blocks and preserves the setting when configurations are parsed, written, and parsed again. This lets generated .tf, .hcl, and .tofu files opt out of automatic HCL formatting by setting hcl_fmt = false, matching the existing generate = { ... } attribute-map behavior.
Telemetry resource now honors OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES
Terragrunt previously hardcoded the service.name resource attribute to terragrunt for every emitted trace and metric, ignoring the standard OpenTelemetry environment variables. Multiple Terragrunt invocations could not be distinguished in an OpenTelemetry backend without an intermediate collector to rewrite the attribute.
The resource is now composed via resource.New with WithFromEnv() placed after Terragrunt's defaults, so OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES are honored on every span and metric. Per the OpenTelemetry specification, OTEL_SERVICE_NAME takes precedence over a service.name entry in OTEL_RESOURCE_ATTRIBUTES. The default service.name remains terragrunt when neither variable is set.
s3:: sources: support virtual-hosted-style URLs
s3:: source URLs using the virtual-hosted-style S3 endpoint format were rejected:
terraform { source = "s3::https://my-bucket.s3.us-west-2.amazonaws.com/terraform/modules/myapp.zip" }This resulted in errors like:
ERROR downloading source url s3::https://my-bucket.s3.us-west-2.amazonaws.com/...
- URL is not a valid S3 URL
Terragrunt now accepts every AWS S3 endpoint form, including virtual-hosted-style URLs (<bucket>.s3.<region>.amazonaws.com) and modern path-style URLs (s3.<region>.amazonaws.com).
Windows console mode is restored when Terragrunt exits
On Windows, running a Terragrunt command from Nushell could leave the shell unable to read input afterward, with keystrokes such as the arrow keys appearing as raw escape sequences instead of being interpreted.
While it runs, Terragrunt reconfigures the console it shares with the parent shell so that terminal escape sequences are processed, but it did not put the original mode back when it exited. PowerShell reapplies its own console settings on every prompt and recovers on its own, so the problem surfaces only in shells that keep the inherited mode, such as Nushell. Terragrunt now records the console mode at startup and restores it on exit, returning the shell to the state it was in beforehand.
Reported in #6245.
π Documentation Updates
Clean Markdown is available for every docs page at <url>.md
Every docs page is now served as clean Markdown at the same URL with .md appended. For example, /getting-started/install is also available at /getting-started/install.md.
curl https://docs.terragrunt.com/getting-started/install.mdThe .md version contains the page content without the site navigation or other surrounding HTML, which makes it well suited as context for LLMs and AI tooling: it is smaller and carries only the documentation itself. Coverage includes every page, including the CLI command reference and the changelog.
This complements the existing llms.txt and llms-full.txt files by providing a per-page Markdown source.
π§ͺ Experiments Added
optional-hooks β Add experimental --no-hooks flag support for terragrunt run
The terragrunt run command now supports an experimental --no-hooks flag for disabling hook execution during command runs.
The feature is gated behind the optional-hooks experiment and skips execution of before_hook, after_hook, and error_hook blocks when enabled.
TG_EXPERIMENT=optional-hooks terragrunt run --no-hooks planThis feature is currently experimental because disabling hooks changes Terragrunt execution semantics and may evolve in future releases.
Using --no-hooks without enabling the optional-hooks experiment will return an error.
hook-context-env experiment exposes additional TG_CTX_* env vars to hooks
Enable the new hook-context-env experiment to surface three additional environment variables to every before_hook, after_hook, and error_hook:
TG_CTX_HOOK_TYPE β before_hook, after_hook, or error_hook, identifying which lifecycle phase invoked the hook.
TG_CTX_SOURCE β the resolved terraform source URL (CLI --source override, else evaluated terraform.source with source-map applied, else .).
TG_CTX_TERRAGRUNT_DIR β the directory of the current Terragrunt config.terragrunt run --all --experiment hook-context-env -- applyThese variables make it easier to share a single hook script across lifecycle phases and to access the unit's source and config directory without threading them through hook arguments.
π§ͺ Experiments Updated
cas: fallbacks now emit telemetry
When the cas experiment is enabled and a CAS operation cannot complete, Terragrunt falls back to a slower path (the standard download client, or a temporary clone when the shared git store is unavailable) and keeps going. Until now the only record of a fallback was a warning in the logs, which made it impractical to measure how often CAS degrades across a fleet.
Each fallback now also emits a cas_fallback telemetry event whose reason attribute identifies the cause: init_error, getter_error, git_store_unavailable, probe_failure, or stack_generation_error. Operators collecting OpenTelemetry traces or metrics from Terragrunt can count and alert on these events to judge CAS health before relying on it by default.
CAS flags for the catalog command
The catalog command now accepts the --no-cas and --cas-clone-depth flags, which were already available on run, stack generate, and stack run. When --no-cas is set, catalog repositories are cloned with plain Git even if the cas experiment is enabled. --cas-clone-depth controls the git clone --depth value the CAS uses when cloning catalog repositories.
terragrunt catalog --experiment cas --cas-clone-depth=-1cas β update_source_with_cas requires a literal source string
When a catalog unit, stack, or terraform block set update_source_with_cas = true with a source that was not a literal string, rewriting silently produced a wrong source. Interpolation such as "../units/${local.name}" had the interpolated portion dropped, leaving a bare prefix; a reference such as local.foo resolved to the directory containing the block itself. In both cases stack generation packaged the wrong directory without any error.
Stack generation now fails with an error explaining that update_source_with_cas requires a literal source string. Non-literal expressions, including interpolation, function calls, and references like local.foo, are rejected.
cas β Malformed cas:: references fail with a clear error
A cas:: source with a malformed hash, such as cas::sha1:a, used to fail with an opaque internal error while looking the hash up in the store.
CAS references are now validated up front: the hash must be lowercase hexadecimal with exactly 40 characters for sha1 or 64 for sha256. References that don't match are rejected with an error identifying the bad reference.
cas β Repositories with submodules now clone correctly
Cloning a repository that contains git submodules through the Content Addressable Store failed while ingesting the repository:
git_cat_file: fatal: Not a valid object name <hash>
A submodule appears in the repository tree as a pointer to a commit in another repository, so the object behind it cannot be read from the repository being cloned.
The CAS now fetches each submodule from the URL registered in .gitmodules at its pinned commit and materializes its contents in place, including nested submodules. Relative submodule URLs (such as ../sibling.git) are resolved against the parent repository URL, matching git's behavior. Submodule contents are stored and deduplicated like any other content, so repeated clones reuse the cache.
catalog-redesign β Failures now exit nonzero and name the sources that failed
The redesigned catalog exited with code 0 even when it failed: a session that ended on an unreachable repository, a failed scaffold, or a failed copy reported success in its exit code. Repositories that failed to load during discovery were dropped too: the warning logged for each one was drawn over by the full-screen interface, so a run where every source failed showed the same "No catalog sources were discovered" screen as a run that genuinely found nothing.
The catalog now exits nonzero when the session ends on a failure: a discovery failure that leaves nothing to browse, a failed scaffold, or a failed copy. Quitting a working session still exits 0. When some sources fail to load while others succeed, the catalog stays usable and a clean quit still exits 0; the component list shows how many sources failed, and the failed repositories are printed with their causes after the catalog closes. When every source fails, the error screen lists each failed repository instead of claiming nothing was found, and dismissing it exits nonzero.
Running terragrunt catalog without an interactive terminal, such as in CI, used to fail with a raw error from the underlying TUI library:
bubbletea: error opening TTY: bubbletea: could not open TTY: open /dev/tty: no such device or addressIt now fails immediately with an error stating that the catalog command requires an interactive terminal.
catalog-redesign β Scaffolding a component no longer fails with a path-traversal error
Scaffolding a component from the catalog (pressing s) could fail on macOS while downloading the source:
subdirectory component contain path traversal out of the repositoryThe catalog caches each repository under the system temporary directory, which macOS reports through a symlink (/var/folders/... pointing at /private/var/folders/...). The source location Terragrunt handed to the downloader was built against the unresolved path, so it pointed outside the cached repository and was rejected.
Terragrunt now resolves the temporary directory before discovering components, so the source stays inside the repository and scaffolding proceeds.
stack-dependencies: HCL tooling now handles autoinclude
Two tooling gaps around the experimental autoinclude block are closed:
hcl validate now validates autoinclude blocks. With the stack-dependencies experiment enabled, validating a terragrunt.stack.hcl that declares autoinclude runs the same strict checks as terragrunt stack generate. A malformed block (for example, a locals block inside autoinclude) is now reported at validation time instead of passing hcl validate and only failing later during generation. Without the experiment, validation behavior is unchanged.
read_terragrunt_config() can read stack-level autoinclude files. Reading a generated terragrunt.autoinclude.stack.hcl previously failed because the file was decoded as a unit configuration, which rejects its unit and stack blocks. With the experiment enabled, the file is now decoded as the stack-file fragment it is, returning its unit and stack blocks the same way reading a terragrunt.stack.hcl does. Unit-level terragrunt.autoinclude.hcl files already read correctly and continue to do so.
stack-dependencies: autoinclude merges like a regular include
A generated unit autoinclude (terragrunt.autoinclude.hcl) now merges into the unit's config using the same default merge as a regular include, which is a shallow merge, applied uniformly across generation, full parse, and discovery. Top-level keys from the unit and the autoinclude combine, and on a conflict the autoinclude wins and replaces the unit's value rather than deep-merging nested maps; locals stay local in scope.
A generated stack autoinclude (terragrunt.autoinclude.stack.hcl) injects unit and stack blocks into the generated terragrunt.stack.hcl. An injected block whose name matches an existing unit or stack now overrides that block wholesale, consistent with unit autoinclude override semantics, and an injected block with a new name is added. This applies uniformly across generation, full parse, and discovery, so a name match no longer produces a duplicate-name error. A stack autoinclude may not declare a top-level dependency block (stacks have no dependencies; declare the dependency inside the target unit's own autoinclude).
A dependency block injected through an autoinclude is now available before a unit's remote_state is evaluated, so referencing dependency.<name>.outputs.<key> there no longer fails. remote_state now behaves the same as generate blocks.
stack-dependencies: autoinclude blocks can reference values.*
An autoinclude block may now reference the stack's values.. Previously a values. reference was rejected at stack generate time, except in a dependency config_path. It now resolves to a literal like local.*, unit.<name>.path, and stack.<name>.path, wherever it appears: inputs, generate, remote_state, mock_outputs, and config_path.
Function calls in an autoinclude now resolve at generate time too, in the terragrunt.stack.hcl context, instead of being kept verbatim and evaluated in the generated unit. Only a dependency.* reference (a dependency's outputs) stays verbatim and resolves inside the unit; in a mixed expression the stack-level parts resolve and only the dependency.* reference is kept.
Because functions now evaluate against the stack file rather than the unit, directory and include functions report the stack file's location: get_terragrunt_dir returns the stack file's directory, and path_relative_to_include returns ".". If you relied on these resolving in the unit, move them to the unit's own configuration, or derive a per-unit value such as a remote_state backend key from unit.<name>.path.
A locals block inside an autoinclude remains rejected; declare stack-level locals in terragrunt.stack.hcl instead.
stack-dependencies: stack dependencies resolve values.* in the target stack's locals
Expanding a dependency that points at a generated stack directory no longer fails when that stack's terragrunt.stack.hcl reads values.* in its locals block. Previously, terragrunt stack generate succeeded but terragrunt run --all then failed with There is no variable named "values" while expanding the dependency into its units.
Dependency expansion now reads the generated terragrunt.values.hcl next to each terragrunt.stack.hcl it visits, including nested stacks, so each nesting level resolves values.* from its own values file, the same way a full stack parse does.
stack-dependencies: component path references in values no longer break next to autoinclude blocks
A unit or stack block's values can reference unit.<name>.path and stack.<name>.path even when another block in the same terragrunt.stack.hcl declares an autoinclude. Previously, the presence of any autoinclude block made stack generate reject those references with Unknown variable; There is no variable named "unit", while the same file without an autoinclude generated fine.
Pull Requests
β¨ Features
feat: add hook-context-env experiment by @arnaud-dezandee in #6189
feat: Adding CAS fallback telemetry by @yhakbar in #6298
π Bug Fixes
fix: Fixing filter tests on Windows by @yhakbar in #6247
fix: Fix Windows nushell bug by @yhakbar in #6250
fix(codegen): fix assume_role parsing failure when transitive_tag_keys or policy_arns arrays are present by @Rahul-Kumar-prog in #5975
fix: Fixing scaffold path traversal check by @yhakbar in #6255
fix(telemetry): honor OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES environment variables by @Tensho in #6256
fix: Fixing graph traversal bug with intersected filter by @yhakbar in #6270
fix: resolve locals in autoinclude mock_outputs by @denis256 in #6274
fix: report the offending field in Terragrunt config errors by @denis256 in #6284
fix: Fixing values without autoinclude by @yhakbar in #6290
fix: Fixing values references in locals of terragrunt.stack.hcl files by @yhakbar in #6291
fix: Fixing experiment promotion by @yhakbar in #6293
fix: Adding support for submodules in CAS by @yhakbar in #6294
fix: Validating CAS sources by @yhakbar in #6296
fix: Support autoinclude in hcl validate and fix read_terragrunt_config() for configurations using autoinclude by @yhakbar in #6297
fix: Fixing legacy virtual hosted style S3 URLs by @yhakbar in #6311
fix: Addressing lint findings by @yhakbar in #6312
π Documentation
docs: Documenting CAS Getters by @yhakbar in #6251
docs: Support completedSince by @yhakbar in #6252
docs: Since/Before cleanup by @yhakbar in #6277
docs: Since/Before cleanup workflow by @yhakbar in #6276
docs: Support .md changelog files by @yhakbar in #6286
docs: Adding autoinclude documentation by @yhakbar in #6299
π§Ή Chores
chore: weekly tests reporting by @denis256 in #6191
chore: Add thanks for #5975 by @yhakbar in #6253
chore: autoinclude merge fixes by @denis256 in #6248
chore: cleaned unused code by @denis256 in #6260
chore: Add CodeRabbit release check by @yhakbar in #6278
chore(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 by @dependabot[bot] in #6265
chore(deps): bump docker/setup-docker-action from 5.1.0 to 5.2.0 by @dependabot[bot] in #6266
chore(deps): bump aws-actions/configure-aws-credentials by @dependabot[bot] in #6267
chore: Make autoinclude more flexible, supporting values.* by @yhakbar in #6283
chore: Threading venv through CLI by @yhakbar in #6089
chore: Isolate test git servers by @yhakbar in #6233
chore: Add --no-cas flag to the catalog command by @yhakbar in #6292
chore: Clean up from #6290 by @yhakbar in #6295
chore: Adding DAG view tests by @yhakbar in #6300
chore: Speeding up files read by @yhakbar in #6301
π Other Changes
Make guides collapsed to start by @karlcarstensen in #6262
Fix for light/dark mode by @karlcarstensen in #6264
Collapse reference section by @karlcarstensen in #6263
serve clean Markdown at .md for every page by @karlcarstensen in #6281
Feature/optional hooks experiment by @Rahul-Kumar-prog in #6227
Update to llms.txt. Added curated llms.txt and configured plugin to also serve full and small by @karlcarstensen in #6280
Changelog by @karlcarstensen in #6285
Fix #5054: support hcl_fmt in generate blocks by @DadaVinqi in #6287
fix Fixing catalog exit codes by @yhakbar in #6302
Original source - Jun 1, 2026
- Date parsed from source:Jun 1, 2026
- First seen by Releasebot:Jun 1, 2026
v1.0.7
Terragrunt adds optional versions for tfr:// module sources and expands CAS to cover more remote sources and registry modules. This release also improves stack dependency path handling, fixes Windows filtering and panic cases, and tightens parallelism validation for safer, smoother runs.
β¨ New Features
tfr:// source URLs accept an optional version
The version query parameter on tfr:// source URLs is now optional. When omitted, Terragrunt queries the registry's list-versions endpoint and downloads the latest stable version, matching how OpenTofu and Terraform resolve a module reference that has no version constraint.
terraform { source = "tfr:///terraform-aws-modules/vpc/aws" }Prereleases are excluded from resolution, so a registry that only publishes 4.0.0-rc1 alongside 3.3.0 will pin to 3.3.0. Pin a version explicitly with ?version= when you need reproducible builds or want to opt into a prerelease.
Thanks to @raman1236 for contributing this feature!
π Bug Fixes
update_source_with_cas: preserve //subdir on a unit's terraform.source
When a unit's terraform.source used the // subdir convention (for example, source = "../..//modules/foo") and opted into update_source_with_cas, the rewritten source dropped the //subdir tail and the synthetic tree contained only the leaf module's files. A module that referenced a sibling via a relative path (source = "../bar") could not resolve that reference after materialization.
Rewrites now preserve the original //subdir (for example, cas::sha1:<hash>//modules/foo), and the synthetic tree is rooted at the path before //, so sibling files reachable via relative paths land in the materialized working directory.
Sources without // are unchanged: the tree stays scoped to the leaf module, and the rewritten reference has no //subdir tail.
--filter now detects affected units on Windows
On Windows, terragrunt find --filter '[origin/main...HEAD]' (and its variants) returned no affected units even when git diff reported changed files. The source= and reading= filters were affected by the same problem.
Filter glob patterns are always written with forward slashes, but the affected-unit comparison was being made with Windows backslash separators, so nothing matched. Terragrunt now compares paths consistently with forward slashes on every platform, and the filter detects changed units on Windows as it already did on Linux and macOS.
Reported in #6214.
startswith, endswith, strcontains, and run_cmd no longer panic on malformed calls
Calling startswith, endswith, or strcontains with the wrong number of arguments (for example a single argument instead of two) crashed Terragrunt instead of reporting a configuration error. Calling run_cmd with only option flags and no command (for example run_cmd("--terragrunt-quiet")) crashed the same way.
These calls now return a clear error: a wrong-number-of-parameters error for the string functions, and an empty-command error for run_cmd.
The --parallelism flag no longer accepts non-positive numbers
Previously, terragrunt commands that accept the --parallelism flag (or equivalently the $TG_PARALLELISM environment variable) used to hang indefinitely when invoked with --parallelism=0.
Terragrunt now validates that the value is positive and exits with an error otherwise.
Reported in #6211
π§ͺ Experiments Updated
cas β content-addressing for non-git sources
CAS now covers module sources beyond git: http(s), Amazon S3, Google Cloud Storage, and Mercurial. Repeat runs against an unchanged remote reuse the cached tree instead of downloading the bytes again.
Before fetching, CAS issues a cheap remote probe (an HTTP HEAD, an S3 object-attributes lookup, a GCS metadata read, or hg identify) to derive a cache key without pulling the source. On a hit, the cached tree is linked directly; on a miss, or when the remote exposes no usable signal, CAS downloads the source, ingests it, and keys the resulting tree by its content hash. A remote that publishes a new version under the same address pins to a new entry, so a stale cache cannot serve outdated bytes.
cas β OpenTofu/Terraform registry sources
Module sources of the form tfr://... are now content-addressed in CAS. Repeat runs against the same pinned registry version reuse the cached module instead of re-downloading the archive from the registry.
CAS resolves a tfr:// source by asking the registry where the underlying archive lives and uses that resolved URL as the cache key. Two runs that pin the same version share one entry; a republish under the same version pins to a new entry, so a stale cache cannot serve outdated bytes.
stack-dependencies: unit.<name>.path and stack.<name>.path resolve in values
The stack-dependencies experiment now exposes unit.<name>.path and stack.<name>.path when evaluating the values attribute of a unit or stack block, not only inside autoinclude blocks. A parent stack can pass the generated path of a sibling component down into a child stack, so a unit nested in that child stack can depend on a unit that lives at a different level of the hierarchy.
unit "vpc" { source = "../catalog/units/vpc" path = "vpc" } stack "app" { source = "../catalog/stacks/app" path = "app" values = { vpc_path = unit.vpc.path } }A unit inside the app stack reads values.vpc_path and uses it as the config_path of an autoinclude dependency, wiring the cross-level relationship at generation time. Paths follow the same layout the generator produces, including no_dot_terragrunt_stack on the referenced block.
stack-dependencies: simplified unit.* / stack.* ref shape
The stack-dependencies experiment no longer resolves stack.<name>.<unit_name>.path or stack.<name>.<nested_stack>.path. Only the top-level stack.<name>.path and unit.<name>.path forms remain. stack.<name>.name and unit.<name>.name are gone too; both only ever echoed the label that the reference already had to spell out.
Nested references required parsing every nested catalog up front and conflicted with the reserved name and path attributes on each ref: a nested unit named name or path could not be addressed.
To depend on a generated unit inside a stack, compute the path as ${stack.<name>.path}/<unit-relative-path> directly. The layout under a stack's generated directory follows no_dot_terragrunt_stack on the parent stack and on each unit, so hand-computed paths must mirror that resolution.
stack-dependencies: .terragrunt-stack-origin no longer written
Terragrunt no longer writes the .terragrunt-stack-origin file when generating nested stacks. Set update_source_with_cas = true on your unit and stack blocks if you would like relative paths in your catalog to resolve correctly instead.
Pull Requests
β¨ Features
feat: Make version optional in tfr:// module registry URLs by @yhakbar in #6112
feat: Supporting all getters in CAS by @yhakbar in #6076
π Bug Fixes
fix: Removing use of cas.WithFS by @yhakbar in #6195
fix: panics in startswith / endswith / strcontains / run_cmd by @denis256 in #5984
fix: Allowing all TG HCL fns in terragrunt.stack.hcl, including autoinclude by @yhakbar in #6166
fix: Fixing synthetic trees for terraform.source URLs with // by @yhakbar in #6218
fix: Fixing nested generation for paths with // by @yhakbar in #6234
fix: Fixing stack path variables in values by @yhakbar in #6235
fix: Fixing stack autoinclude by @yhakbar in #6236
fix: Fixing git filters on Windows by @yhakbar in #6242
fix: validate that --parallelism value is positive by @ccmtaylor in #6212
π Documentation
docs: Cleaning up experiment docs by @yhakbar in #6228
docs: Fixing unreleased changelog page by @yhakbar in #6237
docs: Cleaning up changelogs for v1.0.7 by @yhakbar in #6246
π§Ή Chores
chore: Getting rid of fatih/structs dependency by @yhakbar in #6186
chore: Getting rid of go-homedir direct dependency by @yhakbar in #6184
chore: improved coderabbit rules by @denis256 in #6193
chore: Consolidating on lipgloss for color by @yhakbar in #6188
chore: Removing go-errors as a dependency by @yhakbar in #6182
chore: tests simplification by @denis256 in #6208
chore: Adding separate archive field by @yhakbar in #6196
chore: Addressing UI/UX feedback for interactive scaffold in catalog by @yhakbar in #6175
chore: added unknown-unknowns heuristics for coderabbit by @denis256 in #6220
chore: Make clone tests a bit faster by @yhakbar in #6081
chore: stacks dependencies simplificaitons by @denis256 in #6171
chore(deps): bump actions/stale from 10.2.0 to 10.3.0 by @dependabot[bot] in #6201
chore: Fixing gopls workflow by @yhakbar in #6229
chore: Increasing test coverage for stack dependencies by @yhakbar in #6231
chore: Go and GHA dependencies by @denis256 in #6240
chore: Ensuring full support for tfr in CAS by @yhakbar in #6123
chore: Adding no // path test for source with CAS by @yhakbar in #6239
chore: Modernizing using gopls by @yhakbar in #6232
Original source All of your release notes in one feed
Join Releasebot and get updates from Gruntwork and hundreds of other software products.
- May 25, 2026
- Date parsed from source:May 25, 2026
- First seen by Releasebot:May 26, 2026
v1.0.6
Terragrunt ships bug fixes, experiments, and stack improvements, including safer discovery and render handling, an experimental deep_merge HCL function, opt-out auth during discovery, and a more interactive catalog scaffold flow.
π Bug Fixes
terragrunt no longer hangs when download_dir is a non-hidden subdirectory of the unit
Setting download_dir (via the attribute, --download-dir, or TG_DOWNLOAD_DIR) to a subdirectory of the unit's working directory whose name did not start with a dot caused commands that prepare the OpenTofu or Terraform source (apply, plan, run, and similar) to hang.
For example:
# /infra/web/terragrunt.hcl download_dir = "cache" terraform { source = "./mod" }Here terragrunt apply would copy ./mod into cache/, see the new cache/ directory on the next read of the unit, and recurse into it. The default .terragrunt-cache was unaffected because Terragrunt's source-copy step skips any directory whose name starts with a dot.
These configurations now produce an immediate error identifying the source and destination paths.
mark-many-as-read experiment now triggers during discovery
With the mark-many-as-read experiment enabled, a unit whose terraform { source = ... } pointed at a local module did not show up under --filter 'reading=' filters that referenced files inside that module. Discovery would parse the unit, but the module files were never recorded as read, so the reading filter attribute could not match and the queue came back empty.
The module walk now runs on the discovery code path as well, so changes to files in a local module source flow through to the units that depend on them.
terragrunt render no longer crashes on exclude or catalog blocks with certain attributes
Rendering a config crashed with a value has no attribute of that name panic before any output could be produced when:
- the exclude block set no_run, or
- the catalog block set default_template, no_shell, or no_hooks.
These attributes are now carried through the render pipeline alongside the other fields on their respective blocks, so both blocks round-trip cleanly.
terragrunt render no longer crashes on multiple errors.ignore blocks with mismatched signals
Rendering a config that defined more than one errors.ignore block crashed with an inconsistent list element types panic when the signals map was populated on one block and absent (or differently typed) on another. The same crash showed up in dependency-output evaluation, since both paths build the same rendered representation of the config.
Each ignore block is now rendered with a uniform shape. Indexed access (errors.ignore[0]), length, and iteration still work, and the signals map on each block is preserved as written.
Suppress spurious Unknown variable: dependency errors during dependency resolution
terragrunt plan and apply no longer print ERROR Error: Unknown variable "dependency" lines when a unit pulls in a shared include (e.g. via find_in_parent_folders) that references dependency.* outputs. The plans completed correctly, but the error lines cluttered CI logs.
Resolves #6036.
terragrunt stack commands no longer crash on stacks with multiple units
Running terragrunt stack output (or any command that resolves concurrently parsing multiple configuration files) against a stack with several units could intermittently crash while the units were being parsed in parallel due to a race on internal bookkeeping of files read (used in the reading filter attribute).
Parallel unit parsing now coordinates safely when recording which source files were read, preventing crashes.
terraform_binary properly respected when both tofu and terraform are on PATH
A regression in command execution caching resulted in over-caching the STDOUT result of tofu --version when both tofu and terraform were available on PATH and terraform_binary was set. Early on in the execution flow, Terragrunt checks if OpenTofu is installed what its version is to determine if it supports setting of the automatic provider cache directory. This resulted in the value of terraform_binary being ignored for later version checks to assess compliance with terraform_version_constraint.
The version-detection cache used per run is now scoped to the binary that produced each entry, so the version recorded against an early default-binary resolution no longer leaks into the later resolution that honors terraform_binary.
π§ͺ Experiments Added
deep-merge experiment adds a deep_merge HCL function
Enable the new deep-merge experiment to use the deep_merge(map1, map2, ...) HCL function.
deep_merge recursively merges map and object values. Later arguments override earlier arguments for overlapping keys, nested maps are merged recursively, lists are appended, and null arguments are ignored.
This is useful when composing inputs from multiple decoded JSON, YAML, or HCL-derived maps:
locals { config_json_files = sort(fileset(get_terragrunt_dir(), "*.json")) config = deep_merge([ for file in local.config_json_files : jsondecode(file("${get_terragrunt_dir()}/${file}")) ]...) } inputs = local.configCalling deep_merge without enabling the deep-merge experiment returns an error.
opt-out-auth β Opt out of --auth-provider-cmd during discovery
Enable the new opt-out-auth experiment to use --no-discovery-auth-provider-cmd (env: TG_NO_DISCOVERY_AUTH_PROVIDER_CMD), which disables the auth provider command during the discovery phase.
Without the flag, Terragrunt assumes that --auth-provider-cmd must be run per parsed component during the discovery phase so that it can reliably resolve HCL functions such as get_aws_account_id and run_cmd. On large repositories with run --all --filter='reading=', this dominates wall-clock time because the auth command runs for every discovered unit rather than only the subset that will run.
The --no-discovery-auth-provider-cmd flag turns off auth invocations during discovery. The auth provider command still runs normally when running units.
Units whose discovery-relevant blocks depend on credentials produced by --auth-provider-cmd will fail to parse with the flag set. Use it when you know that parsing will resolve successfully without any authentication done beforehand by Terragrunt.
While this flag is experimental, you must also opt-in to the opt-out-auth experiment by setting the TG_EXPERIMENT environment variable to opt-out-auth or by passing the --experiment=opt-out-auth flag to terragrunt run. This flag might experience breaking changes based on community feedback for the duration of the experiment.
e.g.
terragrunt run --all \ --experiment=opt-out-auth \ --no-discovery-auth-provider-cmd \ --queue-include-units-reading=./changed-file.txt \ planπ§ͺ Experiments Updated
catalog-redesign β Interactive scaffold form on s
Pressing s from the catalog list or detail view now opens an in-TUI form that prompts for every variable/value the selected component exposes. The form is modal: in navigate mode j and k (or the arrow keys) move between fields and enter interacts with the focused one. Required entries are flagged, and optional entries show their default in a muted style until the user opts in.
enter on a text or HCL field switches the form into edit mode. Typing edits the value in place; esc returns to navigate. Only fields the user actually changes get written to the generated file, and optional defaults stay implicit, so the result is leaner than the placeholder flow.
enter on a boolean field toggles between [x] true and [ ] false directly, without a separate edit mode.
x on an optional field marks it "use default" again, removing any in-progress value and leaving the source's default to apply.
Complex types (lists, maps, objects) accept raw HCL and are validated before the file is written, so a typo surfaces inline rather than producing a broken terragrunt.hcl or terragrunt.values.hcl file.
ctrl+d finishes the form. Required fields the user never set still write as # TODO: fill in value so the rest of the file is usable.
S (capital) keeps the previous placeholder-only flow, generating the same TODO-laden file as before for users who prefer to populate values by editing the generated file.
stack-dependencies: parser tolerates HCL expressions throughout terragrunt.stack.hcl
The stack-dependencies experiment now defers evaluation of source, path, values, and include.path until each unit or stack block is parsed on its own. As a result, autoinclude resolution during stack generation and run --all discovery no longer fall over when other parts of a stack file use Terragrunt functions, local., or values.. A few adjacent behaviors are tightened up at the same time.
Autoinclude resolves even when sibling units use expressions.
Before 1.0.6, if any unit in a stack file used a function call or a local.* / values.* reference in source, path, or values, generating an autoinclude on a different unit in the same file could fail. The parser now leaves those expressions alone until they're needed, so an unrelated unit can carry an autoinclude block without being blocked by its neighbors:
locals { shared_region = "us-east-1" } unit "account" { source = "${get_terragrunt_dir()}/../catalog/units/account" path = "account" values = { account = values.account region = local.shared_region } } unit "roles" { source = "${get_terragrunt_dir()}/../catalog/units/roles" path = "roles" autoinclude { dependency "account" { config_path = unit.account.path } } }include blocks in terragrunt.stack.hcl accept computed paths.
The path attribute on an include block can be an HCL expression, not just a string literal. An autoinclude block in the included file is resolved normally after the include merges in:
include "shared" { path = find_in_parent_folders("shared.stack.hcl") }What's Changed
- chore: Fixing release bug fix notification by @yhakbar in #6143
- fix: Fixing panic in render WriteTo by @yhakbar in #6144
- fix: Fixing files read race by @yhakbar in #6145
- Implement IndexNow by @karlcarstensen in #6150
- docs: added filtering of compatibility table by @denis256 in #6149
- feat: add deep_merge HCL function as experiment by @EvansM4 in #5535
- chore(deps): bump jdx/mise-action from 4.0.0 to 4.0.1 by @dependabot[bot] in #6153
- chore(deps): bump peter-evans/create-pull-request from 8.1.0 to 8.1.1 by @dependabot[bot] in #6154
- chore(deps): bump DavidAnson/markdownlint-cli2-action from 22.0.0 to 23.2.0 by @dependabot[bot] in #6155
- chore(deps): bump the js-dependencies group across 1 directory with 12 updates by @dependabot[bot] in #6156
- chore: Trimming JS deps by @yhakbar in #6159
- feat: Allow opt-out from auth in discovery by @yhakbar in #6119
- chore: Removing setup-go from Windows signing by @yhakbar in #6158
- chore: stacks dependencies variables by @denis256 in #6072
- chore: google dependencies update by @denis256 in #6161
- docs: Cleaning up changelog for stack dependencies permissive parser by @yhakbar in #6163
- fix: Fixing tf binary version over-caching by @yhakbar in #6148
- chore: Addressing feedback from #6148 by @yhakbar in #6168
- fix: Fixing panic in ignore signal by @yhakbar in #6167
- feat: Add TUI interactivity for catalog scaffold by @yhakbar in #6162
- chore: Plumbing in vfs to getter by @yhakbar in #6070
- fix: Reducing spurious unknown variable dependency errors by @yhakbar in #6060
- chore: Upping strict control test coverage by @yhakbar in #6080
- chore: Increasing virtualization further by @yhakbar in #6084
- docs: Enhance documentation for --out-dir usage by @FernandoArteaga-telus in #6176
- fix: Fixing mark-many-as-read for discovery by @yhakbar in #6174
- chore: Bumping golang deps from #6164 by @yhakbar in #6177
- chore: Clean-up of comments from #6174 by @yhakbar in #6179
- chore: Clean up strict control debug message by @yhakbar in #6178
- chore: Removing go-commons dependency by @yhakbar in #6180
- fix: Fixing download_dir copy infinite recursion by @yhakbar in #6169
- chore: Fixing sops tests by @yhakbar in #6187
New Contributors
- @EvansM4 made their first contribution in #5535
- @FernandoArteaga-telus made their first contribution in #6176
Full Changelog: v1.0.5...v1.0.6
Original source - May 18, 2026
- Date parsed from source:May 18, 2026
- First seen by Releasebot:May 19, 2026
v1.0.5
Terragrunt releases faster stack output, full cross-platform provider lock files, and a broad set of fixes for auth, caching, source handling, and run reporting. It also adds new CAS enhancements, an azure-backend experiment, and better filter and stack-target guidance.
β¨ New Features
Full .terraform.lock.hcl files from the provider cache server
When the provider cache server is used against the OpenTofu provider registry, Terragrunt now writes .terraform.lock.hcl files containing h1: hashes for every platform the registry supports. A single terragrunt init produces a lock file that works on every platform, removing the need to run tofu providers lock -platform=... separately for each target architecture.
provider "registry.opentofu.org/hashicorp/null" { version = "3.2.2" constraints = "3.2.2" hashes = [ "h1:+1mRmfyz6oA00IhrrSkHK3h/Mdh032x2p0F6OMdMo5s=", "h1:FjLTqvaaYo+vHN8pHZB1cOwEGiNzOj+I9kQyHmr9/7o=", # ... one entry per supported platform ... "zh:00e5877d19fb1c1d8c4b3536334a46a5c86f57146fd115c7b7b4b5d2bf2de86d", # ... one entry per supported platform ... ] }The hashes come from the registry's per-platform download response. When the registry does not supply them (for example, a third-party registry that has not adopted the field), Terragrunt falls back to its previous behavior of writing an h1: hash for the current platform plus zh: hashes for every platform listed in the shasums document.
Tip
Thanks to the OpenTofu team
This feature builds on work done by the OpenTofu team to expose per-platform hashes directly from the OpenTofu provider registry. Starting with OpenTofu 1.12, tofu init populates .terraform.lock.hcl with hashes for every supported platform out of the box, with no tofu providers lock invocation required. Users on older OpenTofu versions still get the same lock files when running through Terragrunt's provider cache server, but upgrading to 1.12 is the easiest way to get the same behavior everywhere, including when using the automatic provider cache dir.
ποΈ Performance Improvements
stack output fetches unit outputs in parallel
terragrunt stack output now fetches outputs from multiple units at the same time, which is noticeably faster on larger stacks. Use the existing --parallelism flag (or TG_PARALLELISM) to lower concurrency if you need to.
terragrunt stack output --parallelism 4π‘ Tips Added
Stack-target hint when --filter is missing | type=stack
run and stack generate now emit a tip when a --filter path resolves to a directory containing terragrunt.stack.hcl but the filter is not restricted to stacks. Without | type=stack, stack generate ignores the filter and run does not generate that stack.
The tip prints the offending filter, the suggested rewrite, and a link to the filter docs. Suppress it with --no-tip stack-target-missing-type-stack or --no-tips.
π Bug Fixes
Auth provider command returning null no longer crashes Terragrunt
If the command configured via --auth-provider-cmd wrote the JSON value null to stdout, Terragrunt crashed with a nil pointer dereference before it could obtain credentials.
A null response is now treated as an empty response: no environment variables and no credentials are applied, and the run continues.
Auto-init now re-runs after a source change when modules are already cached
terragrunt plan/apply could fail with Error: Required plugins are not installed after a source-version change in any unit with a module "" block. The .terragrunt-init-required marker written on source change was being ignored because modulesNeedInit short-circuited as soon as .terraform/modules/ existed.
The marker check now lives at the top of needsInitRunCfg and is honored regardless of cached .terraform/modules/ contents.
Thanks to @arnaud-dezandee for contributing this fix!
--download-dir is now respected through dependency blocks and read_terragrunt_config
A custom download directory set via --download-dir (or TG_DOWNLOAD_DIR) was honored for the unit being run, but lost as soon as parsing crossed into another config. dependency blocks and read_terragrunt_config() would fall back to the dependency's local .terragrunt-cache next to its terragrunt.hcl, ignoring the user-set path.
TG_DOWNLOAD_DIR=/tmp/tg-cache terragrunt run --all plan # Root unit: outputs landed in /tmp/tg-cache β # Dependency outputs: written next to each dependency's terragrunt.hcl βWhen the parsing context switches to a new config path, the download directory is now updated only if it still points at the previous module's default location. A user-supplied path never matches any module's default and is carried through every dependency hop unchanged.
Thanks to @maonat for contributing this fix!
remote_state β apply tags during DynamoDB lock table creation
Terragrunt previously applied dynamodb_table_tags to DynamoDB lock tables after table creation rather than during the initial CreateTable API request.
This caused failures in environments enforcing required AWS resource tags through SCPs or tag policies, where tags must be present at resource creation time.
Terragrunt now includes dynamodb_table_tags in the initial DynamoDB table creation request during remote state bootstrap.
remote_state { backend = "s3" config = { bucket = "my-state-bucket" dynamodb_table = "terraform-locks" dynamodb_table_tags = { Environment = "prod" Team = "platform" } } }Thanks to @Rahul-Kumar-prog for contributing this fix!
Engine archive extraction rejects path-traversal entries
When Terragrunt extracted an engine archive while the engine experiment was active, entries whose target path resolved outside the extraction directory were not rejected correctly. Such an entry could overwrite files anywhere the Terragrunt process could write.
These entries are now rejected early with a descriptive error before any bytes are written. Engine archives produced by Gruntwork were never affected; the gap only mattered for a tampered or untrusted archive.
Thanks to @jackiesre721 for reporting this!
--filter combined with a negation no longer parses excluded units
When a positive path filter was combined with a negated one, Terragrunt classified any unit that matched neither expression as requiring defensive parsing before exclusion instead of being excluded early.
e.g.
$ terragrunt run --all --filter './foo' --filter '!./baz' # If `./bar` existed on disk, it would be parsed before being excluded. This is no longer the case.Any positive filepath filter now consistently results in units that cannot be discovered during Terragrunt discovery being excluded from parsing for evaluating candidacy of inclusion. When a sufficiently complex filter is present, like the following:
$ terragrunt run --all --filter './foo' --filter '!./baz' --filter 'reading=root.hcl' # If `./bar` existed on disk, it will still be parsed before being excluded to determine if it reads `root.hcl`.macOS and Windows binaries report the correct release version
The v1.0.4 macOS and Windows release binaries reported terragrunt version main and parsed as 0.0.0, breaking any terragrunt_version_constraint configured against them.
sign-macos.yml and sign-windows.yml included build jobs for standalone workflow_dispatch runs. During the release workflow, those jobs still saw the original workflow_dispatch event from release.yml, so the old condition evaluated to true. The redundant build used BUILD_VERSION=${{ github.ref_name }} and replaced the correctly versioned artifact uploaded by build.yml.
The signing workflows now skip their internal build job when invoked via workflow_call and only build when dispatched directly, so release binaries keep the version stamped by build.yml.
Fixed 403 Forbidden on nested private modules when using the provider cache server
With TG_PROVIDER_CACHE enabled, OpenTofu/Terraform sent nested module-registry lookups to the upstream registry with the cache server's API key as the bearer token, instead of the credentials configured for that host. Private registries rejected those requests:
Error: Error accessing remote module registry Failed to retrieve available versions for module "<name>" from <registry>: error looking up module versions: 403 Forbidden.Terragrunt sets TF_TOKEN_<host> to the cache server's API key so the cache can front provider downloads. Module-registry requests bypassed the cache and went straight to the upstream, so the registry saw the cache key instead of the user's token.
The cache server now also fronts the modules.v1 endpoint for each configured registry. It drops the inbound cache-server bearer, looks up the user's credentials for the upstream host from the loaded CLI config (TF_TOKEN_<host>, ~/.terraform.d/credentials.tfrc.json, etc.), and forwards the request with that token.
Run report file generation no longer stalls or deadlocks with many runs
Generating a run report via --report-file could stall or deadlock when a queue contained many runs and some were still recording their final status as the report was written.
Reports now serialize each run independently, so writing a report no longer blocks status updates from runs that are still finishing.
Thanks to @jackiesre721 for contributing this fix!
Declining a run --all or --graph confirmation no longer skips cleanup
When terragrunt run --all destroy (or --all state, --all apply, or the equivalent --graph variants) prompted for confirmation and the user answered "no", Terragrunt terminated the process directly, skipping cleanup the run had registered.
Cleanup now runs before Terragrunt exits.
s3:: and gcs:: stack sources now download
Stack file source URLs starting with s3::https:// or gcs::https:// previously failed with a credentials error even when valid credentials were available. They now download. Existing stack files need no change.
Plain https://www.googleapis.com/storage/... URLs are now intended to download anonymously without GCP credentials, but Terragrunt continues to use GCS credentials to download them for backward compatibility, emitting a deprecation warning the first time it does so. To opt into the new behavior, enable the legacy-gcs-public-prefix strict control. To pull from a private GCS bucket explicitly, prefix the URL with gcs:: yourself.
Fixed nested key order in terragrunt stack output
When a unit lived inside more than one nested stack, terragrunt stack output rendered its key with the stack names reversed, so a unit inside root_stack_3 > stack_v3 > stack_v2 appeared under stack_v2.stack_v3.root_stack_3 instead of root_stack_3.stack_v3.stack_v2. Deeply nested units also leaked to the top level of the output.
The output now joins stack names from outermost to innermost, matching the declared hierarchy in both the HCL and JSON formats.
Thanks to @anuragrao04 for contributing this fix!
Fixed failed to create directory ...: file exists from the provider cache server
If a previous run had cached a provider by symlinking ~/.terraform.d/plugins/<provider> into Terragrunt's own provider cache, and that user plugin directory was later moved or deleted, the symlink was left dangling. The next run failed with failed to create directory ...: file exists and refused to cache the provider.
Terragrunt now removes a dangling symlink at the cache path on the next run and proceeds to download the provider. A non-symlink at that path is left in place and surfaced as an error.
π§ͺ Experiments Added
azure-backend β Native Azure Storage (azurerm) remote-state support
The azure-backend experiment has been added as the gate for native Terragrunt support of the Azure Storage (azurerm) remote-state backend. Once it stabilizes, Terragrunt will bootstrap, delete, and migrate Azure storage accounts and blob containers the same way it already does for S3 and GCS, and read state directly from Azure blobs for --dependency-fetch-output-from-state.
In this release the flag is reserved only. Enabling it has no behavioral effect, and remote_state { backend = "azurerm" } continues to pass through to the OpenTofu and Terraform native azurerm backend.
Track progress and share feedback in #4307. For setup steps, see the experiment documentation.
Thanks to @omattsson for driving this experiment forward!
π§ͺ Experiments Updated
CAS keeps a central Git store for incremental fetches
CAS now keeps one bare Git repository per remote URL inside its store, under ~/.cache/terragrunt/cas/store/git/ on Linux by default. See Storage for where this lives on macOS and Windows. On a cache miss, Terragrunt fetches just the requested ref into that repository instead of running a fresh shallow clone into a temporary directory. Repeated misses against the same remote reuse the existing pack files, so fetching a second ref from the same repository transfers only the new objects.
Concurrent Terragrunt runs against the same remote URL share one fetch instead of cloning in parallel; later runs reuse what the first one transferred. If the shared fetch hangs or fails, Terragrunt logs a warning and falls back to a temporary clone so cloning still succeeds.
You can reclaim space at any time by deleting the git/ subdirectory:
rm -rf ~/.cache/terragrunt/cas/store/gitcas β Commit SHAs accepted in ref=
Source URLs of the form git::<url>?ref=<commit-sha> now resolve through CAS. Previously these clones failed because Terragrunt asked the remote to look up the SHA as a symbolic reference, which Git servers don't support.
Both full SHAs (SHA-1 and SHA-256) and abbreviated SHAs are accepted. Abbreviated SHAs must disambiguate inside the repository, the same rule Git itself applies.
terraform { source = "git::https://github.com/acme/infrastructure-modules.git//vpc?ref=a1b2c3d4e5f67890abcdef1234567890deadbeef" }The first cold clone of a repository pinned to a commit SHA fetches the full history of every branch. Shallow fetches require a ref name, and fetching a commit SHA at limited depth depends on a server option (uploadpack.allowAnySHA1InWant) that is not universally enabled, so CAS fetches all branches at full depth and resolves the SHA locally. Subsequent clones reuse the cached repository and never touch the network for the same commit. Branch and tag refs continue to use the existing shallow path.
cas β mutable attribute on terraform, unit, and stack blocks
A new mutable attribute opts a block out of CAS hardlinking when its source is fetched through CAS. With mutable = true, files materialized into .terragrunt-cache (for terraform) or .terragrunt-stack (for unit and stack) are copied from the CAS store and the working tree is editable.
The default is false. Files are materialized read-only so an accidental edit cannot reach back into the shared CAS store.
terraform { source = "git::https://github.com/acme/infrastructure-modules.git//vpc?ref=v1.0.0" mutable = true }The flag is orthogonal to update_source_with_cas and has no effect when content is fetched through the standard download path, which already produces an independent copy.
cas β update_source_with_cas now idempotent across unit and stack blocks
A terragrunt.stack.hcl with two blocks pointing at the same template directory used to fail stack generate when each block had update_source_with_cas = true. The first block's pass rewrote the shared template's source to a cas::sha256:... reference, then the second block's pass re-read the rewritten file and treated the reference as a relative path.
CAS now skips re-processing a source once it already carries the cas:: prefix, so multiple unit or stack blocks can share a template and resolve to the same synthetic tree.
cas β symlinks in the source repository
Source repositories fetched through CAS used to materialize committed symlinks as regular files whose contents were the link target path. The destination tree no longer matched the upstream layout, and any tooling that followed the link saw plain text instead.
CAS now writes a real symbolic link at the destination. Symlink targets that resolve outside the destination tree are rejected so a hostile or stale source cannot escape the working directory.
catalog-redesign β component tags
The catalog-redesign experiment now reads a tags field from the component's README.md front-matter. Tags appear as colored pills next to the component in the list view and in the detail view above the rendered README.
<!-- Frontmatter name: VPC App description: A VPC for application workloads. tags: [networking, aws, module] -->Either inline-array or dash-list YAML form is accepted. Tags render in gray by default. When a tag matches a known component-type name (module, template, unit, or stack, case-insensitive), the pill takes on that type's color.
A tag matching a component-type name also promotes the component into that type's tab. A template whose tags include module appears under both Templates (by its native kind) and Modules (by tag), without changing how it scaffolds.
To learn more, see Component tags.
What's Changed
feat: read catalog component tags from README front-matter by @yhakbar in #6033
feat: Generate full lock files by @yhakbar in #5992
feat: Adding stack target tip by @yhakbar in #6013
feat: Adding central Git store for CAS by @yhakbar in #6003
feat: adding support for commit refs in CAS by @yhakbar in #6010
feat: Adding mutable attribute for clones to force copy instead of hard links by @yhakbar in #6011
feat: stack outputs parallel fetching by @denis256 in #6104
feat: outputs fetching performance improvements by @denis256 in #6122
feat(experiments): register azure-backend experiment with stub azurerm backend by @omattsson in #6014
fix: Fixing provider cache test flake by @yhakbar in #6056
fix: Fixing panic in --auth-provider-cmd against null by @yhakbar in #6137
fix: Making update_source_with_cas idempotent within a single terragrunt generate call by @yhakbar in #6142
fix: Refactoring some HCL fn parameter logic by @yhakbar in #6043
fix: Fixing weak path classifier by @yhakbar in #6062
fix: Fixing race condition in dependencyBlockToCtyValue by @yhakbar in #6067
fix: Fixing string coercion in tags for catalog by @yhakbar in #6066
fix: Propagate original credential configs for requests to modules by @yhakbar in #5999
fix: Fix missing tags in DynamoDB lock table creation during bootstrap by @Rahul-Kumar-prog in #5974
fix: Addressing catalog tag feedback by @yhakbar in #6073
fix: Fixing symlinks in repos for CAS clones by @yhakbar in #6082
fix: Fixing tag refs in CAS by @yhakbar in #6083
fix: defer in loop causing lock accumulation in report writer by @jackiesre721 in #6085
fix: Moving engine extraction to vfs for path traversal check by @yhakbar in #6101
fix: Fixing CAS symlink bug by @yhakbar in #6102
fix(auto-init): Re-init on source change when modules are cached by @arnaud-dezandee in #6059
fix: respect TG_DOWNLOAD_DIR for dependency blocks by @maonat in #6024
fix: Fixing ordering of nested stacks in terragrunt stack output by @yhakbar in #6113
fix: Fixing run --all early exit by @yhakbar in #6127
docs: Update to robots by @karlcarstensen in #6064
docs: Adding thanks for #5974 by @yhakbar in #6079
docs: Changelog for #6085 by @yhakbar in #6091
docs: Adding Continuous Integration w/ Terragrunt guide by @yhakbar in #6006
docs: Adding redirect to vercel by @karlcarstensen in #6094
docs: Remove changefreq by @karlcarstensen in #6096
docs: Vercel trailing slash fix by @karlcarstensen in #6097
docs: Updating changelog for v1.0.5 by @yhakbar in #6103
docs: Documenting hook exit code control by @yhakbar in #6106
docs: Adding thanks for #6059 by @yhakbar in #6107
docs: Adding changelog entry for #6024 by @yhakbar in #6110
docs: Adding changelog for #6014 by @yhakbar in #6138
chore: fixed macos and windows version setting in CICD by @denis256 in #6054
chore: added handling of draft releases by @denis256 in #6055
chore: Expanding lll coverage to format-options by @yhakbar in #5868
chore: Expanding lll coverage to dag-graph by @yhakbar in #5869
chore: Expanding lll coverage to scaffold by @yhakbar in #5870
chore: Expanding lll coverage to runcfg by @yhakbar in #5871
chore: Expanding lll coverage to runall by @yhakbar in #5872
chore: Expanding lll coverage to telemetry by @yhakbar in #5873
chore: Expanding lll coverage to options by @yhakbar in #5874
chore: Expanding lll coverage to retry by @yhakbar in #5877
chore: Expanding lll coverage to report by @yhakbar in #5880
chore: Expanding lll coverage to codegen by @yhakbar in #5881
chore: Addressing feedback from #6025 by @yhakbar in #6031
chore: Adding TGS --help footer by @yhakbar in #6046
chore: Adding additional telemetry & logs by @yhakbar in #6057
chore: Expanding lll coverage to discovery by @yhakbar in #5883
chore: aws-sdk-go-v2 upgrade by @denis256 in #6065
chore: Avoid cancelling main workflows by @yhakbar in #6069
chore: simplified default patterns initialization by @denis256 in #5808
chore: Adding bug fix release notification workflow by @yhakbar in #6063
chore: Consolidating go-getter routes by @yhakbar in #6030
chore: CICD fixes by @denis256 in #6071
chore(deps): bump astro from 6.1.6 to 6.1.10 in /docs by @dependabot[bot] in #6087
chore(deps): bump jdx/mise-action from 4.0.0 to 4.0.1 by @dependabot[bot] in #5734
chore(deps): bump aws-actions/configure-aws-credentials from 6.0.0 to 6.1.0 by @dependabot[bot] in #5812
chore(deps): bump fast-xml-parser and @aws-sdk/xml-builder in /docs/src/fixtures/terralith-to-terragrunt/app/best-cat by @dependabot[bot] in #5981
chore(deps): bump fast-xml-builder from 1.1.5 to 1.2.0 in /docs/src/fixtures/terralith-to-terragrunt/app/best-cat by @dependabot[bot] in #6105
chore(deps): bump actions/cache from 5.0.3 to 5.0.5 by @dependabot[bot] in #5735
chore(deps): bump sigstore/cosign-installer from 4.0.0 to 4.1.2 by @dependabot[bot] in #5772
chore: add support for Opentofu 1.12 by @denis256 in #6134New Contributors
@jackiesre721 made their first contribution in #6085
@arnaud-dezandee made their first contribution in #6059
@omattsson made their first contribution in #6014
Full Changelog: v1.0.4...v1.0.5
Original source - May 11, 2026
- Date parsed from source:May 11, 2026
- First seen by Releasebot:May 11, 2026
v1.0.0
Terratest releases its first stable 1.0.0 and adds semantic versioning, context-aware cloud helpers, mockable WithClient injection for Azure and GCP, Terragrunt v1.0 parity, and reliability fixes across AWS, Azure, GCP, Kubernetes, and OPA.
Terratest 1.0.0 is the first stable release of the project. From this release forward, Terratest follows semantic versioning: breaking changes are restricted to major releases, and renamed or replaced symbols stay around as deprecated aliases in the v1 line. See the v1.0 announcement post for the narrative; the notes below cover what shipped.
β¨ Highlights
Context plumbing throughout. Every cloud-API helper now takes an explicit context.Context as its second argument. FooContext (fail-fast) and FooContextE (returns the error) are the canonical entrypoints; the bare Foo and FooE forms remain as deprecated aliases.
Mockable SDK clients. Most Azure and GCP helpers that previously hid SDK client construction now ship with a WithClient sibling that accepts an injected client. Drive Terratest against Azure's azfake server or a GCP test double for fast unit tests with zero credentials.
Modern, supported underlying SDKs. modules/azure migrated off Microsoft's archived "track 1" SDK onto sdk/resourcemanager; AWS S3 helpers moved off the deprecated s3/manager to s3/transfermanager.
Terragrunt v1.0 feature parity. The terragrunt module fully supports Terragrunt v1.0's CLI redesign with new wrappers and single-unit variants. Terragrunt-specific code is separated from modules/terraform into its own module.
Reliability fixes. EC2 list calls paginate, OPA policy downloads deduplicate, several panics on empty SDK responses are now errors.
β οΈ Breaking Changes
Azure SDK migration
modules/azure moved off the archived "track 1" Azure SDK onto the actively maintained sdk/resourcemanager. Users who import the underlying SDK directly need to update import paths, move field access under .Properties, and replace iterators with pagers. The release also dropped 8 deprecated GetClientE getters in favor of CreateClientE, renamed 4 CreateNewGetClient factories (with deprecated aliases), fixed the NsgRuleSummary.SourceAdresssPrefixes typo, and changed GetVirtualMachineImage{,E} to return *VMImage. See the Azure migration guide for full mechanics.
AWS S3 uploader
The four NewS3Uploader* helpers now return *transfermanager.Client instead of *manager.Uploader. The call shape moves from uploader.Upload(ctx, &s3.PutObjectInput{...}) to client.UploadObject(ctx, &transfermanager.UploadObjectInput{...}). Types live under github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager.
GCP Pub/Sub
modules/gcp/pubsub.go moved from cloud.google.com/go/pubsub v1 to v2. Wrapper shapes are unchanged, but callers driving the underlying client directly switch from client.Topic("name") / client.Subscription("name") handles to TopicAdminClient / SubscriptionAdminClient calls that take fully qualified resource names.
Terragrunt module split
Terragrunt-specific helpers were removed from modules/terraform/ and modules/test-structure/ in favor of the dedicated modules/terragrunt/ package: TgApplyAll, TgDestroyAll, TgPlanAllExitCode, ValidateInputs, InitAndValidateInputs, AssertTgPlanAllExitCode, TgInvalidBinary, TerragruntDefaultPath, ExtraArgs.ValidateInputs, NewTerragruntValidationOptions, and the TG constant. Terragrunt stack output keys were also renamed. See the terragrunt module migration table.
Kubernetes kubeconfig handling
GetKubernetesClientFromOptionsContextE now logs the kubeconfig load error before falling back to in-cluster authentication; previously the fallback was silent. A new KubectlOptions.InClusterAuth = true opt-in skips kubeconfig loading entirely for callers who want fully explicit auth.
testing.TestingT adoption
Helper signatures consistently take testing.TestingT (an interface) instead of the concrete *testing.T. Calls from *testing.T are unaffected; callers that wrap or substitute the test handle may need updates.
β¨ New Features
WithClient injection helpers across Azure and GCP
Most Azure and GCP helpers now ship with a *WithClient sibling that accepts a pre-built SDK client, enabling unit testing against Azure's azfake server, GCP test doubles, and similar fakes without standing up real cloud resources or providing credentials.
Terragrunt v1.0 feature parity
All terraform-passthrough commands use terragrunt run -- <command> and multi-unit functions use terragrunt run --all -- <command>. Generic Run / RunE provide an escape hatch. New command wrappers: Render, RenderJSON, Graph, HclValidate, OutputAllJson, plus single-unit variants for Init, Plan, Apply, Destroy, Validate, and OutputJson.
GCP Pub/Sub helpers
AssertTopicExists and AssertSubscriptionExists added to modules/gcp/pubsub.go. Thanks to @Amit2465 for the contribution.
π§ Code Quality & API Cleanup
Godoc and // Deprecated: annotations. A v1 documentation pass closed godoc gaps so the API surface renders cleanly on pkg.go.dev. Every renamed or replaced symbol carries a machine-readable // Deprecated: line so go vet, staticcheck, and IDE LSPs surface upgrade guidance automatically.
Strict golangci-lint v2 wired into pre-commit and CI across the project.
interface{} β any sweep across the codebase.
collections generics: functions are now generic; ListContains is deprecated in favor of slices.Contains.
π Bug Fixes
EC2 list pagination: DescribeInstances and DescribeTags now paginate; previously capped silently at 1,000 results.
Concurrent OPA download deduplication: modules/opa/download_policy.go uses singleflight so concurrent calls for the same rulePath share a single download.
Empty-response panics β errors: RDS, IAM, OCI list calls, and several Azure SDK-response paths return typed errors on empty responses where they previously panicked on unchecked slice access.
ACM pagination: ACM list calls now paginate.
OCI nil-safety: ListVcns and related calls loop on OpcNextPage; image sort handles nil timestamps; nil-pointer guards added across the package.
SSH file-handle leak: SCPDirFromContextE closes file handles on each download.
OPA cache concurrency race: cache initialization is now race-free under concurrent test runs.
Azure NSG field name typo: NsgRuleSummary.SourceAdresssPrefixes renamed to SourceAddressPrefixes.
π¦ Dependency Updates
AWS SDK v2 bumped across every service used by Terratest; s3/manager (deprecated) replaced with s3/transfermanager.
GCP SDKs current: cloud.google.com/go/storage 1.62, cloud.google.com/go/pubsub/v2 2.4, google.golang.org/api 0.276.
Azure migrated off azure-sdk-for-go v51 onto the actively maintained sdk/resourcemanager modules (compute, network, storage, keyvault, sql, servicebus, frontdoor, monitor, recoveryservices, and others).
mitchellh/go-homedir (archived) removed as a direct dependency in favor of os.UserHomeDir; denisenkom/go-mssqldb swapped for the Microsoft-maintained fork.
google.golang.org/grpc 1.80, github.com/docker/cli 29.x, go.opentelemetry.io/otel/sdk 1.43, github.com/jackc/pgx/v5 5.9.
OpenTofu pin updated to 1.11.6; Terragrunt baseline bumped to v1.0.2.
π Documentation Updates
v1 migration guide covering breaking changes by service, with a dedicated Azure migration guide for the SDK move.
Version pinning guide.
README refreshed with stability and versioning policy; SECURITY.md added.
βοΈ Process Updates
All CI moved from CircleCI to GitHub Actions.
Multi-arch (linux / darwin / windows Γ amd64 / arm64 / 386) build-and-release workflow with SHA256SUMS.
go-mod-tidy-check workflow added.
Full Changelog: v0.56.0...v1.0.0
Original source - May 7, 2026
- Date parsed from source:May 7, 2026
- First seen by Releasebot:May 7, 2026
v1.0.4
Terragrunt releases faster command and repo-root caching, smoother fast-copy performance, and broader bug fixes across auth provider calls, include handling, JSON parsing, Windows paths, and the Provider Cache Server. It also expands stack dependencies, CAS, and catalog support.
ποΈ Performance Improvements
run_cmd and Git repo-root results memoized without the Provider Cache Server
Within a single command, repeated run_cmd(...) calls and repeated Git repo-root lookups across units used to share their cached results only when the Provider Cache Server was running. Commands invoked without --provider-cache (the common case for find, list, and run --all against estates that do not need provider caching) re-evaluated each run_cmd and re-shelled to git rev-parse --show-toplevel for every unit.
Both caches are now active for every command, so identical run_cmd arguments and repeated repo-root lookups are reused across units regardless of whether the Provider Cache Server is enabled.
fast-copy strict control
With the new fast-copy strict control enabled, Terragrunt compiles each include_in_copy and exclude_from_copy pattern once and evaluates it inline during a single copy walk. This avoids re-walking subdirectories for every pattern, which should result in noticeable speed improvements for large source modules.
terragrunt run plan --strict-control fast-copy
The new matcher does not collapse ** to zero path segments when a neighbor is a wildcard, so a//.tf matches a/sub/main.tf but not a/main.tf. Patterns that relied on the old collapsing behavior should use brace alternation like {.tf,/*.tf} to cover both depths.
Fewer git rev-parse invocations on large estates
The get_repo_root() HCL function, the runner, and the find and list discovery commands all ask Git for the enclosing repository root. Previously, two units in the same repository each triggered their own git rev-parse --show-toplevel, even when the answer was identical. On large estates this added up to one fork per unit (and sometimes more) for a value that never changed.
A repository discovered for one working directory is now reused for any other working directory inside it, for the duration of the command. Nested repositories (a checkout vendored inside another) still resolve to their own root.
π Bug Fixes
--auth-provider-cmd no longer runs once per dependency cache directory
Resolving dependency outputs ran the configured --auth-provider-cmd again from inside each .terragrunt-cache working directory, on top of the call already made for the unit.
Terragrunt now reuses the credentials already obtained for the dependency when reading outputs from a cached working directory, so --auth-provider-cmd is invoked once per dependency instead of twice.
Fixed exclude block being dropped when defined only in an included parent
A unit that pulled in an exclude block from an include that did not declare its own exclude block saw the include's exclude configurations ignored.
Included exclude blocks now get properly merged into unit configurations.
Reported in #5089. Thanks to @HeikoNeblung for contributing this fix!
Fixed terragrunt find --include failing on relative include paths
Running terragrunt find --include against units whose include blocks reference parent configs with relative paths (../root.hcl, ./common.hcl, bare filenames, etc.) emitted errors like Rel: can't make ../root.hcl relative to /abs/working-dir and dropped those entries from the output.
Relative include paths are now resolved against the unit's directory before being made relative to the working directory, matching how the rest of Terragrunt interprets the path attribute on an include block.
find and list no longer hard-fail when a path cannot be made relative to its base. The condition is logged as a warning and the path is emitted as-is, so output stays complete and the command exits zero.
Tolerate non-JSON warnings in tofu/terraform output -json
Resolving dependency outputs no longer fails when the underlying tofu/terraform output -json invocation prints a deprecation warning to stdout alongside the JSON payload. Terraform 1.15.0 introduced a backend deprecation warning for the S3 dynamodb_table parameter that is emitted on stdout after the JSON object, which broke parsing with errors like invalid character 'W' after top-level value and the misleading downstream message There is no variable named "dependency".
Terragrunt now isolates the first JSON object in the captured stdout, so leading log lines (for example, the long-standing AWS Client Side Monitoring Enabling CSM line) and trailing warning blocks are both ignored when reading dependency outputs.
Resolves #6001. Thanks to @jpke for contributing this fix!
get_repo_root() returns OS-native separators on Windows
git rev-parse --show-toplevel always emits forward-slash paths, even on Windows. Terragrunt returned that string unchanged from get_repo_root(), so configurations that compared the result against path/filepath-style paths or fed it back into helpers expecting OS-native separators saw spurious mismatches and broken joins on Windows.
The output is now normalized to OS-native separators before being returned, so get_repo_root() produces C:\repo\path on Windows and /repo/path on Linux and macOS.
Reported in #5976.
Hardened module manifest handling
Terragrunt now bounds .terragrunt-module-manifest cleanup to the manifest's own folder, skips paths with symlinked parents, and removes invalid manifests after reading any valid entries. Existing manifests keep the same gob format.
Provider Cache Server now supports custom host blocks
Running terragrunt with the Provider Cache Server enabled against a private registry declared via a host block in .terraformrc (or a file referenced by TF_CLI_CONFIG_FILE) failed with errors such as provider registry.opentofu.org/<org>/<provider> was not found, because the cache server proxy did not recognize the custom registry and rewrote requests to registry.opentofu.org.
Terragrunt now registers each custom host block with the cache server, seeds its service discovery from the services map so registries that do not serve .well-known/terraform.json still work, and forwards OPENTOFU_NETRC_* / TF_TOKEN_* credentials so authenticated registries continue to authenticate through the proxy.
# .terraformrc host "registry.example.com" { services = { "providers.v1" = "https://registry.example.com/repository/terraform-hosted/v1/providers/" } }Resolves #5916. Thanks to @elkh510 for contributing this fix!
π§ͺ Experiments Updated
stack-dependencies β Stricter validation and clearer parse errors for autoinclude
Malformed configuration inside an autoinclude block previously produced misleading messages or, in some cases, was silently ignored during stack discovery.
Two changes tighten this up:
A dependency block inside autoinclude must declare exactly one label. Zero labels (dependency {}) and multiple labels (dependency "a" "b" {}) are now rejected at parse time with a diagnostic that points at the offending block.
Parse failures encountered while expanding autoinclude files during stack generate, find, and list are surfaced with the underlying HCL diagnostic instead of being swallowed or remapped to a generic discovery error.
Reported in #5980.
cas β Local paths supported as stack component sources
CAS-backed stack generation now accepts a local filesystem path as the source of a consumer stack or unit block, in addition to a remote Git URL. Terragrunt copies the referenced directory into a temporary directory, computes a content-addressed root hash over the copy, and applies the same update_source_with_cas rewriting as the remote flow. The original directory is left untouched.
# live/terragrunt.stack.hcl stack "service" { source = "../catalog//stacks/service" path = "service" }This makes a catalog usable against a local checkout under the same update_source_with_cas = true attributes that already work for Git URLs, which is helpful when iterating on a catalog before tagging a release.
See the CAS documentation and Explicit Stacks: Local catalog sources for details.
catalog-redesign β Units and stacks, scaffolded values, and key-binding cleanup
The redesigned terragrunt catalog TUI gains two new component kinds, a guided scaffolding flow for placing them, and a small key-binding cleanup.
Units and stacks join modules and templates
Catalog discovery now classifies units (directories containing a terragrunt.hcl) and stacks (directories containing a terragrunt.stack.hcl) as first-class component kinds, alongside OpenTofu/Terraform modules and boilerplate templates. The list view picks them up automatically and they appear under their own tabs; press tab and shift+tab to cycle.
When more than one classification could apply to the same directory (for example, a stack directory that also contains a unit), Terragrunt resolves it to a single kind under a fixed precedence: template, stack, unit, module.
Copy and scaffolded values
Selecting a unit or stack from the catalog now offers a copy action that materializes the component into your working directory. Terragrunt walks the copied component for values.<name> references and, if it finds any, writes a sibling terragrunt.values.hcl stub. Names referenced outside a try(...) are listed as required with a "TODO" placeholder; names referenced through a try(...) are listed as optional, pre-populated with the literal default from the fallback. An existing terragrunt.values.hcl is left alone.
After the TUI exits, Terragrunt prints a short callout pointing at the directory it wrote to and any follow-up command you need to run, instead of leaving you to find the new directory yourself.
Catalog key bindings
The ctrl+j binding on the catalog list has been removed in favor of enter alone for choosing a focused entry, and dropped from the navigation set used while filtering. The mini help footer is updated to match.
stack-dependencies - Separate filenames for unit vs stack autoincludes
Generated autoinclude files now use distinct filenames depending on the component kind, so tooling (LSP, read_terragrunt_config(), indexers) can identify a file's purpose from its name alone:
- Unit-level autoincludes continue to be written as terragrunt.autoinclude.hcl.
- Stack-level autoincludes (autoinclude blocks declared inside a stack { ... }) are now written as terragrunt.autoinclude.stack.hcl. The .stack.hcl suffix mirrors terragrunt.stack.hcl, matching the convention used elsewhere for stack files.
# terragrunt.stack.hcl unit "app" { source = "../catalog/units/app" path = "app" autoinclude { # Generated as: .terragrunt-stack/app/terragrunt.autoinclude.hcl dependency "vpc" { config_path = unit.vpc.path } } } stack "networking" { source = "../catalog/stacks/networking" path = "networking" autoinclude { # Generated as: .terragrunt-stack/networking/terragrunt.autoinclude.stack.hcl dependency "shared" { config_path = unit.shared.path } } }This change implements the naming convention proposed in the Stack Dependencies RFC so configurations for units and stacks always live in files whose names clearly indicate their purpose.
To learn more, see the experiment documentation.
stack-dependencies β Nested stack paths and discovery integration
The stack-dependencies experiment gains two improvements: nested stack path references at arbitrary depth, and integration with the find and list discovery commands.
Nested stack path references
stack.<name>.<nested_stack>.path now resolves at arbitrary nesting depth. Previously, only units within a stack were reachable via stack.<name>.<unit_name>.path; nested stacks are now first-class references too.
# terragrunt.stack.hcl stack "infra" { source = "../catalog/stacks/infra" path = "infra" } unit "app" { source = "../catalog/units/app" path = "app" autoinclude { dependency "deep" { # infra contains a nested "deep" stack; reference it directly. config_path = stack.infra.deep.path } inputs = { val = dependency.deep.outputs.val } } }Discovery commands surface stack dependencies
The terragrunt find and terragrunt list discovery commands now reflect stack dependencies generated by the autoinclude block. The DAG output correctly orders units by their autoinclude dependencies and shows dependency relationships in JSON, tree, and long formats.
# JSON output includes dependency relationships from autoinclude $ terragrunt find --json --dag --dependencies --experiment stack-dependencies # Long list format shows a Dependencies column $ terragrunt list --long --dependencies --dag --experiment stack-dependencies # Tree format visualizes the dependency hierarchy $ terragrunt list --tree --dag --experiment stack-dependenciesMulti-level dependency trees (for example, A β B,C where B β D,E) are ordered correctly in DAG mode: leaf units appear first, parents appear after all their dependencies.
To learn more, see the experiment documentation.
Cache and plugin directories follow platform conventions
Terragrunt's global cache directory now resolves to the platform's user cache location instead of a hard-coded ~/.cache/terragrunt. On Linux this honors XDG_CACHE_HOME (still ~/.cache/terragrunt by default), on macOS it resolves to ~/Library/Caches/terragrunt, and on Windows it resolves under %LocalAppData%. The CAS content store, the auto provider cache, and the IaC engine plugin directory all move with it.
Existing caches at the previous locations are not migrated. They become orphaned and continue to consume disk space until removed.
Consider deleting the old paths to reclaim that space if you are on macOS or Windows, or have configured a custom XDG_CACHE_HOME:
# CAS store and engine plugins under the legacy ~/.cache layout rm -rf ~/.cache/terragruntWhat's Changed
feat: stack dependencies in find and dag by @denis256 in #5945
feat: Adding support for units and stacks in catalog by @yhakbar in #5971
feat: Adding support for local paths in CAS by @yhakbar in #5933
feat: updated name for stack depednencies by @denis256 in #6018
fix: manifest handling improvements by @denis256 in #6032
fix: Removing extra --auth-provider-cmd call by @yhakbar in #6045
fix: Use FromSlash on return of git rev-parse --show-toplevel by @yhakbar in #5987
fix: Cleaning up #5232 by @yhakbar in #6009
fix: better errors reporting form autoincludes by @denis256 in #5985
fix: Dropping references to ctrl-+j in the catalog key bindings by @yhakbar in #6007
fix: Ensuring relativization is safer by @yhakbar in #6025
fix: tolerate non-JSON warnings in tofu/terraform output -json (#6001) by @jpke in #6029
fix: support custom host blocks in Provider Cache Server by @elkh510 in #5917
perf: Memoizing get_repo_root() better by @yhakbar in #5989
perf: Moving context cache construction earlier by @yhakbar in #6019
docs: Adding a Pull Requests section to the changelog by @yhakbar in #5982
docs: Update buttons on nav by @karlcarstensen in #6000
docs: Calling out update for existing cache locations in v1.0.4 by @yhakbar in #6005
docs: Cleaning up changelog for v1.0.4 by @yhakbar in #6050
docs: Documenting #5917 by @yhakbar in #6044
docs: Optimizing SEO a bit by @yhakbar in #5990
docs: Updating terminology to modernize it a bit by @yhakbar in #6016
chore: Supporting immutable releases by @yhakbar in #5905
chore: Cleaning up other scripts with shellcheck and shfmt by @yhakbar in #5983
chore: Add fast-copy strict control by @yhakbar in #5966
chore: Expanding lll coverage to worktrees by @yhakbar in #5861
chore: Expanding lll coverage to os-exec by @yhakbar in #5862
chore: Expanding lll coverage to runner-creds by @yhakbar in #5865
chore: Expanding lll coverage to tflint by @yhakbar in #5866
chore: Expanding lll coverage to queue by @yhakbar in #5867
chore: Addressing review feedback on #5989 by @yhakbar in #5991
chore: Integrate vexec into engine by @yhakbar in #5957
chore: Moving to XDG-aware paths by @yhakbar in #5941
chore: Optimizing catalog performance by @yhakbar in #5973
chore: Adding checkbox for changelog updates by @yhakbar in #6012
chore: Integrating vexec into Command by @yhakbar in #6004
chore: Addressing #6019 feedback by @yhakbar in #6023
chore: Addressing test flakes by @yhakbar in #6028
chore: Adding thank you to @jpke for fix in #6029 by @yhakbar in #6035
chore: Dropping insignificant OpenTelemetry traces by @yhakbar in #6034
chore: Adding better symlinks experiment tests by @yhakbar in #6038New Contributors
@jpke made their first contribution in #6029
@elkh510 made their first contribution in #5917Full Changelog: v1.0.3...v1.0.4
Original source - Apr 27, 2026
- Date parsed from source:Apr 27, 2026
- First seen by Releasebot:Apr 27, 2026
v1.0.3
Terragrunt releases v1.0.3 with new CAS and stack capabilities, including the --no-cas flag, stack integration for CAS, and broader discovery for catalog templates. It also adds mark-many-as-read and mark_glob_as_read, while fixing crashes, races, and hcl fmt diff output.
β¨ New Features
--no-casflag for disabling CAS per command
The new
--no-casflag disables the CAS for a single invocation, even when the cas experiment is enabled. It is available on run, stack generate, and stack run.terragrunt stack generate --experiment cas --no-casThis is useful when you want to fall back to the standard getter path without unwinding experiment configuration.
Generation and runs error when
--no-casis combined withupdate_source_with_cas = trueon any reachable unit, stack, or terraform block, since relative sources in catalog repositories cannot be resolved without the CAS.π Bug Fixes
hcl fmt --diffno longer requires the diff binary
Previously,
terragrunt hcl fmt --diffspawned a diff process discovered in$PATHto render its output. This made it incompatible with minimal container images and Windows installations where that binary was unavailable.The flag now produces unified diff output without depending on any external binary.
Note that the output is not byte-identical to GNU diff -u. Each file diff is now preceded by a
diff old/<path> new/<path>header line, and the ---/+++ lines no longer include a trailing timestamp. Scripts that parsed the previous output may need small adjustments.- Fixed crash when include and locals with read_terragrunt_config coexist
A unit that combined an include block with a locals block calling
read_terragrunt_config(...)could crash during discovery, surfacing as a misleadingCall to function "read_terragrunt_config" failederror pointed at the locals expression.Discovery now reports the underlying error instead of crashing.
Reported in #5949.
- Fixed crash when a root.hcl declares no remote_state block
A root.hcl that only declared locals (or otherwise omitted a remote_state block) could trigger a nil pointer dereference inside Terragrunt's remote-state initialization. Downstream tools that embed the Terragrunt config parser, such as terragrunt-ls, crashed on every such file.
A missing remote_state block now initializes an empty remote-state value instead of panicking, so parsing proceeds normally when no backend is configured.
Reported in terragrunt-ls#134.
Thanks to @SAY-5 for contributing this fix!
- Fixed a race condition in terragrunt stack generate
Fixed a race condition in
terragrunt stack generatethat could produce non-deterministic file errors on nested stack hierarchies. The same stack file could reach the worker pool twice through different path forms and cause the duplicate writes to conflict with each other. Paths are now normalized before dispatch so each stack file is generated exactly once per invocation.When a stack file is legitimately claimed by more than one parent during generation, Terragrunt now logs a warning that names the contending parents and records the latest claimant, so the configuration can be corrected before it causes silent overwrites.
- Fixed data race in --version flag parsing under concurrent CLI invocations
When multiple Terragrunt CLI invocations ran concurrently in the same process, urfave/cli/v2's package-level VersionFlag singleton was mutated concurrently by each invocation's flag-parsing path, producing a
WARNING: DATA RACEon shared flag state.Terragrunt now sets
cli.App.HideVersion = trueat construction, which prevents urfave from auto-appending its shared VersionFlag into each App's flag set. The--version/-vflag is unchanged from the user's perspective β it is handled by Terragrunt's own flag registered ininternal/cli/flags/global.NewHelpVersionFlags.π§ͺ Experiments Added
mark-many-as-readβ Mark many files as read in one step
Enable the new
mark-many-as-readexperiment to turn on two behaviors that each mark many files as read in a single call: automatic marking of files inside a localterraform { source = "..." }block, and the newmark_glob_as_readHCL function.With the experiment on, a unit like this:
# live/unit/terragrunt.hcl terraform { source = "../../modules/service" }records every
*.tf,*.tf.json,*.hcl,*.tofu, and*.tofu.jsonfile found under../../modules/service(recursively) as read for the unit. Non-source files such asREADME.mdare skipped. A reading-based filter expression such as--filter 'reading=../../modules/service/**'then matches every unit that points at the module, so a change to any file in the module cascades to its consumers.The same experiment also enables a new HCL function,
mark_glob_as_read(pattern), which expands a glob using the same gobwas/glob syntax as filter expressions and marks every matching file as read. It returns the list of absolute paths that matched, so it composes with other expressions:locals { configs = mark_glob_as_read("${get_terragrunt_dir()}/config/{*.yaml,**/*.yaml}") }** only collapses the surrounding separators when the adjacent segments are literals, so match-at-any-depth with a wildcard trailing segment is written as
{*.yaml,**/*.yaml}. See the HCL reference for full pattern syntax.This is useful when a unit reads a collection of files indirectly (for example, via
run_cmdortemplatefile) and you want changes to any of them to trigger the unit through reading-based filters. Callingmark_glob_as_readwithout the experiment enabled returns an error.π§ͺ Experiments Updated
casβ Stack integration via update_source_with_cas
The
casexperiment now integrates with stacks. Units and terraform blocks can setupdate_source_with_cas = trueto use relative source paths in catalog repositories, removing the need to plumb remote Git URLs through values expressions.# stacks/my-stack/terragrunt.stack.hcl (in your catalog repository) unit "service" { source = "../..//units/my-service" update_source_with_cas = true path = "service" }During stack generation, Terragrunt rewrites these relative sources to
cas::references that resolve against content stored in the CAS. The repository is cloned once, and subsequent stack generations resolve content from the local store without network access. Generated.terragrunt-stackfiles contain deterministic CAS references, so regeneration does not produce spurious diffs.CAS also supports SHA-256 repositories now, detected automatically via
git rev-parse --show-object-format. The on-disk store layout was reorganized intoblobs/andtrees/namespaces under~/.cache/terragrunt/cas/store/.To learn more, see the CAS documentation and Explicit Stacks: CAS Integration.
catalog-redesignβ Templates and .terragrunt-catalog-ignore
The
catalog-redesignexperiment picked up user-visible improvements to discovery and filtering.Discovery walks the entire repository instead of only a
modules/directory, so modules and templates can live anywhere in the tree. Boilerplate templates (directories containing a.boilerplate/subdirectory or a top-levelboilerplate.yml) are discovered as a distinct component kind alongside OpenTofu/Terraform modules and labeled as templates in the UI. When a directory qualifies as both, it is classified as a template.Catalog authors can commit a
.terragrunt-catalog-ignorefile at the repo root to keep directories such asexamples/ortest/out of discovery. The file uses.gitignore-style semantics: one pattern per line,#for comments,!for negation, and last match wins. Matching is anchored at the repo root; a lone*does not cross/, and**does.# .terragrunt-catalog-ignore examples examples/** test/** !test/keepAn
--ignore-fileflag (also available viaTG_IGNORE_FILE) points at an additional ignore file that is layered on top of the repo's.terragrunt-catalog-ignore. The extra rules are appended under last-match-wins semantics, so the flag can either add new exclusions or re-include paths that the repo file excluded.To learn more, see Excluding paths from discovery.
The list view is split into All, Modules, and Templates tabs, with All selected on launch so every discovered component is visible without switching views. Press tab and shift+tab to cycle between them; each tab keeps its own cursor and search filter.
stack-dependenciesβ Multi-level nestedstack.<name>.<nested_stack>.pathreferences
The
stack-dependenciesexperiment already supportedstack.<name>.path(a whole stack) andstack.<name>.<unit_name>.path(a unit inside a stack). It now also resolves references where the second segment is itself a nested stack, so an autoinclude block in a parent stack can target a stack that lives inside another stack:# live/terragrunt.stack.hcl stack "infra" { source = "../catalog/stacks/infra" path = "infra" } unit "app" { source = "../catalog/units/app" path = "app" autoinclude { dependency "deep" { config_path = stack.infra.deep.path } } }Here
stack.infra.deep.pathresolves to the generated directory of astack "deep"block declared insidecatalog/stacks/infra/terragrunt.stack.hcl. This makes deeper stack hierarchies addressable from a single dependency expression without flattening the layout.What's Changed
- feat: Mark module sources as read by @yhakbar in #5963
- feat: Adding support for CAS in stacks by @yhakbar in #5911
- feat: Splitting modules from templates by @yhakbar in #5932
- feat: allow units to depend on stacks by @denis256 in #5924
- fix: Addressing panic in read_terragrunt_config() by @yhakbar in #5953
- fix: version flag race condition fix by @denis256 in #5961
- fix: fixing concurrent-write race in stack generate by @denis256 in #5962
- fix(remotestate): survive nil Config passed to New by @SAY-5 in #5965
- docs: Cleaning up changelog for v1.0.3 by @yhakbar in #5977
- docs: Touching up docs for catalog-redesign by @yhakbar in #5940
- docs: Adding Terragrunt Scale callout in README.md by @yhakbar in #5946
- docs: Fixing Kapa integration by @yhakbar in #5942
- chore: Integrating vexec into NewGitRunner by @yhakbar in #5934
- chore: Offboarding Travis by @yhakbar in #5944
- chore: Expanding lll coverage to amazonsts by @yhakbar in #5852
- chore: Expanding lll coverage to runner-common by @yhakbar in #5853
- chore: Expanding lll coverage to runner-graph by @yhakbar in #5854
- chore: Expanding lll coverage to list by @yhakbar in #5855
- chore: stacks generation improvements by @denis256 in #5969
- chore: Expanding lll coverage to errorconfig by @yhakbar in #5856
- chore: Expanding lll coverage to experiment by @yhakbar in #5857
- chore: Expanding lll coverage to externalcmd by @yhakbar in #5858
- chore: Expanding lll coverage to cache-controllers by @yhakbar in #5859
- chore: Expanding lll coverage to vfs by @yhakbar in #5860
- chore: Expanding lll coverage to stack by @yhakbar in #5841
- chore: Expanding lll coverage to backend-delete by @yhakbar in #5842
- chore: Expanding lll coverage to cloner by @yhakbar in #5843
- chore: Expanding lll coverage to engine by @yhakbar in #5844
- chore: Expanding lll coverage to git by @yhakbar in #5845
- chore: Consolidating independent integration tests by @yhakbar in #5938
- chore: Integrating signals into vexec by @yhakbar in #5935
- chore: Expanding lll coverage to prepare by @yhakbar in #5846
- chore: Expanding lll coverage to exec by @yhakbar in #5847
- chore: Expanding lll coverage to find by @yhakbar in #5848
- chore: Expanding lll coverage to stacks-output by @yhakbar in #5850
- chore(deps): bump astro from 6.1.2 to 6.1.6 in /docs by @dependabot[bot] in #5947
- chore: Expanding lll coverage to placeholders by @yhakbar in #5851
- chore: Removing dependency on diff by @yhakbar in #5954
- chore: Addressing feedback on #5953 and #5954 by @yhakbar in #5964
- chore: Windows signing fix by @denis256 in #5979
New Contributors
- @SAY-5 made their first contribution in #5965
Full Changelog: v1.0.2...v1.0.3
Original source - Apr 21, 2026
- Date parsed from source:Apr 21, 2026
- First seen by Releasebot:Apr 21, 2026
v1.0.2
Terragrunt ships bug fixes for backend config serialization, telemetry panics, and stack output exclusions, while adding a redesigned catalog experiment, expanded stack-dependencies support, and install script options for tip and test builds.
π Bug Fixes
shared_credentials_files and other list/map backend config values were serialized incorrectly
Setting shared_credentials_files (or any other list-valued key) in the remote_state.config block produced a broken -backend-config argument:
-backend-config=shared_credentials_files=[/a/creds /b/creds]OpenTofu and Terraform both failed to parse this. The same problem affected map-valued keys. Lists and maps are now written as single-line HCL (["/a/creds","/b/creds"] and {key="value"}), and strings inside them are quoted so embedded quotes, newlines, and tabs survive the round trip.
Thanks to @Rahul-Kumar-prog for contributing this fix!
Panic in get_repo_root() when OpenTelemetry tracing is enabled with TRACEPARENT
Running terragrunt stack generate (or any command that invoked shell commands like git rev-parse) with OpenTelemetry trace exporting enabled (TG_TELEMETRY_TRACE_EXPORTER=http) caused a nil pointer panic:
Call to function "get_repo_root" failed: panic in function implementation: runtime error: invalid memory address or nil pointer dereferenceThe root cause of the panic was fixed, and telemetry codepaths have been hardened against future panics.
stack output now respects the exclude block
terragrunt stack output previously ignored the exclude block on units, attempting to fetch outputs (including directly from S3 state when using --dependency-fetch-output-from-state) for units that should have been excluded.
The fix uses Terragrunt discovery to identify excluded units before reading outputs. Excluded units are now omitted from the stack output entirely, consistent with how they are handled during stack run.
To exclude a unit from stack output, add "output" to the actions list in the exclude block:
exclude { if = true actions = ["plan", "apply", "destroy", "output"] }Special action values "all" and "all_except_output" are also supported.
π§ͺ Experiments Added
catalog-redesign β Reworked terragrunt catalog TUI
A new catalog-redesign experiment reworks the design of the terragrunt catalog TUI.
terragrunt catalog now launches the TUI right away and runs discovery in the background instead of waiting for discovery to complete before launching the TUI. As a consequence, terragrunt catalog users with large catalogs should see significant speed improvements as they launch the terragrunt catalog TUI.
Modules now stream into the list view of the catalog as they are discovered, so you'll be able to select and use a module even if your entire catalog hasn't been discovered yet.
If catalog.urls is not configured in root.hcl, terragrunt catalog no longer errors. A welcome screen explains how to populate the catalog and can open the catalog documentation on a keypress. In addition, terraform.source values from existing units are automatically included in the set of URLs used for discovery, so users with existing units get a populated catalog pointing to other modules that can be pulled from the same module source without any additional configuration.
This experiment is subject to change, and core elements of the design are being iterated on rapidly.
To try it out, run:
terragrunt catalog --experiment catalog-redesignTo learn more, see the experiment documentation.
π§ͺ Experiments Updated
stack-dependencies β Cross-stack dependency support and autoinclude improvements
The stack-dependencies experiment now supports cross-stack and nested-stack dependency patterns, expanding the autoinclude block capabilities in terragrunt.stack.hcl files.
New features:
stack.<name>.path references for depending on an entire stack. The DAG expands the stack into its constituent units so that all units in the stack complete before the dependent unit runs
stack.<name>.<unit_name>.path references for depending on a specific unit within a nested stack (fine-grained cross-stack dependencies)
dependency blocks targeting stack directories β aggregated outputs from all units in the stack are accessible as dependency.stack_name.outputs.unit_name.output_key
Partial evaluation of local.* in autoinclude β expressions mixing local.* and dependency.* are partially evaluated during stack generation: locals resolve to literals while dependency references are preserved for evaluation when the unit is applied
Dependency on an entire stack:
stack "infra" { source = "../catalog/stacks/infra" path = "infra" } unit "app" { source = "../catalog/units/app" path = "app" autoinclude { dependency "infra" { config_path = stack.infra.path } inputs = { vpc_id = dependency.infra.outputs.vpc.vpc_id } } }Dependency on a unit within a nested stack:
stack "networking" { source = "../catalog/stacks/networking" path = "networking" } unit "app" { source = "../catalog/units/app" path = "app" autoinclude { dependency "vpc" { config_path = stack.networking.vpc.path } inputs = { vpc_id = dependency.vpc.outputs.vpc_id } } }terragrunt run --all --experiment stack-dependencies -- planTo learn more, see the experiment documentation.
βοΈ Process Updates
Install script now supports tip and test builds
The install script can now install tip builds and on-demand test builds. Three new flags are available:
- --tip installs the latest tip build from main
- --test installs an on-demand test build
- --commit <sha> installs a build for a specific commit
Downloads are verified against GPG/Cosign signatures and SHA256 checksums before installation.
Tip build notifications on referenced issues
When a tip build is produced on main for a merged PR, Terragrunt now posts a comment on any issues that PR references, linking to the build and including instructions for installing and testing it.
What's Changed
- feat: add new hclparse package in internal by @denis256 in #5816
- feat: Adding catalog-redesign experiment by @yhakbar in #5894
- feat: Adding types, sources and versions to catalog by @yhakbar in #5922
- feat: handling of stacks dependencies in run queue / runner pool by @denis256 in #5909
- feat: Supporting catalog with no config by @yhakbar in #5902
- feat: Supporting streaming components to the catalog by @yhakbar in #5914
- fix: Addressing #5895 review comments by @yhakbar in #5897
- fix: correct cloud-nuke config YAML keys and bump to v0.49.0 by @james00012 in #5920
- fix: Fixing panic in telemetry by @yhakbar in #5915
- fix: handling of exclusions when reading outputs by @denis256 in #5900
- fix: Use httptest in ./internal/tf to avoid issues from integration in unit tests by @yhakbar in #5925
- fix(s3): fix shared_credentials_files HCL serialization for backend config by @Rahul-Kumar-prog in #5886
- docs: Avoid indexing changelog in search by @yhakbar in #5928
- docs: Fix bash commands in "Terralith to Terragrunt" guide by @chorrell in #5904
- docs: Fix missing newline in remote_state examples by @thoreinstein in #5921
- docs: Splitting up changelog by @yhakbar in #5930
- docs: updated stack-dependencies implementation roadmap by @denis256 in #5910
- docs: Updating v1.0.2 changelog entries by @yhakbar in #5927
- docs: Updating install docs by @yhakbar in #5923
- chore: add 7-day cooldown to dependabot updates by @diofeher in #5889
- chore: Adding vexec by @yhakbar in #5931
- chore: Adding catalog redesign fork by @yhakbar in #5896
- chore: Adding support for vfs in cas by @yhakbar in #5908
- chore: Adding tests and docs missing from #5886 by @yhakbar in #5926
- chore: Adding tip notification system by @yhakbar in #5895
- chore: bump cloud-nuke to v0.49.0 by @james00012 in #5893
- chore: coverage scripts collection simplifications by @denis256 in #5724
- chore: Dropping CAS test by @yhakbar in #5936
- chore: Expanding lll coverage to configbridge by @yhakbar in #5834
- chore: Expanding lll coverage to errors by @yhakbar in #5833
- chore: Expanding lll coverage to gcphelper by @yhakbar in #5832
- chore: Expanding lll coverage to generate by @yhakbar in #5840
- chore: Expanding lll coverage to help by @yhakbar in #5835
- chore: Expanding lll coverage to middleware by @yhakbar in #5839
- chore: Expanding lll coverage to tips by @yhakbar in #5837
- chore: Expanding lll coverage to tui by @yhakbar in #5836
- chore: Expanding lll coverage to writer by @yhakbar in #5838
- chore: Make workflow dispatch for signing useful by @yhakbar in #5929
- chore: otel dependencies update by @denis256 in #5878
- chore: simplified returned discovery errors by @denis256 in #5664
- chore: Updating install script to support tip builds by @yhakbar in #5892
- chore: Revert "chore: bump cloud-nuke to v0.49.0" by @yhakbar in #5919
New Contributors
- @diofeher made their first contribution in #5889
- @chorrell made their first contribution in #5904
- @thoreinstein made their first contribution in #5921
- @Rahul-Kumar-prog made their first contribution in #5886
Full Changelog: v1.0.1...v1.0.2
Original source - Apr 13, 2026
- Date parsed from source:Apr 13, 2026
- First seen by Releasebot:Apr 14, 2026
v1.0.1
Terragrunt adds new experiments for DAG queue visualization, long-running task progress, and stack dependencies, while improving validation, worktree handling, Windows provider caching, retry behavior, file copy performance, and concurrency handling.
π§ͺ Experiments Added
dag-queue-display β DAG tree visualization for the run queue
A new dag-queue-display experiment renders the run queue as a dependency tree instead of a flat list, making it easier to understand execution order and dependency relationships at a glance.
$ terragrunt run --all --experiment dag-queue-display -- plan 19:06:59.108 INFO The following units will be run, starting with dependencies and then their dependents: . βββ monitoring β°ββ vpc β°ββ database β°ββ backend-app β°ββ frontend-appTo learn more, see the experiment documentation.
slow-task-reporting β Progress reporting for long-running operations
A new slow-task-reporting experiment displays animated progress spinners for operations that take longer than 1 second, such as source downloads, Git worktree creation, and catalog repository cloning. In non-interactive environments (CI/CD, piped output), spinners are replaced with periodic INFO log lines every 30 seconds to prevent CI systems from killing jobs due to output inactivity.
$ terragrunt run --all --experiment slow-task-reporting -- plan INFO Downloading source from git::https://github.com/example/module.git... INFO Downloaded source from git::https://github.com/example/module.git (3.2s)To learn more, see the experiment documentation.
stack-dependencies β Dependency wiring between units in stacks
A new stack-dependencies experiment enables the autoinclude block in terragrunt.stack.hcl files, allowing units and stacks to define dependency relationships and arbitrary configuration overrides during stack generation. This implements RFC #5663.
unit "vpc" { source = "../catalog/units/vpc" path = "vpc" } unit "app" { source = "../catalog/units/app" path = "app" autoinclude { dependency "vpc" { config_path = unit.vpc.path } inputs = { vpc_id = dependency.vpc.outputs.vpc_id } } } terragrunt run --all --experiment stack-dependencies -- planTo learn more, see the experiment documentation.
π‘ Tip Added
Windows symlink warning for provider cache users
Terragrunt now warns Windows users when symlink creation fails and provider caching is enabled. OpenTofu and Terraform may silently fall back to copying provider plugins instead of symlinking, which can increase disk usage and slow down operations. For OpenTofu >= 1.12.0, the tip includes guidance on using TF_LOG=warn to detect the fallback.
Thank you to the OpenTofu team for introducing this warning to ensure that Windows users are aware of the fallback behavior.
π Bug Fixes
hcl validate no longer fails on dependency.outputs references
terragrunt hcl validate previously failed with "Unsupported attribute" when a configuration referenced dependency.<name>.outputs.<key> without mock_outputs.
During validation, output resolution is skipped, but the outputs attribute was never added to the dependency evaluation context, causing any output reference to error. The fix provides a dynamic placeholder for dependency outputs (and inputs) during validation so that attribute access evaluates to unknown rather than failing. Additionally, the dependency resolution pipeline is now more resilient during validation. Dependencies with unresolvable config_path values or nonexistent targets no longer cause the entire dependency namespace to disappear from the evaluation context.
Destroy queue now displays units in correct order
Previously, the run queue display showed units in apply order even for destroy commands. The queue now correctly shows dependents before their dependencies when running destroy, matching the actual execution order.
Dependent discovery fixed in worktrees
Dependents are now correctly discovered when units are discovered in worktrees. Previously, dependent discovery could fail to find related units when operating within a git worktree.
Filter exclusions now respected in worktree sub-discoveries
Negated filters (e.g., !./catalog/** from .terragrunt-filters or --filter) are now propagated to worktree sub-discoveries used by git-based filtering (--filter-affected, --filter '[ref...ref]').
Previously, excluded source catalog units in worktrees were still discovered and parsed, causing errors when they referenced values.* or dependency.* variables without the stack generation context.
read_terragrunt_config() behavior in implicit stacks fixed
A regression introduced in v0.99.4 caused read_terragrunt_config() to fail to parse dependency blocks in external configurations during stack execution. This is fixed by resetting parsing context fields that prevented proper evaluation of dependencies in configurations read by read_terragrunt_config().
get_original_terragrunt_dir() now resolves correctly during dependency parsing
A regression introduced in v1.0.0-rc3 caused get_original_terragrunt_dir() to return the dependent directory instead of the dependency's directory when parsing dependency configurations from a unit.
This broke configurations where a dependency's read_terragrunt_config() chain relied on get_original_terragrunt_dir() to locate sibling files. The fix introduces a dedicated WithDependencyConfigPath method that correctly resets the original config path when parsing a dependency as an independent unit.
Chained dependency with exposed include conversion fixed
Chaining dependencies with exposed includes no longer produces a spurious "Could not convert include to the execution ctx to evaluate additional locals" error during partial parsing.
Provider cache fixed on Windows for remote URLs
The provider cache failed on Windows with CreateFile https://...: The filename, directory name, or volume label syntax is incorrect because remote download URLs were passed to os.Stat, and the colon in https: is invalid Windows path syntax. The fix skips the filesystem existence check when the download URL is a remote URL (://), going directly to the download path.
Additional transient network errors now retried automatically
Added retry patterns for provider resolution and registry connection failures commonly seen in CI environments, including TLS handshake timeouts, TCP connection resets, context deadline exceeded errors, and failed discovery document requests. These cover both Terraform and OpenTofu provider workflows.
File copy performance improved
Terragrunt now streams data from source files to target files more often by replacing some instances where files were read into memory in their entirety and written to a target file. This results in improved performance when copying files and reduced memory footprint.
βοΈ Process Updates
Tip builds now available from main
Every successful CI run on the main branch now automatically produces tip build binaries with signed checksums for all supported platforms (Windows and macOS binaries are not codesigned in tip builds). These builds are accessible via the builds API at https://builds.terragrunt.com β see the releases process documentation for API endpoints and usage examples. Maintainers can also trigger on-demand test builds from any branch using the test-build.yml workflow.
Concurrency limits now respect GOMAXPROCS
All internal concurrency limits now use runtime.GOMAXPROCS(0) instead of runtime.NumCPU(). This means Terragrunt correctly honors the GOMAXPROCS environment variable and container CPU quotas (e.g., cgroups), resulting in better behavior in resource-constrained environments like Kubernetes pods and CI runners with CPU limits.
AWS SDK updated to v1.41.5
The aws-sdk-go-v2 dependency has been updated to v1.41.5.
Terragrunt Scale documentation added
A new Terragrunt Scale section has been added to the docs, covering Pipelines, Drift Detection, and Patcher with brief overviews and links to the full Gruntwork documentation.
What's Changed
feat: experiment for reporting long running tasks by @denis256 in #5730
feat: add stack dependencies experiment by @denis256 in #5809
fix: Fixing #5624 by @yhakbar in #5766
fix: Fixing #4153 by @yhakbar in #5746
fix: Fixing macOS linting by @yhakbar in #5775
fix: Refactoring unit display in runs for better communication by @yhakbar in #5752
fix: Discover dependents in worktrees if units are discovered there by @yhakbar in #5763
fix: provider cache path handling in Windows by @denis256 in #5788
fix: Adding Windows symlink tip by @yhakbar in #5778
fix: Addressing test flakes for TestReadTerragruntConfigDependencyInStack by @yhakbar in #5781
fix: Fixing generation in stacks that read files by @yhakbar in #5790
fix: use io.Copy instead of reading files into memory by @thisguycodes in #5608
fix: Fix coverage compare regarding retries by @thisguycodes in #5793
fix: add retry patterns for transient provider/registry network errors by @denis256 in #5779
fix: Fixing get_original_terragrunt_dir() interaction with dependencies by @yhakbar in #5828
fix: Using cty.DynamicVal to avoid 'Unsupported Attribute' errors by @yhakbar in #5827
fix: Preventing parse errors in stack generation in worktrees by @yhakbar in #5826
fix: Addressing #5828 feedback by @yhakbar in #5876
fix: Fixing up lints by @yhakbar in #5887
docs: Adding v1.0.0 callout by @yhakbar in #5768
docs: Disable vercel skew protection by @karlcarstensen in #5789
docs: Updating GTM tag by @yhakbar in #5769
docs: Fixing search by @yhakbar in #5776
docs: Fixing strict controls by @yhakbar in #5782
docs: Fixing up changelog implementation by @yhakbar in #5784
docs: Documenting tip/test build installation instructions by @yhakbar in #5829
docs: Adding TGS docs by @yhakbar in #5831
chore: disabled tmpfs usage in GHA by @denis256 in #5787
chore: Adding tests to confirm #4395 is resolved by @yhakbar in #5761
chore: updated aws-sdk-go-v2 to 1.41.5 by @denis256 in #5771
chore(deps): bump the js-dependencies group across 1 directory with 5 updates by @dependabot[bot] in #5764
chore(deps): bump peter-evans/create-pull-request from 7.0.8 to 8.1.0 by @dependabot[bot] in #5736
chore: Replace runtime.NumCPU() usage with runtime.GOMAXPROCS(0) by @yhakbar in #5794
chore: various lint fixes by @thisguycodes in #5796
chore: Adding tip build workflows by @yhakbar in #5823
chore: Upgrading go deps by @yhakbar in #5795
chore: misc testing and lint updates by @thisguycodes in #5885
Full Changelog: v1.0.0...v1.0.1
Original source - Apr 8, 2026
- Date parsed from source:Apr 8, 2026
- First seen by Releasebot:Apr 9, 2026
alpha-2026040801
Terragrunt ships an alpha release prototype for the stack dependencies RFC, along with fixes for dependency discovery, Windows provider cache path handling, macOS linting, and improved run unit display communication.
β οΈ Alpha Release
Prototype implementation of stack dependencies
RFC: #5663
What's Changed
- chore: Adding tests to confirm #4395 is resolved by @yhakbar in #5761
- fix: Fixing #5624 by @yhakbar in #5766
- docs: Adding v1.0.0 callout by @yhakbar in #5768
- fix: Fixing #4153 by @yhakbar in #5746
- docs: Updating GTM tag by @yhakbar in #5769
- fix: Fixing macOS linting by @yhakbar in #5775
- docs: Fixing search by @yhakbar in #5776
- fix: Refactoring unit display in runs for better communication by @yhakbar in #5752
- chore: updated aws-sdk-go-v2 to 1.41.5 by @denis256 in #5771
- fix: Discover dependents in worktrees if units are discovered there by @yhakbar in #5763
- docs: Fixing strict controls by @yhakbar in #5782
- docs: Fixing up changelog implementation by @yhakbar in #5784
- chore: disabled tmpfs usage in GHA by @denis256 in #5787
- Disable vercel skew protection by @karlcarstensen in #5789
- fix: provider cache path handling in Windows by @denis256 in #5788
Full Changelog: v1.0.0...alpha-2026040801
Original source - Mar 30, 2026
- Date parsed from source:Mar 30, 2026
- First seen by Releasebot:Mar 31, 2026
v1.0.0
Terragrunt releases v1.0.0 with a stable 1.0 promise, cleaner discovery and rendering defaults, better Windows path handling, faster unit filtering, and many fixes for caches, provider downloads, SOPS, logs, and stack runs. It also adds tips, improved errors, and new docs.
v1.0.0 Release
Terragrunt is now v1!
This means that Terragrunt will no longer have any breaking changes in minor releases, with all future breaking changes taking place in (infrequent) future major releases.
For a list of guarantees that will be observed by maintainers for the duration of Terragrunt 1.0, see the Terragrunt 1.0 Guarantees page in the docs.
π οΈ Breaking Changes
Consistent .terragrunt-cache directory generation
Terragrunt now creates a .terragrunt-cache directory for every run, regardless of whether the terragrunt.hcl file defines a terraform block with a source attribute.
This change improves consistency across all Terragrunt executions, as OpenTofu/Terraform will now always run within the .terragrunt-cache directory. This standardized behavior simplifies troubleshooting and makes the execution model more predictable.
Removal of tflint
Terragrunt has been shipping with a version of tflint compiled into the binary to allow for more convenient usage without installing tflint directly. However due to the adoption of a BUSL license in tflint, the version included in Terragrunt was frozen.
The dependency on tflint is now fully removed from Terragrunt. If you want to call tflint using a before_hook using Terragrunt, you will have to have tflint installed locally to do so.
To reduce the burden of this breaking change, Terragrunt will continue to provide conveniences like automatically running tflint init on behalf of users, although it no longer ships with a compiled version of tflint in the terragrunt binary.
To learn more, read the documentation on the integration with tflint.
Discovery commands discover hidden configurations by default
The find and list commands now discover units/stacks in hidden directories by default (this previously required usage of the --hidden flag), notably this now discovers .terragrunt-stack directories by default. The commands also now support an opt-in --no-hidden flag to avoid discovery in hidden directories.
The --hidden flag has been deprecated, and will not be removed in 1.0. Using the flag no longer does anything.
render --format=json no longer discovers dependents by default
Prior to this release, the render --format=json command would automatically start to perform dependent discovery on other units related to the unit being rendered. Avoiding this required usage of the --disable-dependent-modules flag. That behavior has been removed. HCL and JSON rendering of unit configurations will now proceed without the additional overhead of dependent discovery by default.
This functionality is better served by a combination of find and graph-based filters.
e.g. If you want to detect all the dependents of a given unit foo, expecting to find the dependent unit bar you can run the following:
$ terragrunt find --filter '...^foo' barIf you aren't familiar with filters, this reads as "find all dependents of foo, not foo itself"
Windows compatibility in file paths improved
All HCL functions now return operating system native file paths without forward slash normalization.
get_terragrunt_dir()
get_original_terragrunt_dir()
get_parent_terragrunt_dir()
get_path_from_repo_root()
get_path_to_repo_root()
find_in_parent_folders()
path_relative_to_include()
path_relative_from_include()
If you and your team do not work in Windows environments, you are unlikely to see any change as a consequence of this. If you do use Terragrunt in a Windows environment, Terragrunt will now return appropriate Windows file paths, with backslashes as file path separators instead of Unix-like forward slashes.
If you need to normalize paths, you can use the replace function to achieve this.
# root.hcl remote_state { backend = "s3" generate = { path = "backend.tf" if_exists = "overwrite_terragrunt" } config = { bucket = "my-tofu-state" key = "${replace(path_relative_to_include(), "\\", "/")}/tofu.tfstate" region = "us-east-1" encrypt = true dynamodb_table = "my-lock-table" } }Ambiguous unit/stack components now throw errors
Previously, Terragrunt would silently engage in undefined behavior when both a terragrunt.hcl and terragrunt.stack.hcl file existed in the same directory.
With this release, Terragrunt will start to throw warnings and prevent such usage. Users will have to ensure that only one of a unit (terragrunt.hcl) or stack configuration (terragrunt.stack.hcl) exist in a unit or stack directory, respectively.
β¨ New Features
Tips added
Terragrunt will now provide helpful tips when it detects usage patterns that might benefit from some additional guidance.
You can disable the display of tips at any time using --no-tips or disable individual tips with --no-tip, (e.g. --no-tip=debugging-docs).
--report-file support for single runs
The --report-file will now generate reports even when runs are performed without the --all flag.
Improved error messages for undefined flags
Detection has been added for scenarios when a user is using a flag that might be meant to be passed to OpenTofu/Terraform in the run command, and suggests using the -- argument to pass it through.
As an example:
$ terragrunt run providers lock -platform linux_amd64 -platform darwin_arm64 14:52:19.496 ERROR flag `-platform` is not a Terragrunt flag. If this is an OpenTofu/Terraform flag, use `--` to forward it (e.g. `terragrunt run -- <command> -platform`).ποΈ Performance Improvements
Discovery performance improved
The way in which Terragrunt discovers and filters units and stacks for runs has improved significantly.
Terragrunt is now better at avoiding parsing units/stacks unnecessarily, based on the filter you use. Previously, the logic used was more coarse, and could result in a requirement to parse some configurations (e.g. presence of a dependency graph expression) to result in parsing all configurations. Discovery has been refactored to allow for much more careful opt-in parsing based on the need to support the filter used by users (or lack thereof).
This will also result in improvements to Terragrunt's ability to ignore broken parts of infrastructure estates when Terragrunt can predictably determine that it won't impact a run.
EncodeSourceVersion execution sped up
The performance of EncodeSourceVersion has been improved by utilizing SkipDir to optimize directory traversals.
Special thanks to @healthy-pod for contributing this improvement!
Provider Cache Server used for fetching outputs from dependencies
The Provider Cache Server is now used when fetching outputs from dependencies, improving performance of output resolution for users using the provider cache server.
π Bug Fixes
Improved filter parsing errors
Parsing errors returned when invalid filter queries are used with --filter have been improved to provide more detailed error messages and actionable recommendations.
Retries added for registry timeouts in provider cache server
The Provider Cache Server will now perform automatic retries on timeouts to OpenTofu/Terraform provider registries.
Discoverability of init-from-module documentation improved
The special internal init-from-module command referenced in hooks has had its documentation improved to make it easier to discover. It was difficult to find in the terraform HCL block documentation, and that resulted in confusion for users.
Over-warning on strict controls prevented
Using --strict-mode resulted in over-warning on completed controls. Those warnings will no longer appear when using strict mode.
Stdout/stderr from run_cmd emitted when included
A bug prevented the run_cmd HCL function from emitting to stdout/stderr when included by a unit. That bug has been fixed.
Provider Cache Server integration with custom registries fixed
The Provider Cache Server now properly integrates with custom registries. You will still need to use the --provider-cache-registry-names flag to ensure that the Provider Cache Server properly handles proxying requests to the custom provider registry.
The no_run attribute of exclude is fixed
A bug prevented the no_run attribute of the exclude block from being respected when being explicitly set to false (as opposed to not being defined at all). This bug has been fixed.
The --report-file is now respected for single runs
The --report-file will now generate reports even when runs are performed without the --all flag.
Path manipulation removed from log messages
Log messages no longer have paths updated automatically. This caused confusion for users when seeing OpenTofu/Terraform stdout and hook stdout emitted through logs, as paths were unconditionally updated to be relative to the unit path. This logic has been moved to logging call sites to ensure that external process stdout/stderr is not manipulated unexpectedly.
Absolute URLs in registry self-discovery integration with Provider Cache Server Fixed
When using the Provider Cache Server in conjunction with a remote registry using absolute URLs for modules, the Provider Cache Server will now properly resolve the module source.
SOPS decryption race condition fixed
A race condition in the concurrent access to SOPS decrypted secrets in different environments combined with usage of the --auth-provider-cmd flag resulted in authentication failures. Synchronization controls have been introduced to ensure authentication proceeds correctly for each environment independently.
Version constraints in stack runs fixed
When running against a stack, a bug prevented Terragrunt + OpenTofu/Terraform version constraints from being respected while using the terragrunt_version_constraint and terraform_version_constraint HCL attributes. That bug has been fixed.
Interrupt signal propagation to OpenTofu/Terraform fixed
The mechanism by which Terragrunt sends interrupt signals to OpenTofu/Terraform processes it started has been made more robust. Terragrunt will now send the interrupt signal in the event that a user explicitly sends an interrupt signal to Terragrunt in addition to scenarios where Terragrunt's context cancellation is triggered (e.g. in the event of a timeout).
Remote state configuration parsing fixed
Remote state configuration parsing (especially S3) is now more tolerant of common input formats, reducing decode-related failures from type mismatches in configuration values.
Parsing behavior has also been made more consistent across related remote configuration blocks in Terragrunt, with regression tests added to prevent future breakages.
Invalid unit configurations cause explicit errors instead of silently being excluded during runs
A bug in discovery logic resulted in units with invalid HCL configurations being silently excluded from runs with a warning. This bug has been fixed, and attempting to parse invalid HCL configurations during a run will result in an error.
Partial parse configuration cache fixed
A bug affecting the partial parse configuration cache (in use when the --use-partial-parse-config-cache flag is supplied) has been resolved, ensuring configurations are cached and read accurately without incorrect cache collisions.
Engine output adjusted
The display and formatting of engine outputs have been updated to be cleaner and more intuitive for users when running Terragrunt workflows.
Stdout/Stderr entries emitted from engines will now have the engine tool listed instead of tofu.
More accurate matching of retryable errors
Fixes a bug where retries were triggered when an expected error is matched against non-stderr output from external process errors.
Duplicate error reporting fixed
Fixes a bug where duplicate errors were reported when running units through the worker pool subsystem.
Interaction between --working-dir and -detailed-exitcode fixed
Fixes a bug where the wrong cache key was used for storing exit codes for OpenTofu/Terraform runs in units when the --working-dir flag was also used.
Variable sanitization via escaping added
Escaping added for interpolation expressions (e.g. ${foo}) that are unlikely to be desired by users.
Removing usage of filepath.Abs and reducing usage of filepath.ToSlash
Usage of the Golang filepath.Abs and filepath.ToSlash standard library functions significantly reduced. Overly broad application of these functions to file paths caused subtle operating system compatibility issues and incompatibility with the --working-dir flag.
The codebase has been updated to only use filepath.Abs early on in initialization of the CLI prior to setting the value of --working-dir (after which, working dir is considered the source of truth for file path canonicalization) and tests. The codebase has been updated to use filepath.ToSlash only where unix-style forward slash normalization is a requirement (e.g. when used in file path globs).
Handling of backend init when disable_init=true
Fixes a bug where disable_init = true affected behavior beyond Terragrunt's bootstrap operations. disable_init now correctly limits its scope to Terragrunt bootstrap steps only.
Fix detection of offline usage in Provider Cache Server
A bug in the detection of offline usage in the Provider Cache Server resulted in attempts to reach the default provider registry for OpenTofu/Terraform to trigger errors even when using the Provider Cache Server to proxy requests to a network or filesystem mirror.
This has been fixed. When the default provider registry isn't available for OpenTofu/Terraform for any reason, the Provider Cache Server will use the provided network/filesystem mirror instead without attempting to use the discovery endpoint. This will help users in air-gapped environments using the Provider Cache Server.
Improved log messages for hooks with errors
Hooks encountering errors will now return errors that better communicate whether an error was caused by failure to execute an external process or successfully running an external process, but receiving a non-zero exit code.
Relative paths in reading files fixed
A bug in the logic for incorporating includes as absolute paths in tracked "read" files has been fixed.
OpenTofu file extensions handled in catalog and scaffold
Terragrunt catalog now lists modules that use .tofu, .tf.json, or .tofu.json files. Terragrunt scaffold now parses variables from .tofu files β previously, variables defined in .tofu files were silently missing from the generated terragrunt.hcl.
Bootstrap use_lockfile boolean handling fixed
A bug in remote state backend configuration caused use_lockfile = true to be emitted as use_lockfile = "true" (quoted string), which OpenTofu/Terraform rejects. Boolean values in backend config are now normalized correctly.
Provider cache lock file corruption fixed
A bug that could cause provider cache lock file corruption has been fixed.
Git filter discovery for read_terragrunt_config fixed
Git-filter discovery now correctly detects stacks affected by changes to sidecar files read via read_terragrunt_config(), by parsing stack files to check FilesRead against diff paths instead of relying on generic directory-based detection.
S3 bucket tagging moved to bucket creation
S3 bucket tagging during backend bootstrapping has been moved to bucket creation. This prevents errors caused when SCPs restrict creation of buckets without appropriate tags.
Windows user input fixed
A bug on Windows caused user input prompts (e.g. for confirming apply) to stop working after subprocess execution. Terragrunt now saves and restores console state around every subprocess execution and re-enables Virtual Terminal processing.
Authentication during queue construction fixed
A bug in the logic for parsing configurations during discovery for use-cases like --filter 'reading=*' where configurations need to be parsed to determine whether or not they end up in the final run queue has been fixed. Configurations will now properly call any configured --auth-provider-cmd authenticator before parsing configurations, preventing errors for HCL functions like sops_decrypt_file that require authentication before parsing can proceed.
hcl fmt on unintended files during scaffold fixed
A bug caused hcl fmt to run on files that weren't generated by scaffold. Formatting is now scoped to only scaffolded content.
Input precision loss fixed
A bug in the way Terragrunt handled setting of OpenTofu/Terraform inputs from numbers resulted in precision loss. That bug has been fixed.
π Documentation Updates
1.0 Guarantees
A living document named Terragrunt 1.0 Guarantees has been added to the Terragrunt website clarifying what is and isn't considered a breaking change for the duration of 1.0.
Over time, as ambiguity in edge-cases for what is considered a breaking change are addressed, the page will be updated so that you can be confident your workflows won't be impaired.
llms.txt added
An /llms.txt route has been added to the Terragrunt website to make it easier for LLMs to consume Terragrunt documentation in Markdown format.
New Home for the Terragrunt website!
The Terragrunt website is now hosted at https://terragrunt.com and https://docs.terragrunt.com for marketing and documentation purposes, respectively.
Existing links to https://terragrunt.gruntwork.io should seamlessly redirect to the new domain that hosts the content for that URI.
π§ͺ Experiments Updated
Engines now use GitHub environment variables for downloads
When downloading engines using the engine experiment, Terragrunt will detect and leverage the GH_TOKEN and GITHUB_TOKEN environment variables if present to authenticate with the GitHub API while performing release discovery and download of engines.
βοΈ Process Updates
Go bumped to v1.26
The version of Golang used to compile the Terragrunt binary has been updated to v1.26.0.
OpenTofu/Terraform Compatibility Updated
Terragrunt is now continuously tested against OpenTofu 1.11.4 and Terraform 1.14.4 in CI.
AWS and GRPC dependencies update
Updated AWS SDK and gRPC dependencies to pick up the latest bug fixes and security patches:
- google.golang.org/grpc to v1.79.1
- github.com/aws/aws-sdk-go-v2/config to v1.32.8
- github.com/aws/aws-sdk-go-v2/credentials to v1.19.8
What's Changed
- feat: Improving filter parsing errors by @yhakbar in #5413
- feat: Adding community invite link redirect by @yhakbar in #5432
- feat: .terragrunt-cache directory creation by @denis256 in #5402
- feat: use github auth for engine release checks / downloads by @thisguycodes in #5447
- feat: Adding --no-hidden flag to discovery commands and deprecating --hidden by @yhakbar in #5450
- feat: Adding tip system by @yhakbar in #5434
- fix: Addressing bucket verification flake by @yhakbar in #5419
- fix: Fixing TestTerragruntDestroyOrder flake by @yhakbar in #5427
- fix: Adding lock files to cache key for provider cache by @yhakbar in #5430
- fix: Fixing TestSopsDecryptOnMissing test by @yhakbar in #5428
- fix: Fixing TestTerragruntStackCommandsWithSymlinks test by @yhakbar in #5426
- fix: Adding timeout and avoiding null caching in GitHub API memoization in docs by @yhakbar in #5429
- fix: fixing TestTerragruntDestroyOrderWithQueueIgnoreErrors flake by @thisguycodes in #5436
- fix: Fixing usage of %w in logs by @yhakbar in #5441
- fix: Updating --auth-provider-cmd schema in flags docs by @yhakbar in #5435
- fix: Fixing TestAwsBootstrapBackendWithAccessLoggingFlake by @yhakbar in #5442
- fix: Fixing null input passing by @yhakbar in #5455
- fix: Fixing flake in TestDeprecatedDefaultCommand_TerraformSubcommandCliArgs by @yhakbar in #5456
- fix: Addressing review feedback on #5455 by @yhakbar in #5459
- fix: Fixing TestAwsS3SSECustomKey by @yhakbar in #5457
- fix: Use helpers.CopyEnvironment wherever there's a test with side-effects by @yhakbar in #5460
- fix: Handle registry timeouts in provider cache server by @yhakbar in #5471
- fix: Adding test for init-from-module and improving discoverability by @yhakbar in #5491
- fix: Fixing over-warning on strict controls by @yhakbar in #5501
- fix: Emit output from run_cmd when included by @yhakbar in #5495
- fix: Fixing provider cache server integration with custom registry by @yhakbar in #5500
- fix: Fixing exclude no_run behavior by @yhakbar in #5506
- fix: Adding --report-file support to single runs by @yhakbar in #5507
- fix: Removing path manipulation in log messages by @yhakbar in #5489
- fix: Fixing cache server absolute URLs in self-discovery by @yhakbar in #5519
- fix: SOPS decryption env variables locking by @denis256 in #5522
- fix: Fixing respect for version constraints when running a stack by @yhakbar in #5516
- fix: Fixing signal propagation by @yhakbar in #5518
- fix: Addressing render --format=json by @yhakbar in #5511
- fix: Fixing partial parse config cache by @yhakbar in #5538
- fix: Using SyncWriter to fix TestTerragruntReportWithUnitTiming flakes by @yhakbar in #5494
- fix: Adjusting engine output by @yhakbar in #5386
- fix: Assume any transport errors to discovery URL are a sign that the user is offline by @yhakbar in #5615
- fix: duplicate error reporting in worker pool by @anuragrao04 in #5526
- fix: Fixing #3514 by @yhakbar in #5739
- fix: Fixing #4556 by @yhakbar in #5640
- fix: Fixing -detailed-exitcode when used in combination with --working-dir by @yhakbar in #5590
- fix: Fixing hcl fmt on unintended files during scaffold by @yhakbar in #5721
- fix: Fixing CORS for terragrunt.com by @yhakbar in #5631
- fix: Fixing incremental lint issue by @yhakbar in #5592
- fix: Fixing provider cache lock file corruption by @yhakbar in #5692
- fix: Fixing redirect for /contact-tgs by @yhakbar in #5636
- fix: Fixing relative paths in tracked reading files by @yhakbar in #5651
- fix: Fixing SOPS call during queue construction by @yhakbar in #5722
- fix: handling of backend init when disable_init=true by @denis256 in #5594
- fix: handling of invalid paths in read_terragrunt_config by @denis256 in #5753
- fix: Improving error message for undefined flags by @yhakbar in #5571
- fix: Increasing accuracy of retryable errors match by @yhakbar in #5568
- fix: Moving tagging to bucket creation by @yhakbar in #5706
- fix: Removing usage of filepath.Abs in production code and reducing usage of filepath.ToSlash by @yhakbar in #5597
- fix: variables values interpolation by @denis256 in #5585
- fix: fixed bootstrap and use_lockfile by @denis256 in #5665
- fix: handling of tofu extensions by @denis256 in #5675
- fix: windows user input fixes by @denis256 in #5710
- fix: worktree fixes for read_terragrunt_config by @denis256 in #5682
- docs: Memoizing latest release call by @yhakbar in #5424
- docs: Adding 1.0 guarantees by @yhakbar in #5425
- docs: Update terminology to use the new root.hcl pattern by @hashlash in #5135
- docs: Change move command to copy and corrected supporting text in quick st⦠by @therealgglggl in #5332
- docs: Add output_dir to inputs in multiple sections by @therealgglggl in #5334
- docs: add instructions on bypassing tflint integration behavior by @thisguycodes in #5437
- docs: tweak opening wording of stacks generate by @thisguycodes in #5443
- docs: Adding llms.txt by @yhakbar in #5449
- docs: Update provider cache documentation to include a valid command by @CodyRay in #5276
- docs: Adding --tip and --no-tips docs by @yhakbar in #5468
- docs: remove lint meta comment that's getting displayed on the site by @thisguycodes in #5470
- docs: install page checksum signature check by @denis256 in #5473
- docs: New ambassador by @karlcarstensen in #5496
- docs: Simple component for pagefind styles by @karlcarstensen in #5523
- docs: Pagefind css by @karlcarstensen in #5524
- docs: Fix command reference in CLI redesign documentation by @PedroMartinSteenstrup-htg in #5541
- docs: Adding Golang compatibility notes by @yhakbar in #5544
- docs: Breaking down filters docs by @yhakbar in #5552
- docs: Revert css fixes now that docs site is live by @karlcarstensen in #5556
- docs: Making filter docs a bit more consistent by @yhakbar in #5557
- docs: Adding callout for the lack of library compatibility guarantees by @yhakbar in #5564
- docs: Adding a changelog by @yhakbar in #5754
- docs: Adding changelog copy button by @yhakbar in #5755
- docs: Adding more v1.0.0 changelog docs by @yhakbar in #5756
- docs: Adding tgs discord link by @yhakbar in #5750
- docs: Addressing docs gaps by @yhakbar in #5742
- docs: Breaking down features by @yhakbar in #5684
- docs: compatibility table updates by @denis256 in #5609
- docs: Documenting --queue-strict-include deprecation in strict controls by @yhakbar in #5581
- docs: Documenting deprecation of --disable-dependent-modules by @yhakbar in #5539
- docs: Fix 'move' to 'moved' block in documentation by @hashlash in #5661
- docs: Fix typo in overview documentation by @BenjaminHerbert in #5666
- docs: Fixing 404s by @yhakbar in #5637
- docs: Fixing Migrating Deprecated Attributes by @yhakbar in #5638
- docs: Moving docs-starlight to docs by @yhakbar in #5635
- docs: Updating dependency-fetch-output-from-state experiment docs by @yhakbar in #5740
- docs: Updating docs dependencies by @yhakbar in #5686
- docs: Fix theme light/dark by @karlcarstensen in #5669
- docs: Fixing button by @karlcarstensen in #5667
- docs: Hide switcher in hamburger menu by @karlcarstensen in #5668
- docs: Setting up migration to docs.terragrunt.com by @yhakbar in #5514
- chore: removal of unused AssumeAlreadyApplied field by @denis256 in #5417
- chore: IaC tool CLI arguments re-ordering by @denis256 in #5414
- chore: IAC tool cli building improvements by @denis256 in #5448
- chore: Adding fuzz tests for filter by @yhakbar in #5420
- chore: Remove tflint by @thisguycodes in #5433
- chore: Using slim runners where possible by @yhakbar in #5461
- chore: iac cli package by @denis256 in #5462
- chore: removed unused public functions and constants by @denis256 in #5472
- chore: go bump to 1.25.6 by @denis256 in #5481
- chore: IaC update - Terraform 1.14.4 Opentofu 1.11.4 by @denis256 in #5479
- chore: Updates the discord link by @karlcarstensen in #5521
- chore: Adding testing for RelPathForLog by @yhakbar in #5513
- chore: dependencies update - otel, aws, go-git by @denis256 in #5533
- chore: removed unused constatns, simplified noRun checking by @denis256 in #5517
- chore: Adding VFS testing by @yhakbar in #5490
- chore: Bumping Go to 1.26 by @yhakbar in #5543
- chore: Remote config parsing improvements by @denis256 in #5540
- chore: Refactor discovery for nuanced parse handling by @yhakbar in #5477
- chore: Units code cleanup by @denis256 in #5550
- chore(deps): bump aws-actions/configure-aws-credentials from 5 to 6 by @dependabot[bot] in #5553
- chore: SOPS tests improvements by @denis256 in #5554
- chore: Removing options from components by @yhakbar in #5551
- chore: refactor cache dir exclusion code by @healthy-pod in #5559
- chore: Clean up of #5559 by @yhakbar in #5561
- chore: Adding lll lint incrementally by @yhakbar in #5582
- chore: Adding terragrunt-infrastructure-live-stacks-example test by @yhakbar in #5703
- chore: Adding external testing for config by @yhakbar in #5653
- chore: Adding some testing for logs by @yhakbar in #5641
- chore: Adding test to verify that the Provider Cache Server is used when fetching outputs from dependencies by @yhakbar in #5611
- chore: Addressing #5589 feedback by @yhakbar in #5633
- chore: Addressing #5707 feedback by @yhakbar in #5712
- chore: addressing PR #5665 feedback by @denis256 in #5696
- chore: Addressing review feedback from #5597 by @yhakbar in #5604
- chore: aws-sdk-go-v2 dependency update by @denis256 in #5747
- chore: aws-sdk-go-v2 version bump by @denis256 in #5610
- chore: CICD base tests performance improvements by @denis256 in #5505
- chore: Cleaning up shell scripts by @yhakbar in #5707
- chore: Compile filter globs earlier by @yhakbar in #5574
- chore: cosign v4 upgrade by @denis256 in #5676
- chore: dead code removal by @denis256 in #5683
- chore: go dependencies update by @denis256 in #5634
- chore: go-getter upgrade 1.8.5 by @denis256 in #5691
- chore: GRPC and AWS dependencies update by @denis256 in #5572
- chore: handling of terragrunt and stack files by @denis256 in #5645
- chore: improved log message for failing hooks by @denis256 in #5603
- chore: lint cache key update by @denis256 in #5588
- chore: Moving filters to opts by @yhakbar in #5591
- chore: Moving permissions down to job level when possible by @yhakbar in #5705
- chore: Multiple dependencies bump by @denis256 in #5673
- chore: Pinning workflows further by @yhakbar in #5704
- chore: Re-enabling rustfs test by @yhakbar in #5751
- chore: Reducing dependency on opts in config - Part Four by @yhakbar in #5573
- chore: Reducing dependency on opts in config - Part Three by @yhakbar in #5569
- chore: Reducing dependency on opts in config - Part Two by @yhakbar in #5563
- chore: Reducing dependency on opts in config by @yhakbar in #5560
- chore: Removing options from awshelper by @yhakbar in #5587
- chore: Removing options from runner and remotestate by @yhakbar in #5589
- chore: Removing explicit mise cache by @yhakbar in #5694
- chore: Removing imports of options from tf by @yhakbar in #5583
- chore: Removing options from shell by @yhakbar in #5584
- chore: Removing Terratest dependency by @yhakbar in #5614
- chore: Reverting tmpfs mount by @yhakbar in #5744
- chore: sops upgrade to 3.12.2 by @denis256 in #5718
- chore: sops v3.12.1 gcp storage v1.60.0 by @denis256 in #5618
- chore: Temporarily skipping rustfs test by @yhakbar in #5749
- chore: upgraded github.com/buger/jsonparser to v1.1.2 by @denis256 in #5729
- chore: Verifying fix for #3080 by @yhakbar in #5639
- chore(deps): bump @astrojs/vercel from 10.0.0 to 10.0.2 in /docs by @dependabot[bot] in #5741
- chore(deps): bump actions/download-artifact from 7.0.0 to 8.0.0 by @dependabot[bot] in #5626
- chore(deps): bump actions/download-artifact from 8.0.0 to 8.0.1 by @dependabot[bot] in #5698
- chore(deps): bump actions/setup-go from 6.2.0 to 6.3.0 by @dependabot[bot] in #5628
- chore(deps): bump actions/stale from 10.1.1 to 10.2.0 by @dependabot[bot] in #5600
- chore(deps): bump actions/upload-artifact from 6.0.0 to 7.0.0 by @dependabot[bot] in #5627
- chore(deps): bump digicert/ssm-code-signing from 1.1.1 to 1.2.1 by @dependabot[bot] in #5527
- chore(deps): bump fast-xml-parser, @aws-sdk/client-s3, @aws-sdk/client-dynamodb, @aws-sdk/lib-dynamodb and @aws-sdk/s3-request-presigner in /docs-starlight/src/fixtures/terralith-to-terragrunt/app/best-cat by @dependabot[bot] in #5578
- chore(deps): bump github.com/cloudflare/circl from 1.6.1 to 1.6.3 in /test/flake by @dependabot[bot] in #5620
- chore(deps): bump google.golang.org/grpc from 1.79.2 to 1.79.3 by @dependabot[bot] in #5708
- chore(deps): bump handlebars from 4.7.8 to 4.7.9 in /docs/src/fixtures/terralith-to-terragrunt/app/best-cat by @dependabot[bot] in #5745
- chore(deps): bump jdx/mise-action from 3.6.1 to 3.6.2 by @dependabot[bot] in #5647
- chore(deps): bump jdx/mise-action from 3.6.2 to 3.6.3 by @dependabot[bot] in #5678
- chore(deps): bump jdx/mise-action from 3.6.3 to 4.0.0 by @dependabot[bot] in #5699
- chore(deps): bump mikepenz/action-junit-report from 6.1.0 to 6.3.1 by @dependabot[bot] in #5697
- chore(deps): bump the js-dependencies group across 1 directory with 9 updates by @dependabot[bot] in #5602
- chore: tests coverage collection by @denis256 in #5717
- build(deps): bump sigstore/cosign-installer from 3.10.1 to 4.0.0 by @dependabot[bot] in #5486
- chore: Revert "build(deps): bump sigstore/cosign-installer from 3.10.1 to 4.β¦ by @yhakbar in #5656
- perf: speed up EncodeSourceVersion by using SkipDir by @healthy-pod in #4533
- perf: Adding discovery benchmark by @yhakbar in #5562
New Contributors
- @hashlash made their first contribution in #5135
- @therealgglggl made their first contribution in #5332
- @CodyRay made their first contribution in #5276
- @PedroMartinSteenstrup-htg made their first contribution in #5541
- @healthy-pod made their first contribution in #4533
- @anuragrao04 made their first contribution in #5526
- @BenjaminHerbert made their first contribution in #5666
Full Changelog: v0.99.5...v1.0.0
Original source - Mar 26, 2026
- Date parsed from source:Mar 26, 2026
- First seen by Releasebot:Mar 27, 2026
v0.99.5
Terragrunt fixes working-dir exit code handling and improves queue construction authentication, so config parsing now runs auth providers before HCL evaluation and avoids errors with functions like sops_decrypt_file.
π Bug Fixes
--working-dir interaction with exit codes fixed
A bug in the logic for tracking exit codes for plan -detailed-exitcode when users supply the --working-dir flag has been fixed.
Authentication during queue construction fixed
A bug in the logic for parsing configurations during discovery for use-cases like --filter 'reading=*' where configurations need to be parsed to determine whether or not they end up in the final run queue has been fixed. Configurations will now properly call any configured --auth-provider-cmd authenticator before parsing configurations, preventing errors for HCL functions like sops_decrypt_file that require authentication.
What's Changed
chore: Backporting #5590 by @yhakbar in #5593
chore: Backporting #5722 by @yhakbar in #5731
Full Changelog: v0.99.4...v0.99.5
Original source - Mar 20, 2026
- Date parsed from source:Mar 20, 2026
- First seen by Releasebot:Mar 21, 2026
alpha-2026032001
Terragrunt ships an alpha release with WIP fixes for sops_decrypt_file, --auth-provider-cmd, and --filter 'reading=', plus bug fixes, docs updates, dependency bumps, and workflow cleanup.
β οΈ Alpha Release
Alpha release including WIP work to fix the combination of sops_decrypt_file + --auth-provider-cmd + --filter 'reading=' from the following PR:
#5722
What's Changed
- docs: Fix 'move' to 'moved' block in documentation by @hashlash in #5661
- Fix theme light/dark by @karlcarstensen in #5669
- Hide switcher in hamburger menu by @karlcarstensen in #5668
- Fixing button by @karlcarstensen in #5667
- bug: handling of tofu extensions by @denis256 in #5675
- chore: cosign v4 upgrade by @denis256 in #5676
- chore: dead code removal by @denis256 in #5683
- docs: Fix typo in overview documentation by @BenjaminHerbert in #5666
- chore(deps): bump jdx/mise-action from 3.6.2 to 3.6.3 by @dependabot[bot] in #5678
- docs: Updating docs dependencies by @yhakbar in #5686
- chore: Multiple dependencies bump by @denis256 in #5673
- docs: Breaking down features by @yhakbar in #5684
- chore: go-getter upgrade 1.8.5 by @denis256 in #5691
- chore: Removing explicit mise cache by @yhakbar in #5694
- bug: fixed bootstrap and use_lockfile by @denis256 in #5665
- chore: addressing PR #5665 feedback by @denis256 in #5696
- chore(deps): bump mikepenz/action-junit-report from 6.1.0 to 6.3.1 by @dependabot[bot] in #5697
- chore(deps): bump actions/download-artifact from 8.0.0 to 8.0.1 by @dependabot[bot] in #5698
- fix: Fixing provider cache lock file corruption by @yhakbar in #5692
- chore(deps): bump jdx/mise-action from 3.6.3 to 4.0.0 by @dependabot[bot] in #5699
- chore: Adding terragrunt-infrastructure-live-stacks-example test by @yhakbar in #5703
- bug: worktree fixes for read_terragrunt_config by @denis256 in #5682
- chore: Moving permissions down to job level when possible by @yhakbar in #5705
- chore: Pinning workflows further by @yhakbar in #5704
- chore(deps): bump google.golang.org/grpc from 1.79.2 to 1.79.3 by @dependabot[bot] in #5708
- chore: Adding some testing for logs by @yhakbar in #5641
- fix: Moving tagging to bucket creation by @yhakbar in #5706
- chore: Cleaning up shell scripts by @yhakbar in #5707
- chore: Addressing #5707 feedback by @yhakbar in #5712
- bug: windows user input fixes by @denis256 in #5710
- chore: sops upgrade to 3.12.2 by @denis256 in #5718
New Contributors
- @BenjaminHerbert made their first contribution in #5666
Full Changelog: v1.0.0-rc3...alpha-2026032001
Original source - Mar 19, 2026
- Date parsed from source:Mar 19, 2026
- First seen by Releasebot:Mar 19, 2026
alpha-2026031901
Terragrunt releases an alpha-style changelog for v1.0.0-rc3...alpha-2026031901, highlighting testing updates, bug fixes, numerous dependency bumps, and new contributor notes, signaling ongoing development and prep for a broader release.
β οΈ Alpha Release
Release scripts testing
What's Changed
- docs: Fix 'move' to 'moved' block in documentation by @hashlash in #5661
- Fix theme light/dark by @karlcarstensen in #5669
- Hide switcher in hamburger menu by @karlcarstensen in #5668
- Fixing button by @karlcarstensen in #5667
- bug: handling of tofu extensions by @denis256 in #5675
- chore: cosign v4 upgrade by @denis256 in #5676
- chore: dead code removal by @denis256 in #5683
- docs: Fix typo in overview documentation by @BenjaminHerbert in #5666
- chore(deps): bump jdx/mise-action from 3.6.2 to 3.6.3 by @dependabot[bot] in #5678
- docs: Updating docs dependencies by @yhakbar in #5686
- chore: Multiple dependencies bump by @denis256 in #5673
- docs: Breaking down features by @yhakbar in #5684
- chore: go-getter upgrade 1.8.5 by @denis256 in #5691
- chore: Removing explicit mise cache by @yhakbar in #5694
- bug: fixed bootstrap and use_lockfile by @denis256 in #5665
- chore: addressing PR #5665 feedback by @denis256 in #5696
- chore(deps): bump mikepenz/action-junit-report from 6.1.0 to 6.3.1 by @dependabot[bot] in #5697
- chore(deps): bump actions/download-artifact from 8.0.0 to 8.0.1 by @dependabot[bot] in #5698
- fix: Fixing provider cache lock file corruption by @yhakbar in #5692
- chore(deps): bump jdx/mise-action from 3.6.3 to 4.0.0 by @dependabot[bot] in #5699
- chore: Adding terragrunt-infrastructure-live-stacks-example test by @yhakbar in #5703
- bug: worktree fixes for read_terragrunt_config by @denis256 in #5682
New Contributors
- @BenjaminHerbert made their first contribution in #5666
Full Changelog: v1.0.0-rc3...alpha-2026031901
Original source - Mar 10, 2026
- Date parsed from source:Mar 10, 2026
- First seen by Releasebot:Mar 11, 2026
alpha-2026031001
Gruntwork highlights Cosign v4 alpha release test with minor doc and UI fixes, signaling an early access build overall.
β οΈ Alpha Release
Cosign v4 signing test
What's Changed
- docs: Fix 'move' to 'moved' block in documentation by @hashlash in #5661
- Fix theme light/dark by @karlcarstensen in #5669
- Hide switcher in hamburger menu by @karlcarstensen in #5668
- Fixing button by @karlcarstensen in #5667
Full Changelog: v1.0.0-rc3...alpha-2026031001
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.
Similar to Gruntwork with recent updates:
- Smokeball release notes129 release notes Β· Latest Jun 10, 2026
- Cosmolex release notes20 release notes Β· Latest Jul 30, 2025
- PracticePanther release notes34 release notes Β· Latest Apr 8, 2026
- Salesforce release notes14 release notes Β· Latest Jun 10, 2026
- Zoom release notes166 release notes Β· Latest Jun 1, 2026
- Hubspot release notes129 release notes Β· Latest Jun 10, 2026