Skip to content

chore(deps): update dependency terragrunt to v1.1.4 - #30538

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/terragrunt-1.x
Open

chore(deps): update dependency terragrunt to v1.1.4#30538
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/terragrunt-1.x

Conversation

@renovate

@renovate renovate Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Type Update Change
terragrunt tools patch 1.1.11.1.4
terragrunt tools minor 1.1.11.1.4

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Release Notes

gruntwork-io/terragrunt (terragrunt)

v1.1.4

Compare Source

✨ New Features

duplicate-dependency-labels strict control

Declaring two dependency blocks with the same label in one terragrunt.hcl configuration file parsed without error, and then quietly resolved every reference to that label to whichever block came last. The blocks before it were silently overridden:

dependency "vpc" {
  config_path = "../vpc-us-east-1"
}

dependency "vpc" {
  config_path = "../vpc-us-west-2"
}

inputs = {
  # Reads ../vpc-us-west-2.
  vpc_id = dependency.vpc.outputs.vpc_id
}

Terragrunt now warns when it finds this. With the new duplicate-dependency-labels strict control enabled, the warning becomes an error naming the address the blocks share:

terragrunt run plan --strict-control duplicate-dependency-labels
/path/to/terragrunt.hcl: dependency vpc is declared more than once; every dependency needs an address of its own

Give each block a label of its own. A configuration that was relying on the shadowing to pick the last block should keep only that block.

scaffold asks for values interactively

Scaffolding from the command line wrote # TODO placeholders for every input and left you to fill them in by hand, while scaffolding the same component from the Catalog TUI opened a form and collected them. terragrunt scaffold now opens that same form:

terragrunt scaffold github.com/gruntwork-io/terragrunt-infrastructure-modules-example//modules/mysql

For a module or a template it lists the source's variables; for a unit or a stack it lists the values.* references its configuration makes, which are written to terragrunt.values.hcl. Dismissing the form with esc writes nothing.

The form is skipped, and the placeholders written as before, when you pass --non-interactive, when stdin is not a terminal, or when the source asks for nothing. A scaffold in a CI job, or one run by another program, therefore behaves exactly as it did.

See Scaffold for the full behavior, and the form's keybindings for driving it.

🏎️ Performance Improvements

Faster startup when --tf-path is not set

When you don't set --tf-path, Terragrunt picks the binary it wraps by looking for tofu on your PATH and falling back to terraform when it isn't there. Terragrunt used to make that choice by running tofu -version, which meant launching a process at the start of every command, including commands like find and list that never run the binary. That process launch is gone, and a terragrunt --version benchmark runs roughly 1.7x faster as a result.

This changes what happens when tofu is on your PATH but can't run: Terragrunt now selects it and reports the failure rather than silently falling back to terraform. Set --tf-path or TG_TF_PATH to pick the binary yourself.

🐛 Bug Fixes

Autoinclude dependency overrides no longer evaluate replaced paths

Terragrunt used to evaluate a dependency's original config_path before applying a sibling autoinclude override. This could prevent a unit from being parsed when the original path referenced a value that the unit no longer supplied, even though the autoinclude replaced that path. Terragrunt now leaves replaced dependency blocks undecoded, then applies the autoinclude override. Dependency blocks without an autoinclude override are still validated.

Blocks that use expansion are still decoded, because a bare autoinclude label does not name their instances. If the autoinclude also declares the same label without expansion, Terragrunt reports a dependency label collision.

Fixed Git sources with a depth query parameter

A terraform.source (or stack source) URL carrying the go-getter depth query parameter, such as ...vpc.git?depth=1&ref=v5.21.0, failed to download since v1.1.0, when the CAS became the default path for Git sources. Terragrunt lifted ref out of the URL but left depth in place, so git received ...vpc.git?depth=1 and rejected it as an invalid repository name. A URL with depth and no ref hit the same failure.

Terragrunt now strips depth, with or without a ref, before invoking git, so these sources download again. The clone depth itself always comes from --cas-clone-depth, which defaults to 1; a depth on a source URL is never applied for CAS clones.

