Skip to content

Conversation

@philipmckenna-symphony
Copy link

@philipmckenna-symphony philipmckenna-symphony commented Dec 6, 2025

Description

Fixes #5175.

While each stackfile is being evaluated, set the OriginalTerragruntConfigPath to that filepath, allowing get_original_terragrunt_dir to function similarly for terragrunt.stack.hcl files as it does for terragrunt.hcl files.

Each scenario below terragrunt stack generate is run in the live directory.


Scenario 1

# live/dev/parent
locals {
   stack_dir = basename(get_original_terragrunt_dir())
}

stack "some_stack" {
   source = "..."
   path    = "child"
   values = {
      stack_dir = locals.stack_dir
   }
}

Before: stack_dir = live
After: stack_dir = parent


Scenario 2

# live/common/stack_config.hcl
locals {
   stack_dir = basename(get_original_terragrunt_dir())
}

...

# live/dev/parent
locals {
   common = read_terragrunt_config(find_in_parent_folders("common/stack_config.hcl"))
}

stack "some_stack" {
   source = "..."
   path    = "child"
   values = {
      stack_dir = local.common.locals.stack_dir
   }
}

Before: stack_dir = live
After: stack_dir = parent


Scenario 3

# live/dev/parent
stack "some_stack" {
   source = "..."
   path    = "child"
   values = {
      stack_dir = basename(get_original_terragrunt_dir())
   }
}

Before: stack_dir = live
After: stack_dir = parent


TODOs

Read the Gruntwork contribution guidelines.

  • I authored this code entirely myself
  • I am submitting code based on open source software (e.g. MIT, MPL-2.0, Apache)]
  • I am adding or upgrading a dependency or adapted code and confirm it has a compatible open source license
  • Update the docs.
  • Run the relevant tests successfully, including pre-commit checks.
  • Include release notes. If this PR is backward incompatible, include a migration guide.

Release Notes (draft)

During multi-directory terragrunt stack generate, get_original_terragrunt_dir returns the expected path when called from stackfile locals or from within a read_terragrunt_config target.

Migration Guide

Summary by CodeRabbit

  • New Features

    • Capture and propagate the original Terragrunt configuration directory into stack evaluations and pass it into nested stacks via values.
  • Tests

    • Added integration tests verifying the original Terragrunt directory is propagated across nested and non-nested stack scenarios (with/without locals and read-config).
  • Documentation

    • Clarified the get_original_terragrunt_dir() behavior in the functions reference.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 6, 2025

@philipmckenna-symphony is attempting to deploy a commit to the Gruntwork Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 6, 2025

📝 Walkthrough

Walkthrough

Propagates the original Terragrunt stack config path into the stack parsing context by setting stackOpts.OriginalTerragruntConfigPath = filePath in ReadStackConfigFile(), and adds fixtures plus an integration test to verify get_original_terragrunt_dir() behavior across nested, non-nested, and read-config scenarios.

Changes

