๐ 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
excludeblock setno_run, or - the
catalogblock setdefault_template,no_shell, orno_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
renderWriteToby @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-gofrom 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
catalogscaffold by @yhakbar in #6162 - chore: Plumbing in
vfstogetterby @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-dirusage by @FernandoArteaga-telus in #6176 - fix: Fixing
mark-many-as-readfor 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-commonsdependency by @yhakbar in #6180 - fix: Fixing
download_dircopy 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