CAS handles local sources that have already been initialized

With CAS enabled, reading a local source that had already been initialized failed and fell back to the slower standard copy. Generating a stack from such a unit logged CAS processing failed ... source escapes repository root.

Provider caching was the cause. Both the Provider Cache Server and the Automatic Provider Cache Dir leave the plugins under .terraform pointing into a shared cache outside the source. CAS read those links as the source reaching outside itself and refused to copy the link for safety.

CAS now leaves .terraform and .terragrunt-cache out of local sources, keeping .terraform.lock.hcl and everything else. OpenTofu, Terraform, and Terragrunt rebuild both directories on demand, so units and stacks no longer receive a stale copy of either. Running tofu init in a source directory no longer changes that source's CAS key.

Fixed the signal sent to a running command during shutdown

On Windows, when a failure rather than Ctrl+C cancelled a run, Terragrunt crashed with a nil pointer panic instead of stopping the command it had started. It now terminates the command, which is the closest thing Windows offers to an interrupt.

On every platform, when a command exited on its own during the grace period after Ctrl+C, Terragrunt could still send it the signal and then log a forwarding error against a process that was already gone.

terraform_binary respected when reading dependency outputs

Reading a dependency block's outputs ignored the terraform_binary of the unit being read and fell back to the auto-detected binary, which is OpenTofu whenever tofu is on your PATH. With terraform_binary = "terraform", a unit ran through Terraform while the dependency it consumed was read through OpenTofu. A run --all over units that each worked on their own then failed with a backend initialization error, followed by a misleading There is no variable named "dependency".

Dependency outputs are now read through the binary the dependency itself configures, so a unit's terraform_binary applies wherever its state is read. --tf-path and TG_TF_PATH still take precedence over the config value.

Numbers with extreme exponents fail fast instead of stalling

A number literal such as 9E9999999 in inputs, locals, or a dependency block's mock_outputs used to cost over a minute of CPU on a single unit. Written out in decimal that number is ten million digits long, and terragrunt render --format=json produced every digit before failing with a ten megabyte error message.

Terragrunt now rejects numbers larger than 1e4096, and non-zero numbers smaller than 1e-4096, before it tries to write them out, and names the attribute holding the value:

count: number is outside the supported range of 1e-4096 to 1e4096

Numbers inside that range are unaffected.

Registry credentials are no longer copied into the generated CLI config

When the Provider Cache Server is enabled, Terragrunt writes a CLI config for OpenTofu/Terraform into each unit's working directory, based on your own CLI config. That generated file used to include a copy of every credentials block from your config, including the ones for registries Terragrunt routes through the cache server.

Those copies were never read. For a routed registry, Terragrunt sets the matching TF_TOKEN_<hostname> environment variable, which takes precedence over a credentials block, and the cache server presents your real credentials when it contacts the registry on your behalf. The generated file now leaves the block out for those registries, so your token stays in the CLI config you put it in instead of being duplicated somewhere it had no effect.

Credentials for hosts the cache server does not route are unchanged, since OpenTofu/Terraform contacts those directly and still reads them from the generated config.

Upgrading does not rewrite the files an earlier version already generated. Each is named .terraformrc and sits in a unit's working directory, which is under .terragrunt-cache for remote sources. Delete those files, or clear the cache, to get the copied credentials off disk.

Generated files are readable only by the user who ran Terragrunt

Terragrunt created several files and directories that other users on the same machine could read:

  • The CLI config Terragrunt writes for OpenTofu/Terraform when the Provider Cache Server is enabled, and the directory holding it.
  • The JSON plan files written to --json-out-dir, and that directory.
  • The directories holding the plan files written to --out-dir.
  • The config written by render --write, which holds the resolved values of inputs, locals, and dependency outputs.

Terragrunt now creates those files as 0600 and those directories as 0700.

hcl fmt --stdin honors --check and --diff

