-
-
Notifications
You must be signed in to change notification settings - Fork 146
Description
Describe the Bug
When a component's instance name differs from its metadata.component value, Atmos JIT vendoring (atmos terraform source pull) and atmos terraform $command resolve to two different .workdir paths for the same component. This means:
source pull --forcehydrates one directory.plan/initlooks in a different directory and re-downloads (or fails to find) the source.
This was discussed in the Atmos Slack and appeared related to PR #2093, but the issue persists.
Expected Behavior
Both atmos terraform source pull and atmos terraform init/plan should resolve to the same workdir path for a given component instance.
When metadata.component is set, it represents the upstream module identity — the JIT workdir path should be derived consistently from that same identity regardless of which subcommand triggers the resolution.
Expected .workdir layout (one directory):
.workdir/
└── terraform/
└── demo-dev-my-module/ # keyed by metadata.component
└── <module files>
Actual behavior
Two separate directories are created:
.workdir/
└── terraform/
├── demo-dev-my-module-iac/ # created by `source pull` (uses instance name)
└── demo-dev-my-module/ # created by `init`/`plan` (uses metadata.component)
The practical consequence is that source pull --force pre-seeds the wrong directory, and every subsequent plan/init re-downloads the source from scratch (or vice versa, depending on which path the subcommand resolves first).
Steps to Reproduce
#!/usr/bin/env bash
# ============================================================
# ATMOS REPRO: JIT workdir mismatch when metadata.component
# differs from the component instance name
# ============================================================
set -euo pipefail
WORKDIR="$(mktemp -d -t atmos-repro-XXXXXX)"
echo "Working in: ${WORKDIR}"
cd "${WORKDIR}"
# --- 1) atmos.yaml ---
cat <<'EOF' > atmos.yaml
base_path: "."
components:
terraform:
base_path: "components/terraform"
command: "tofu"
apply_auto_approve: false
deploy_run_init: true
init_run_reconfigure: true
auto_generate_backend_file: true
stacks:
name_template: "{{ .vars.tenant }}-{{ .vars.environment }}"
base_path: "stacks"
included_paths:
- "**/*"
EOF
# --- 2) Stack YAML ---
# Key detail: the component *instance* name is "my-module-iac"
# but metadata.component is "my-module"
# (mirrors a real pattern where the same upstream module
# is instantiated multiple times under different names)
mkdir -p stacks
cat <<'EOF' > stacks/demo.yaml
vars:
tenant: "demo"
environment: "dev"
terraform:
backend_type: local
components:
terraform:
my-module-iac: # <-- instance name
source:
uri: "git::https://github.com/cloudposse/terraform-null-label.git"
version: "0.25.0"
provision:
workdir:
enabled: true
metadata:
component: "my-module" # <-- DIFFERENT from instance name
EOF
# --- 3) Show structure ---
echo
echo "=== workspace layout ==="
find . -maxdepth 3 -type f | sed 's|^\./||'
echo
echo "=== atmos describe component (pre-pull) ==="
atmos describe component my-module-iac -s demo-dev
# --- 4) Explicit source pull (simulates pre-seeding the cache) ---
echo
echo "=== atmos terraform source pull ==="
atmos terraform source pull --force my-module-iac -s demo-dev
echo
echo "=== .workdir contents AFTER source pull ==="
find .workdir -maxdepth 4 -type d 2>/dev/null || echo "(no .workdir directory found)"
# --- 5) Init / plan (these use metadata.component for the workdir path) ---
echo
echo "=== atmos terraform init ==="
atmos terraform init my-module-iac -s demo-dev || true
echo
echo "=== .workdir contents AFTER init ==="
find .workdir -maxdepth 4 -type d 2>/dev/null || echo "(no .workdir directory found)"
echo
echo "=== RESULT ==="
echo "Expected: exactly ONE directory under .workdir/terraform/"
echo "Actual: two directories — one keyed by instance name, one by metadata.component"
echo
echo "Done. Workspace preserved at: ${WORKDIR}"Results - you can see two different .workdirs
✓ Vendored my-module-iac@0.25.0 to .workdir/terraform/demo-dev-my-module-iac
=== .workdir contents AFTER source pull ===
.workdir
.workdir/terraform
.workdir/terraform/demo-dev-my-module-iac
.workdir/terraform/demo-dev-my-module-iac/test
.workdir/terraform/demo-dev-my-module-iac/test/src
.workdir/terraform/demo-dev-my-module-iac/docs
.workdir/terraform/demo-dev-my-module-iac/exports
.workdir/terraform/demo-dev-my-module-iac/examples
.workdir/terraform/demo-dev-my-module-iac/examples/complete
.workdir/terraform/demo-dev-my-module-iac/examples/autoscalinggroup
.workdir/terraform/demo-dev-my-module-iac/.github
.workdir/terraform/demo-dev-my-module-iac/.github/workflows
.workdir/terraform/demo-dev-my-module-iac/.github/ISSUE_TEMPLATE
=== atmos terraform init ===
✓ Auto-provisioned source to .workdir/terraform/demo-dev-my-module
Initializing the backend...
Successfully configured the backend "local"! OpenTofu will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
OpenTofu has been successfully initialized!
=== .workdir contents AFTER init ===
.workdir
.workdir/terraform
.workdir/terraform/demo-dev-my-module-iac
.workdir/terraform/demo-dev-my-module-iac/test
.workdir/terraform/demo-dev-my-module-iac/test/src
.workdir/terraform/demo-dev-my-module-iac/docs
.workdir/terraform/demo-dev-my-module-iac/exports
.workdir/terraform/demo-dev-my-module-iac/examples
.workdir/terraform/demo-dev-my-module-iac/examples/complete
.workdir/terraform/demo-dev-my-module-iac/examples/autoscalinggroup
.workdir/terraform/demo-dev-my-module-iac/.github
.workdir/terraform/demo-dev-my-module-iac/.github/workflows
.workdir/terraform/demo-dev-my-module-iac/.github/ISSUE_TEMPLATE
.workdir/terraform/demo-dev-my-module
.workdir/terraform/demo-dev-my-module/test
.workdir/terraform/demo-dev-my-module/test/src
.workdir/terraform/demo-dev-my-module/.terraform
.workdir/terraform/demo-dev-my-module/docs
.workdir/terraform/demo-dev-my-module/exports
.workdir/terraform/demo-dev-my-module/examples
.workdir/terraform/demo-dev-my-module/examples/complete
.workdir/terraform/demo-dev-my-module/examples/autoscalinggroup
.workdir/terraform/demo-dev-my-module/.github
.workdir/terraform/demo-dev-my-module/.github/workflows
.workdir/terraform/demo-dev-my-module/.github/ISSUE_TEMPLATE
.workdir/terraform/demo-dev-my-module/.atmos
=== RESULT ===
Expected: exactly ONE directory under .workdir/terraform/
Actual: two directories — one keyed by instance name, one by metadata.component
Done. Workspace preserved at: /var/folders/rs/nw_8jpb53l30mnds_y98zq6m0000gp/T/atmos-repro-XXXXXX.39t8f1SFIi
Screenshots
No response
Environment
Atmos version 1.207.0, also tested on #2093
Additional Context
No response