Skip to content

fix: write Terragrunt plan artifacts to the run's unique temp dir#205

Merged
patrickchugh merged 1 commit into
patrickchugh:mainfrom
jcoffi:fix/terragrunt-tfplan-temp-path-collision
Jun 28, 2026
Merged

fix: write Terragrunt plan artifacts to the run's unique temp dir#205
patrickchugh merged 1 commit into
patrickchugh:mainfrom
jcoffi:fix/terragrunt-tfplan-temp-path-collision

Conversation

@jcoffi

@jcoffi jcoffi commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Fixes #204

Sibling of #202 / #203, which fix the same temp-path collision for plain Terraform in tf_initplan. This PR applies the same fix to the Terragrunt path.

Type of Change

  • Bug Fix
  • New Feature
  • Refactor
  • Documentation

What this changes

tg_initplan() in modules/tgwrapper.py wrote its plan artifacts (tg_tfplan.bin, tg_tfplan.json, tg_tfgraph.dot) into tempfile.gettempdir(), the shared temp root (usually /tmp), under fixed names. Two terravision runs against Terragrunt sources at once then write to the same files and overwrite each other's plan and graph.

tg_run_all_plan() (multi-module) runs tg_initplan() once per child module, so it shares the same paths.

The fix writes the artifacts into tfwrapper.temp_dir.name, the per-process TemporaryDirectory terravision already uses for Terraform artifacts. tempfile is no longer referenced in the module, so the import is removed.

-    tfplan_path = os.path.join(tempfile.gettempdir(), "tg_tfplan.bin")
-    tfplan_json_path = os.path.join(tempfile.gettempdir(), "tg_tfplan.json")
-    tfgraph_path = os.path.join(tempfile.gettempdir(), "tg_tfgraph.dot")
+    tfplan_path = os.path.join(tfwrapper.temp_dir.name, "tg_tfplan.bin")
+    tfplan_json_path = os.path.join(tfwrapper.temp_dir.name, "tg_tfplan.json")
+    tfgraph_path = os.path.join(tfwrapper.temp_dir.name, "tg_tfgraph.dot")

Why this is safe

  • tfwrapper.temp_dir is the module-level TemporaryDirectory created at import, already used for Terraform plan artifacts and as TF_DATA_DIR. tgwrapper already depends on tfwrapper for _write_override, convert_dot_to_json, and tf_makegraph, so this adds no new coupling.
  • The filenames keep their tg_ prefix, so they do not clash with the Terraform artifacts in the same directory.
  • Within a single run the paths are reused sequentially (each module's plan is decoded before the next module runs), exactly as before. Only the directory changed, from shared to per-process.
  • _run_terragrunt_plan() and _decode_tg_plan() receive the same path variables, so they follow the new location automatically.

Testing

  • python -m black --check modules/tgwrapper.py passes.
  • python -m py_compile modules/tgwrapper.py passes.
  • The Terragrunt integration tests in tests/test_tgwrapper.py are marked @pytest.mark.slow and exercise tg_initplan / tg_run_all_plan end to end. They assert on the returned tfdata (resource types, codepath, override cleanup), not on the temp-file location, so this change does not affect them. I could not run the slow suite in my environment (no terragrunt binary available).
  • No new regression test added, matching the minimal approach taken for the Terraform counterpart in fix: write Terraform plan artifacts to the run's unique temp dir #203. Happy to add one together with a small refactor if you would prefer.

A note on scope

This is intentionally a single focused change for the Terragrunt path, paired with the Terraform fix in #203. Between them they cover both tf_initplan and tg_initplan.

Checklist

All Submissions:

  • Checked for other open PRs covering the same change
  • Written Documentation/Tests (see the Testing note above)
  • Done my own code review
  • Disclosed AI tool/model use (below)

AI Assistance Declaration

  • Tools used: opencode (CLI coding agent)
  • Model: Claude Opus 4 (anthropic/claude-opus-4-8)
  • Scope: identified the shared-path collision in tg_initplan, applied the fix, removed the now-unused tempfile import, and wrote this PR.

Checklist for Changes to Core Features:

  • Minor bugfix, raised directly as the template allows for minor fixes
  • PR is focused on a single change
  • Explanation of what and why is included above
  • New tests not added (rationale in Testing)
  • Verified the existing slow Terragrunt tests do not assert on the changed path

tg_initplan built tg_tfplan.bin, tg_tfplan.json and tg_tfgraph.dot under
tempfile.gettempdir(), the shared temp root (usually /tmp), at fixed
names. Two terravision runs against Terragrunt sources at once then write
to the same files and overwrite each other's plan and graph.

Write them into tfwrapper.temp_dir.name instead, the per-process
TemporaryDirectory terravision already uses for Terraform artifacts, so
each run keeps its files in its own directory. tempfile is no longer used
in this module, so drop the import.

tg_run_all_plan (multi-module) calls tg_initplan per child module, so it
inherits the fix. This is the Terragrunt counterpart of the same fix in
tf_initplan.
@jcoffi jcoffi force-pushed the fix/terragrunt-tfplan-temp-path-collision branch from d7bafda to 2e7ab34 Compare June 26, 2026 20:47
@patrickchugh patrickchugh merged commit 5a9201f into patrickchugh:main Jun 28, 2026
1 check passed
@patrickchugh

Copy link
Copy Markdown
Owner

@jcoffi Thanks for the PR.

@jcoffi jcoffi deleted the fix/terragrunt-tfplan-temp-path-collision branch June 28, 2026 18:24
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.

tg_initplan writes Terragrunt plan artifacts to a shared /tmp path; concurrent runs collide

2 participants