terragrunt hcl fmt --stdin ignored --check and --diff. It printed the reformatted HCL and exited 0 whether or not the input needed formatting.

--check now exits with status code 1 when the input needs formatting, and --diff prints a unified diff labeled old/stdin and new/stdin. Neither flag prints the formatted content, so getting that content back means running --stdin without them.

hcl validate no longer crashes on errors that carry no source location

terragrunt hcl validate crashed while formatting its output when one of the errors it found had no position in the configuration. Terragrunt now prints that error's summary and detail, without a location line.

Fixed the deprecated environment variables for hcl validate

TG_HCLVALIDATE_STRICT_VALIDATE, the deprecated name for --strict, also turned on --show-config-path. --strict only takes effect alongside --inputs, and --show-config-path cannot be combined with --inputs. With that variable set, terragrunt hcl validate --inputs failed with specifying both -show-config-path and -inputs is invalid.

TG_HCLVALIDATE_SHOW_CONFIG_PATH, the deprecated name for --show-config-path, was not recognized at all.

TG_HCLVALIDATE_STRICT_VALIDATE now sets only --strict, and TG_HCLVALIDATE_SHOW_CONFIG_PATH sets --show-config-path. TG_STRICT_VALIDATE, TERRAGRUNT_STRICT_VALIDATE, and TERRAGRUNT_HCLVALIDATE_SHOW_CONFIG_PATH are unchanged.

Fixed panic on invalid if_disabled value with include block

A generate block with an invalid if_disabled value combined with an include block caused a nil pointer panic instead of a descriptive error. Terragrunt now returns an error naming the generate block and the invalid value, consistent with if_exists validation.

OCI sources reject Docker-style :tag suffixes instead of fetching latest

An oci:// source that pinned a version with a Docker-style suffix, like oci://ghcr.io/acme/modules/vpc:1.0.0, silently ignored the suffix and resolved the latest tag, so a run could fetch a different module version than the one pinned. Terragrunt now validates the registry and repository the same way OpenTofu does and rejects such sources with an error that shows the source rewritten in the supported ?tag=/?digest= form, for example oci://ghcr.io/acme/modules/vpc?tag=1.0.0. Repository names that violate the OCI reference grammar are also rejected before any registry is contacted.

Prompts accept a piped answer that has no trailing newline

Piping an answer to a confirmation prompt, as in printf yes | terragrunt run --all destroy, failed with an EOF error because Terragrunt discarded a final answer that ended without a newline. Terragrunt now reads that final answer, and only a prompt that gets no input at all reports EOF.

Provider cache supports signed provider download URLs

When a provider mirror returned a signed download URL, the Provider Cache Server used the entire URL, including its query string, as the archive filename. Long authentication parameters could exceed filesystem filename limits and fail with file name too long.

Terragrunt now derives the archive filename only from the URL path while preserving the query string when downloading it. Signed provider URLs, including archives in nested object paths and relative mirror URLs, now download and cache correctly.

find and list reject a --queue-construct-as value that holds no command

A value made only of shell punctuation, such as terragrunt find --queue-construct-as=';', ended the run with a crash report. A value that quotes an empty command, such as --queue-construct-as='""', was accepted even though it names no command.

find and list now exit with an error that repeats the value you passed and shows what --queue-construct-as expects instead.

render --write picks a default filename without a format flag

terragrunt render --write failed with is a directory unless it was paired with --format or --json. Only those flags set the default filename, so a bare --write had no output path and Terragrunt tried to write to the unit directory itself.

The default now follows the format in use. terragrunt render --write writes terragrunt.rendered.hcl next to the unit configuration, and --json or --format=json writes terragrunt.rendered.json. An explicit --out still takes precedence.

sops_decrypt_file now uses the credentials your auth provider supplies

When a run obtained credentials from --auth-provider-cmd, sops_decrypt_file ignored them for any variable already set in the environment Terragrunt started with. The rest of the run honored the auth provider, and correctly overrode any ambient environment variables. OpenTofu/Terraform received those credentials, and so did the AWS calls Terragrunt makes on a unit's behalf, such as get_aws_account_id.