Cohort / File(s) Summary
Core Implementation
config/stack.go
Sets stackOpts.OriginalTerragruntConfigPath = filePath inside ReadStackConfigFile() so the original Terragrunt config path is available to the parsing context.
Integration Test
test/integration_stacks_test.go
Adds testFixtureStackOriginalTerragruntDir and TestStackOriginalTerragruntDir() to generate stacks and assert generated terragrunt.values.hcl include the expected stack_dir.
Test Fixtures — Units
test/fixtures/stacks/get-original-terragrunt-dir/units/terragrunt.hcl
Adds inputs mapping that reads values.stack_dir into unit inputs.
Test Fixtures — Stacks (no-locals/with-locals/read-config variants)
test/fixtures/stacks/get-original-terragrunt-dir/stacks/*/terragrunt.stack.hcl
Adds multiple stack definitions that propagate stack_dir via values (variants: no-locals, with-locals, read-config).
Test Fixtures — Live variants (nested & non-nested)
test/fixtures/stacks/get-original-terragrunt-dir/live/account1/.../*
Adds many live fixture stack files covering nested, non-nested, and read-config patterns; several pass get_original_terragrunt_dir() (directly or via read_terragrunt_config) into nested units.
Test Fixtures — Shared Config
test/fixtures/stacks/get-original-terragrunt-dir/live/common/stack_config.hcl
Adds locals.stack_dir = get_original_terragrunt_dir() for read-config scenarios.
Docs
docs-starlight/src/content/docs/04-reference/01-hcl/04-functions.mdx
Clarifies that get_original_terragrunt_dir() returns the directory of the terragrunt.stack.hcl currently being read during stack generation, including when invoked via read_terragrunt_config().

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Single-line core change but affects evaluation context used by many fixtures and the new integration test.
  • Areas to review closely:
    • config/stack.go — verify correct assignment and that parsing context uses OriginalTerragruntConfigPath as intended.
    • TestStackOriginalTerragruntDir in test/integration_stacks_test.go — confirm path expectations for nested/non-nested/read-config fixture combinations.
    • Representative fixtures under test/fixtures/stacks/get-original-terragrunt-dir/ for correctness of values propagation.

Possibly related issues

Possibly related PRs

Suggested reviewers

  • ThisGuyCodes
  • denis256
  • yhakbar

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly summarizes the main change: fixing the behavior of get_original_terragrunt_dir during stack generation, which is the core objective of the PR.
Description check ✅ Passed The PR description is comprehensive and complete. It includes a clear reference to the linked issue (#5175), detailed explanation of the fix, concrete before-and-after scenarios, completed TODOs with checkmarks, release notes, and a migration guide placeholder.
Linked Issues check ✅ Passed The PR fully addresses issue #5175's requirements: it fixes get_original_terragrunt_dir to return the stack directory (not the command working directory) by setting OriginalTerragruntConfigPath during stack evaluation, enables all three scenarios from the description to work correctly, and includes comprehensive test fixtures and test cases validating the fix.
Out of Scope Changes check ✅ Passed All changes are directly in scope: the core fix in config/stack.go, test fixtures demonstrating the three scenarios, integration test validating the fix, and documentation updates explaining the behavior. No unrelated changes detected.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5dac421 and 705f061.

📒 Files selected for processing (1)
  • docs-starlight/src/content/docs/04-reference/01-hcl/04-functions.mdx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • docs-starlight/src/content/docs/04-reference/01-hcl/04-functions.mdx

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
config/stack.go (1)

414-436: Optional: mirror original-path behavior in ReadStackConfigString

If ReadStackConfigString is ever used in contexts that rely on get_original_terragrunt_dir for stacks, consider cloning opts here as well and setting OriginalTerragruntConfigPath = configPath before building the parsing context, for symmetry with ReadStackConfigFile. Not urgent given current usage.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92eeec3 and 26a03a1.

📒 Files selected for processing (19)
  • config/stack.go (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/no-locals-nested/no-locals/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/no-locals-nested/read-config/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/no-locals-nested/with-locals/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/non-nested/no-locals/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/non-nested/read-config/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/non-nested/with-locals/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/read-config-nested/no-locals/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/read-config-nested/read-config/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/read-config-nested/with-locals/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/with-locals-nested/no-locals/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/with-locals-nested/read-config/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/with-locals-nested/with-locals/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/live/common/stack_config.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/stacks/no-locals/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/stacks/read-config/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/stacks/with-locals/terragrunt.stack.hcl (1 hunks)
  • test/fixtures/stacks/get-original-terragrunt-dir/units/terragrunt.hcl (1 hunks)
  • test/integration_stacks_test.go (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.go

⚙️ CodeRabbit configuration file

Review the Go code for quality and correctness. Make sure that the Go code follows best practices, is performant, and is easy to understand and maintain.

Files:

  • config/stack.go
  • test/integration_stacks_test.go
🧠 Learnings (5)
📓 Common learnings
Learnt from: jkarkoszka
Repo: gruntwork-io/terragrunt PR: 5116
File: test/integration_test.go:2785-2795
Timestamp: 2025-11-18T09:54:06.008Z
Learning: In Terragrunt, `read_terragrunt_config_with_cache` intentionally has different semantics than `read_terragrunt_config`: it caches the first parse result (including context like `original_terragrunt_dir`) and returns that cached value on subsequent calls to the same file, even if the calling context has changed. This is a performance optimization that trades context accuracy for speed. Tests showing different assertions between cached and non-cached variants for context-dependent values like `original_terragrunt_dir` are expected and correct.
📚 Learning: 2025-11-18T09:54:06.008Z
Learnt from: jkarkoszka
Repo: gruntwork-io/terragrunt PR: 5116
File: test/integration_test.go:2785-2795
Timestamp: 2025-11-18T09:54:06.008Z
Learning: In Terragrunt, `read_terragrunt_config_with_cache` intentionally has different semantics than `read_terragrunt_config`: it caches the first parse result (including context like `original_terragrunt_dir`) and returns that cached value on subsequent calls to the same file, even if the calling context has changed. This is a performance optimization that trades context accuracy for speed. Tests showing different assertions between cached and non-cached variants for context-dependent values like `original_terragrunt_dir` are expected and correct.

Applied to files:

  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/non-nested/with-locals/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/with-locals-nested/with-locals/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/no-locals-nested/read-config/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/non-nested/read-config/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/stacks/with-locals/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/read-config-nested/with-locals/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/read-config-nested/read-config/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/with-locals-nested/read-config/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/stacks/no-locals/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/stacks/read-config/terragrunt.stack.hcl
  • test/integration_stacks_test.go
📚 Learning: 2025-02-10T13:36:19.542Z
Learnt from: levkohimins
Repo: gruntwork-io/terragrunt PR: 3723
File: cli/commands/stack/action.go:160-160
Timestamp: 2025-02-10T13:36:19.542Z
Learning: The project uses a custom error package `github.com/gruntwork-io/terragrunt/internal/errors` which provides similar functionality to `fmt.Errorf` but includes stack traces. Prefer using this package's error functions (e.g., `errors.Errorf`, `errors.New`) over the standard library's error handling.

Applied to files:

  • config/stack.go
📚 Learning: 2025-11-03T04:40:01.000Z
Learnt from: ThisGuyCodes
Repo: gruntwork-io/terragrunt PR: 5041
File: test/fixtures/hclvalidate/valid/duplicate-attributes-in-required-providers/main.tf:2-7
Timestamp: 2025-11-03T04:40:01.000Z
Learning: In the terragrunt repository, test fixtures under test/fixtures/hclvalidate/valid/ are intentionally testing that INPUT validation succeeds even when Terraform code contains syntax errors or other issues unrelated to input validation (e.g., duplicate attributes, circular references, invalid locals). The "valid" designation means "valid for input validation purposes" not "syntactically valid Terraform/OpenTofu code".

Applied to files:

  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/non-nested/read-config/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/stacks/no-locals/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/units/terragrunt.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/stacks/read-config/terragrunt.stack.hcl
  • test/integration_stacks_test.go
📚 Learning: 2025-02-10T23:20:04.295Z
Learnt from: yhakbar
Repo: gruntwork-io/terragrunt PR: 3868
File: docs-starlight/patches/@astrojs%[email protected]:33-33
Timestamp: 2025-02-10T23:20:04.295Z
Learning: In Terragrunt projects, all `.hcl` files can be assumed to be Terragrunt configurations by default, with specific exceptions like `.terraform.lock.hcl` that need explicit handling.

Applied to files:

  • test/fixtures/stacks/get-original-terragrunt-dir/live/account1/non-nested/read-config/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/stacks/no-locals/terragrunt.stack.hcl
  • test/fixtures/stacks/get-original-terragrunt-dir/stacks/read-config/terragrunt.stack.hcl
🔇 Additional comments (20)
test/fixtures/stacks/get-original-terragrunt-dir/live/account1/with-locals-nested/no-locals/terragrunt.stack.hcl (1)

1-4: Test fixture correctly supports nested stack scenario for get_original_terragrunt_dir validation.

This fixture appropriately tests the case where a nested stack (sourcing parent configuration via find_in_parent_folders) is evaluated without locals, ensuring get_original_terragrunt_dir correctly resolves the stack directory in this context.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/read-config-nested/no-locals/terragrunt.stack.hcl (1)

1-4: Nested read-config stack fixture looks correct

This minimally wraps the parent stacks/read-config stack at unit_dirs, which matches the intended nested/no-locals scenario for the new tests.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/no-locals-nested/no-locals/terragrunt.stack.hcl (1)

1-8: Good coverage of nested no-locals + direct original dir usage

Passing stack_dir = get_original_terragrunt_dir() via values is a clear way to assert the fixed behavior for nested/no-locals stacks.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/non-nested/with-locals/terragrunt.stack.hcl (1)

1-12: Non-nested with-locals fixture is well-structured

Capturing stack_dir once in locals and passing it to unit_1 via values is a clean pattern and gives a straightforward assertion point for the fixed get_original_terragrunt_dir.

test/fixtures/stacks/get-original-terragrunt-dir/live/common/stack_config.hcl (1)

1-3: Common stack_config.hcl correctly centralizes original dir

Defining locals.stack_dir = get_original_terragrunt_dir() here is a good anchor for scenarios that read_terragrunt_config into this file and then propagate stack_dir outward, matching the intended context-dependent behavior while leaving read_terragrunt_config_with_cache semantics untouched. Based on learnings, this aligns with the expected difference between cached and non-cached reads.

test/fixtures/stacks/get-original-terragrunt-dir/units/terragrunt.hcl (1)

1-3: Unit fixture cleanly consumes propagated stack_dir

Reading stack_dir exclusively from values.stack_dir keeps the “where did this stack come from?” concern in the stack layer, which is exactly what these tests need.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/non-nested/no-locals/terragrunt.stack.hcl (1)

1-8: Non-nested no-locals fixture nicely complements with-locals tests

Using values.stack_dir = get_original_terragrunt_dir() here exercises the “simple, single stackfile” case without locals, rounding out the matrix of scenarios.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/no-locals-nested/with-locals/terragrunt.stack.hcl (1)

1-12: Nested with-locals fixture covers the remaining matrix corner

Capturing stack_dir in locals and passing it into a nested stacks/no-locals source via values gives good coverage of the “nested + locals” case, complementary to the no-locals variant.

config/stack.go (1)

399-412: Correctly scoping OriginalTerragruntConfigPath to each stackfile

Cloning opts and setting both TerragruntConfigPath and OriginalTerragruntConfigPath to filePath for stackOpts means that stack locals and any read_terragrunt_config calls from stackfiles will now treat the stackfile’s directory as the “original” dir, which matches the bug report and the new fixtures, while leaving the outer opts unchanged for downstream logic. This looks like the right minimal fix.

test/fixtures/stacks/get-original-terragrunt-dir/stacks/with-locals/terragrunt.stack.hcl (1)

1-21: LGTM! Test fixture correctly validates get_original_terragrunt_dir() in locals.

The fixture appropriately captures the original Terragrunt directory in locals and propagates it to units via the values map. The defensive try(values, {}) pattern ensures graceful handling of undefined values.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/with-locals-nested/with-locals/terragrunt.stack.hcl (1)

1-12: LGTM! Nested stack fixture is correctly structured.

This fixture appropriately tests the behavior of get_original_terragrunt_dir() in nested stack scenarios by capturing the directory in locals and passing it to the child stack.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/with-locals-nested/read-config/terragrunt.stack.hcl (1)

1-12: LGTM! Read-config fixture correctly validates nested behavior.

This fixture appropriately tests the behavior when get_original_terragrunt_dir() is used within a config loaded via read_terragrunt_config(), ensuring the original directory context is preserved.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/non-nested/read-config/terragrunt.stack.hcl (1)

1-12: LGTM! Non-nested read-config fixture is correct.

This fixture appropriately tests the non-nested scenario with read_terragrunt_config(), ensuring proper directory resolution in simpler stack configurations.

test/fixtures/stacks/get-original-terragrunt-dir/stacks/no-locals/terragrunt.stack.hcl (1)

1-17: LGTM! No-locals fixture correctly tests passthrough behavior.

This fixture appropriately tests the scenario where get_original_terragrunt_dir() is not called in the stack's locals block, validating the expected behavior when the function is invoked later in the evaluation chain.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/read-config-nested/read-config/terragrunt.stack.hcl (1)

1-12: LGTM! Nested read-config fixture validates combined scenario.

This fixture correctly tests the combination of nested stacks with read_terragrunt_config(), ensuring proper directory context propagation through multiple levels.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/read-config-nested/with-locals/terragrunt.stack.hcl (1)

1-12: LGTM! Final nested fixture completes test coverage.

This fixture appropriately rounds out the test coverage by combining nested stacks with local directory capture, ensuring comprehensive validation of the fix.

test/integration_stacks_test.go (2)

57-57: LGTM! Test fixture constant follows naming convention.

The constant name is consistent with other test fixture constants in the file.


1443-1476: LGTM! Test setup and file discovery logic is correct.

The test appropriately sets up the environment, generates the stack, and walks the directory tree to collect all terragrunt.values.hcl files for validation.

test/fixtures/stacks/get-original-terragrunt-dir/live/account1/no-locals-nested/read-config/terragrunt.stack.hcl (1)

1-12: Verify referenced shared config file defines expected stack_dir local.

This fixture exercises the PR fix by reading a shared config and extracting stack_dir from its locals (line 10). For this pattern to work, common/stack_config.hcl must define locals.stack_dir using get_original_terragrunt_dir(), so that when read from this stack file context, it returns the correct stack directory.

test/fixtures/stacks/get-original-terragrunt-dir/stacks/read-config/terragrunt.stack.hcl (1)

1-21: Verify that shared config and unit directory dependencies are present in the fixture tree.

This fixture reads shared config from live/common/stack_config.hcl and propagates stack_dir to nested units via merge() with try(values, {}) (lines 9, 18). Ensure the following fixture dependencies exist:

  • live/common/stack_config.hcl defining locals.stack_dir via get_original_terragrunt_dir()
  • units directory containing unit_1 and unit_2 subdirectories at the relative path specified in the source attributes

@philipmckenna-symphony
Copy link
Author

@yhakbar @denis256

Thank you again for the chat in office hours, the following commit is the proposed documentation changes you requested: 705f061

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stack generate: get_original_terragrunt_dir and get_terragrunt_dir can’t reliably resolve the current stack directory

1 participant