Decryption now runs as the identity Terragrunt resolved for the unit, the same one the rest of the run uses, regardless of ambient environment variables.

info strict list <name> now honors --all

Passing a control name to info strict list shows that control's subcontrols. Unlike the top-level listing, it ignored the --all flag and always included completed subcontrols.

Terragrunt now applies the same rule when you name a control.

String inputs reach modules with ${...} intact

Passing a string input that contains ${...} to a variable declared with a type other than string used to fail with Variables not allowed, because OpenTofu/Terraform parse those values as HCL expressions and read ${...} as an interpolation. Reading a JSON or YAML file into an input hit this whenever the file happened to contain that sequence:

inputs = {
  config = file("./config.json")
}

Terragrunt now escapes interpolation sequences in string inputs when the module declares the variable with a type that makes the value parse as HCL, so ${...} arrives as literal text instead of failing the run. Variables declared as string, and variables declared with no type at all, are read verbatim by OpenTofu/Terraform, and their values are still passed through untouched.

🧪 Experiments Updated

Read dependency outputs directly from Azure state

The dependency-fetch-output-from-state experiment can now read dependency outputs directly from Azure Storage (azurerm) state, in addition to S3. This avoids initializing the dependency and running tofu output or terraform output.

Azure direct reads require the azure-backend experiment as well. Unsupported configurations requiring native-only authentication, endpoint, timeout, or customer-provided-key behavior continue to use the native output path.

When a dependency has no state yet, Terragrunt uses that dependency block's mock_outputs, as it already does for S3. When Azure direct reads resolve a storage account key through Azure Resource Manager, which is the case unless access_key, sas_token, or use_azuread_auth is set, a resource_group_name, storage_account_name, or subscription_id naming a resource that does not exist fails with an error naming those keys rather than substituting mock outputs.

Read dependency outputs directly from GCS state

The dependency-fetch-output-from-state experiment can now read dependency outputs directly from GCS state, in addition to S3. This avoids initializing the dependency and running tofu output or terraform output.

Unsupported GCS configurations continue to use the native output path. When a dependency has no state yet, Terragrunt uses that dependency block's mock_outputs, as it already does for S3.

Thanks to @​joshmyers for the original GCS implementation.

render previews what an expanded dependency block expanded to

With the block-iteration experiment enabled, a dependency block that carries an expansion block now renders as it was written, followed by the elements it expanded into, commented out and with their bodies resolved:

$ terragrunt render --experiment block-iteration
dependency "aurora" {
  expansion {
    for_each = toset(["web", "api"])
  }

  config_path = "../aurora-${each.key}"
}

# Expands to:

#
# dependency "aurora" {

#   config_path = "../aurora-api"
# }

#
# dependency "aurora" {

#   config_path = "../aurora-web"
# }

The elements are comments because they aren't valid Terragrunt HCL configurations (you are not allowed to use the same dependency label twice in Terragrunt configurations), the previews are there to help you understand how expansion will resolve.

⚙️ Process Updates

Go bumped to v1.27

The version of Golang used to compile the Terragrunt binary has been updated from v1.26.6 to v1.27.0.

If you build Terragrunt from source, or import it as a Go module, you now need a Go 1.27 toolchain.

OpenTelemetry SDK updated to v1.45.0

Terragrunt's OpenTelemetry tracing and metrics dependencies have been updated from v1.44.0 to v1.45.0. The logging packages and exporters have also been updated to their compatible releases, and Terragrunt now uses the v1.43.0 semantic conventions.

Telemetry behavior is unchanged.

Pull Requests

✨ Features
🐛 Bug Fixes
🏎️ Performance
📖 Documentation
✅ Tests
🤖 CI
🧹 Chores

v1.1.3

Compare Source

🐛 Bug Fixes

Fixed Unsupported attribute errors for values.* inputs that autoinclude overrides

A unit input referencing a values.* key that the unit's values file doesn't define no longer fails with Unsupported attribute when an autoinclude block supplies that input. The autoinclude value is applied as intended.

# stacks/terragrunt.stack.hcl
unit "subnet" {
  source = "../units/subnet"
  path   = "subnet"

  autoinclude {
    dependency "vpc" {
      config_path  = unit.vpc.path
      mock_outputs = { vpc_id = "mock" }
    }

    inputs = {
      vpc_id = dependency.vpc.outputs.vpc_id
    }
  }

  values = {
    cidr_block = "10.0.0.0/24"
  }
}
# units/subnet/terragrunt.hcl
inputs = {
  vpc_id     = values.vpc_id      # supplied by autoinclude, not the values file
  cidr_block = values.cidr_block  # still resolves from values file
}

Fixed overwrite_terragrunt and remove_terragrunt on files with no trailing newline

generate blocks using if_exists = "overwrite_terragrunt" or if_disabled = "remove_terragrunt" failed to properly handle existing files when the file at the target path had no newline after its first line, empty files included.

Terragrunt now properly handles files like this, so a file carrying the Terragrunt signature is overwritten or removed as configured, and a file without it produces the usual error naming the path Terragrunt would not touch.

Dependency mock_outputs apply when the state bucket doesn't exist yet

When reading a dependency's outputs directly from remote state (--dependency-fetch-output-from-state), Terragrunt fell back to mock_outputs only when the state object was missing, not when the S3 bucket itself didn't exist. A dependency on an environment that hadn't been bootstrapped yet would fail instead of using its mocks.

A missing bucket is now treated the same as a missing state object, so commands like plan and validate can resolve mocks before the dependency's backend has been created.

Source permissions preserved on hidden directories copied by include_in_copy

With the fast-copy strict control enabled, a hidden directory that Terragrunt copied due to include_in_copy matching something within it took the permissions of the first file generated within it, instead of the permissions it had in the source.

Those directories now keep their source permissions, matching the copy Terragrunt performs with the control disabled.

Applied the positive half of a filter that begins with a negation

When a --filter query began with a negation, Terragrunt treated the whole query as an exclusion. The expressions chained after the negation stopped restricting the selection and only narrowed what got subtracted, so components matching none of them came back in the results. Those expressions are now applied.

$ terragrunt list
bar  baz  foo
$ terragrunt list --filter '!name=foo | name=bar'
bar  baz  foo
$ terragrunt list --filter '!name=foo | name=bar'
bar

This follows the left-to-right refinement that | has everywhere else: each expression narrows what the one before it selected. A query is only treated as an exclusion when every one of its expressions is negated, such as '!name=foo' or '!name=foo | !name=bar'.

See Combining Expressions for how negation, intersection and union interact.

Fixed a race condition that left cached provider archives in the working directory

With the provider cache server enabled via --provider-cache, a race let the server start responding to requests before it had finished preparing the directories it caches into. A provider requested in that window had its archive and lock file written relative to the working directory instead of into the cache, leaving zip files behind in your project.

That race condition has been fixed. Providers now always download into the cache directory.

Fixed a race condition between concurrent Terragrunt runs downloading providers

A race condition in the logic used to synchronize provider downloads meant that two Terragrunt runs on the same machine could interfere with each other while caching the same provider. Each run staged its downloads at the same path, so a run that finished first could delete an archive another run was still unpacking, failing that run with failed to open zip archive.

That race condition is now fixed. Two runs can cache the same provider at the same time.

Fixed space-delimited flag values in providers lock

The space-delimited form, providers lock -platform linux_amd64, now reaches OpenTofu and Terraform intact. Previously it was the attached form, -platform=linux_amd64, that worked: given the value as a separate argument, Terragrunt moved it to the end of the command, where it was read as a provider address and the run failed with Invalid provider type "linux_amd64".

-fs-mirror and -net-mirror were moved the same way, and now keep their values too.

With --provider-cache enabled, platforms are also split correctly across the per-platform providers lock runs used to warm the cache.

Fixed scaffold on units and stacks

terragrunt scaffold read every source as an OpenTofu/Terraform module. Given a unit or a stack, which are Terragrunt configurations rather than OpenTofu/Terraform modules, it exited successfully having written an invalid terragrunt.hcl file.

Units and stacks are now scaffolded the way the Catalog TUI scaffolds them: their files are copied into the working directory for you to edit in place, along with a terragrunt.values.hcl listing every values.* reference the configuration makes.

terragrunt scaffold 'github.com/gruntwork-io/terragrunt-scale-catalog//units/aws/oidc/iam-oidc-role'

Copying refuses to overwrite: a file that would land on an existing path stops the command before anything is written. Modules and templates are unaffected and are still scaffolded from their variables.

See Scaffold for what gets copied and how the values file is filled in.

Answered every prompt when input is piped in

A run that asks for confirmation more than once, such as terragrunt backend delete prompting for both the lock table entry and the state object, used to read only the first answer when the answers were piped in rather than typed. The remaining answers were discarded while reading ahead, and the next prompt failed with an end-of-input error. Every prompt in a run now reads from the same input, so piping yes for each one works.

Stack dependencies honor mock_outputs with --dependency-fetch-output-from-state

A dependency block that reads outputs from a stack (its config_path points at a terragrunt.stack.hcl directory) used to fail when a unit in that stack had no state yet, even when the dependency declared mock_outputs. This blocked commands like plan and validate against a stack that hadn't been applied.

Such a dependency now falls back to mock_outputs for the units that have no state yet. In a partially applied stack, applied units resolve to their real outputs while the rest use their mocks.

Mocks for a stack dependency are keyed by unit name, so mock_outputs has to be a map or object. Declaring it as any other type now reports that directly, instead of leaving the units it can't cover out of the stack outputs.

Fixed --config= being ignored by the tflint hook

The built-in tflint hook reads the configuration file out of the arguments you give it, then uses that path for tflint init and for the lint run. It only recognized the space-separated --config <path> spelling, so a hook written as:

before_hook "tflint" {
  commands = ["plan"]
  execute  = ["tflint", "--config=custom.tflint.hcl"]
}

was treated as though no configuration file had been named at all. Terragrunt searched the unit directory and its parents for a .tflint.hcl file instead, and either failed with a config-not-found error or ran tflint init against whatever unrelated configuration the search turned up. Terragrunt now recognizes --config <path>, --config=<path>, -c <path>, and -c=<path>.

The hook also builds --var arguments from the unit's inputs and from TF_VAR_ entries in extra_arguments blocks. Those arguments came out in a different order on every run, which made the logged command line, and anything comparing it between runs, needlessly unstable. They are now ordered by variable name.

🧪 Experiments Added

block-iteration experiment reserves the expansion block

The block-iteration experiment has been added as the gate for iterating a dependency, unit, or stack block over a count or for_each, declared through a nested expansion block, along with an enabled attribute on unit and stack blocks.

In this release the flag is reserved only, and enabling it has no behavioral effect. Writing an expansion block without the experiment now reports an error naming the flag, rather than leaving the block to be silently discarded:

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

Track progress and share feedback in #​4504.

bounded-discovery — Added a directory boundary for graph traversal

Filter expressions that traverse the dependency graph reach beyond the working directory: dependents (--filter '...{unit}') by walking up to the Git repository root, dependencies (--filter '{unit}...') by following declared paths. Either way, Terragrunt reads and parses every configuration it touches. In monorepos with isolated environments, that traversal can fail or do wasted work reading sibling environments.

Enable the new bounded-discovery experiment to set a boundary for that traversal. The --discovery-boundary flag (env: TG_DISCOVERY_BOUNDARY) replaces the Git repository root as the enclosure for a whole run:

cd environments/staging
terragrunt run --all plan --experiment bounded-discovery --filter '...{vpc}' --discovery-boundary .

The experiment also unlocks an inline (dir) boundary operand, which bounds a single expression and overrides the flag. It occupies the same slot as a traversal depth, so it bounds discovery by location the way a number bounds it by graph hops:

cd environments/staging
terragrunt run --all plan --experiment bounded-discovery --filter '(.)...{vpc}'

Any configuration that resolves outside the boundary, whether a dependent or a dependency, is not read, parsed, or returned: find does not list it and run --all does not run it. Configurations inside the boundary are discovered as usual.

The boundary must be an existing directory, and relative paths are resolved against the working directory. Dependent traversal searches upward from the working directory, so filters that use it also need the boundary to be the working directory or one of its parents. Dependency traversal follows declared paths from the units a filter matched, so dependency-only filters accept any directory, including one below the working directory:

# From the repository root, follow app's dependencies but keep them within prod
terragrunt find --experiment bounded-discovery --filter '{./prod/app}...' --discovery-boundary ./prod

Reserving ( and ) for the boundary operand changes how --filter reads those characters everywhere, not only when the experiment is enabled. An expression such as --filter '1...(foo | bar)' previously matched a unit literally named (foo or bar); it is now rejected as a malformed boundary. Wrap a name or path containing parentheses in braces (e.g. --filter '{./weird(name)}') to keep it literal.

browse-tui — Added an interactive browser for your estate

The new browse-tui experiment adds the terragrunt browse command. With the experiment enabled, terragrunt browse opens a three-column Terminal User Interface (TUI) browser of your infrastructure estate: the parent directory on the left, the current directory in the middle, and a detail pane on the right showing metadata for the highlighted unit, stack, or directory. The browser opens immediately and fills in metadata as discovery completes in the background.

browse-navigation

Enable it with --experiment browse-tui or TG_EXPERIMENT=browse-tui. See the experiment documentation for the keybindings, search, and the criteria for stabilization.

mutable-generate — Deduplicated generate block output

The mutable-generate experiment has been added. With it enabled, the contents a generate block produces are stored in the Content Addressable Store (CAS), and the file written at path is a read-only link to that stored copy rather than a file of its own.

Since the stored copy is addressed by the hash of its contents, anything generating identical contents links to the same copy. A generate block inherited by several hundred units therefore costs one copy in .terragrunt-cache rather than several hundred.

The link is read-only because that copy is shared. Where a generated file does need to be edited in place, a new mutable attribute on the generate block gives it a writable file of its own:

generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite"
  mutable   = true
  contents  = "..."
}

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

For details, see the experiment documentation.

optional-dependency-outputs — Added --no-dependency-outputs flag to skip dependency output resolution

Added a --no-dependency-outputs flag that skips all dependency output resolution globally, mirroring the existing skip_outputs = true attribute on individual dependency blocks.

The feature is gated behind the optional-dependency-outputs experiment:

TG_EXPERIMENT=optional-dependency-outputs terragrunt run --no-dependency-outputs -- init

Using --no-dependency-outputs without enabling the optional-dependency-outputs experiment will return an error.

Thanks to @​pjrm for contributing this feature!

🧪 Experiments Updated

catalog-format — Added reading the catalog as JSON Lines

The catalog command draws a terminal user interface, and refuses to start where there is no terminal to draw it on. With the catalog-format experiment enabled, --format=jsonl writes the same discovery to standard output instead, as one JSON object per line:

terragrunt catalog --experiment=catalog-format --format=jsonl | jq -c '{kind, title, component_source}'

Entries are written as they are discovered rather than collected first, so output is readable while the remaining repositories are still loading, and a reader that stops early ends the command quietly:

terragrunt catalog --experiment=catalog-format --format=jsonl | head -5

[!NOTE]
Closing the pipe

In this example, the head program exits after reading in five lines, and Terragrunt detects the SIGPIPE signal from the OS, and shuts down cleanly.

Entries appear in discovery order, which interleaves the repositories being loaded and differs between runs. Every entry carries the complete body of the component's README in the doc field. Combine usage of Terragrunt with other tools like jq to drop it.

terragrunt catalog --experiment=catalog-format --format=jsonl | jq -c 'del(.doc)'

Entries follow a published JSON schema. For the fields and their meanings, see Non-interactive catalog.

--format=tui is the default, and leaves the terminal user interface exactly as it was.

catalog-format — Added reading the catalog as Markdown

The catalog-format experiment gains a second non-interactive format. Where --format=jsonl writes a record per catalog entry for a program to parse, --format=md writes one Markdown document for a person or an agent to read:

terragrunt catalog --experiment=catalog-format --format=md > catalog.md

Each entry becomes a section holding the metadata the catalog user interface shows for it, the source the component is scaffolded from, and the component's README. Sections are written as entries are discovered, so the document is readable while the remaining repositories are still loading.

READMEs are reproduced inside fenced blocks, so the headings one carries are not read as sections of the catalog document. The document closes with a table naming every component it holds and a count of what was discovered, which is how a reader tells a complete document from one that was cut short by a consumer that stopped reading.

For the fields each section carries, see Non-interactive catalog.

oci — Added OCI sources for stack units and stacks

terragrunt.stack.hcl now accepts oci:// sources in unit and stack blocks, so a stack can pull its components straight from an OCI registry. Without the oci experiment enabled, such a source fails with a clear error instead of an unsupported-scheme failure.

oci — Added OpenTofu CLI-config credentials for OCI module sources

oci:// module downloads now read OpenTofu's CLI-config credentials, so one configuration serves both OpenTofu and Terragrunt.

Terragrunt honors the oci_credentials "<registry>[/<repo-prefix>]" blocks (username and password, OAuth tokens, or a docker_credentials_helper, which like tofu may only be set on a whole registry) and the oci_default_credentials fallback helper. A TF_CLI_CONFIG_FILE or TERRAFORM_CONFIG value selects the config file outright; otherwise Terragrunt reads the first of ~/.tofurc and ~/.terraformrc that exists, and merges the *.tfrc and *.tfrc.json files in OpenTofu's config directory.

Terragrunt picks the most specific matching source across CLI config and ambient Docker config; an explicit CLI-config entry wins when both match equally. Set discover_ambient_credentials = false in the oci_default_credentials block to use CLI config only.

⚙️ Process Updates

Go bumped to v1.26.5

The version of Golang used to compile the Terragrunt binary has been updated from v1.26.0 to v1.26.5.

Thanks to @​apoiget for contributing this upgrade!

Pull Requests

✨ Features
🐛 Bug Fixes

Note

PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • "before 9am on tuesday"
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added changelog:skip dependencies Pull requests that update a dependency file renovate labels Aug 4, 2026
@renovate
renovate Bot force-pushed the renovate/terragrunt-1.x branch 2 times, most recently from 0358c3e to f87e577 Compare August 11, 2026 13:31
@renovate
renovate Bot force-pushed the renovate/terragrunt-1.x branch 2 times, most recently from 4e4abe8 to bc87f5e Compare August 18, 2026 15:57
@renovate renovate Bot changed the title chore(deps): update dependency terragrunt to v1.1.2 chore(deps): update dependency terragrunt to v1.1.3 Aug 18, 2026
@renovate
renovate Bot force-pushed the renovate/terragrunt-1.x branch 2 times, most recently from 31921b9 to 3006a4f Compare August 25, 2026 18:20
@renovate
renovate Bot force-pushed the renovate/terragrunt-1.x branch 2 times, most recently from b863bdd to 26339fa Compare September 1, 2026 10:30
@renovate
renovate Bot force-pushed the renovate/terragrunt-1.x branch from 26339fa to 598a4ca Compare September 1, 2026 18:18
@renovate renovate Bot changed the title chore(deps): update dependency terragrunt to v1.1.3 chore(deps): update dependency terragrunt to v1.1.4 Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog:skip dependencies Pull requests that update a dependency file renovate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants