fix: add JIT vendoring support to generate varfile and generate backend @aknysh (#2054)
what
- Add JIT (Just-In-Time) vendoring support to
atmos terraform generate varfileandatmos terraform generate backendcommands - Fix
writeBackendConfigFile()to useconstructTerraformComponentWorkingDir()instead of hardcoded path construction, so backend files are written to the correct directory for JIT-vendored components - Add
ensureTerraformComponentExists()helper that resolves the component path, checks existence, and triggers JIT provisioning viaAutoProvisionSourcewhen a source is configured - Replace hardcoded
"terraform"strings withcfg.TerraformComponentTypeconstant - Add comprehensive unit tests for all new helper functions,
writeBackendConfigFileworkdir support, and path construction with JIT vendored components
why
generate varfileandgenerate backendbypassed JIT provisioning because they calledProcessStacks()directly without triggering the provisioning hooks that download component sourceswriteBackendConfigFilehardcoded the component path (BasePath/Components.Terraform.BasePath/prefix/component) instead of usingconstructTerraformComponentWorkingDir(), which checks forWorkdirPathKeyset by JIT provisioning- This meant both commands failed for any component that relied on source vendoring, as the component directory didn't exist yet and the backend file was written to the wrong path
references
- Closes #2019
Summary by CodeRabbit
-
New Features
- Just-in-time provisioning for Terraform components when missing (5-minute timeout).
- Terraform component type made configurable for generation commands.
-
Bug Fixes
- Improved working-directory and varfile path resolution, including vendored/JIT component scenarios.
- Stronger component-existence validation with clearer, contextual errors.
-
Tests
- Extensive new unit/integration tests for varfile/backend generation, JIT provisioning, permission/error cases, and deprecated command behavior.
-
Deprecations
- Legacy generate commands now signal deprecation with explicit errors.
fix: Resolve Atmos Pro template regression with {{ .atmos_component }} in non-.tmpl files @aknysh (#2053)
what
- Fix regression introduced in Atmos 1.205 where
{{ .atmos_component }}and{{ .atmos_stack }}templates in non-.tmplfiles fail during import with:map has no entry for key "atmos_component" - Add
processTemplatesInSection()helper to resolve{{ .locals.X }}in individual sections (settings, vars, env) without triggering full-file template processing - Skip
.terraformdirectories in describe-affected test copies to avoid dangling symlink failures - Add
--verify=falsetohelm plugin installin Dockerfile for Helm 4 compatibility
why
Atmos Pro template regression (Issue #2032)
The locals feature (PR #1994) inadvertently triggered template processing for imported non-.tmpl files. extractAndAddLocalsToContext() populated the template context with settings/vars/env from the file, making len(context) > 0, which triggered the template processing guard. Templates like {{ .atmos_component }} then failed because component context isn't available at import time.
Fix: Track whether context was originally provided externally (originalContextProvided) vs extracted from the file itself. When template processing fails and only file-extracted context is available, gracefully fall back to raw content — preserving templates like {{ .atmos_component }} for later resolution in ProcessStacks when the full component context is available.
Additionally, extractAndAddLocalsToContext() now processes templates in individual sections (settings → vars → env) using a pipeline with resolved locals context. This enables bidirectional references between locals and settings while avoiding premature processing of component-scoped templates.
Dangling .terraform symlinks in describe-affected tests
TestDescribeAffectedWith* tests failed locally due to a dangling symlink in examples/secrets-masking/.terraform/providers/ left by a previous test run. Added .terraform to the copy skip filter alongside the existing node_modules skip.
Helm plugin install in Dockerfile
Helm 4 requires --verify=false because helm-diff does not ship .prov signature files.
references
- Closes #2032
Summary by CodeRabbit
-
Bug Fixes
- Preserve component- and stack-level templates during import and defer evaluation until full context is available to prevent premature resolution and regressions.
- Persist resolved section values so downstream describe/merge flows see processed results.
-
New Features
- Enhanced template resolution to support cross-references between locals, settings, vars, and env.
-
New Tests
- Large suite of tests covering template processing, cross-references, external-context behavior, and a regression case.
-
Chores
- Adjusted Helm plugin install for Helm 4 compatibility and expanded file exclusion patterns during config processing.
Fix: Vendoring excluded_paths not matching simple filenames @Benbentwo (#2049)
what
- Fixed pattern matching bug where
excluded_pathsincomponent.yamlandvendor.yamlweren't matching simple filename patterns like"providers.tf" - Fixed logic error where combined
excluded_paths+included_pathswasn't working correctly - Added comprehensive unit tests and YAML-based integration tests for the fix
why
- Users could not use simple filename patterns in
excluded_pathswithout the**/glob prefix - When both
excluded_pathsandincluded_pathswere specified, the include filter was never applied - Patterns were matched against absolute temp paths instead of relative paths, causing simple patterns to always fail
references
- Fixes vendoring with simple filename exclusions like
excluded_paths: ["providers.tf"] - Enables proper filtering when both exclude and include patterns are specified together
Summary by CodeRabbit
-
Bug Fixes
- Improved vendor file exclusion/inclusion logic to apply patterns correctly and consistently.
- Fixed path matching to work with relative paths, enabling simpler exclusion/inclusion patterns without directory prefixes.
- Added early exclusion checks for clearer and more efficient filtering behavior.
-
Tests
- Added comprehensive test suite for vendor exclude/include scenarios covering various pattern combinations.
feat: register terraform compound subcommands in Cobra command tree @aknysh (#2044)
what
- Register terraform compound subcommands (
state,providers,workspace) as proper Cobra child commands - Register per-subcommand compat flags for all 15 compound terraform subcommands
- Add dedicated documentation pages for all compound subcommands with detailed "Native Terraform Flags" sections
- Update screengrabs for all CLI commands
- Fix quoted compound terraform subcommands like
"providers lock" - Add compound subcommand argument parsing (
parseCompoundSubcommand,processTerraformCompoundSubcommand) - Add website documentation updates (templates defaults, stores, hooks)
why
Terraform compound subcommands registered in Cobra command tree (#2018)
Previously, compound terraform subcommands (state list, providers lock, workspace select, etc.) were handled entirely by argument parsing in processArgsAndFlags. This had several limitations:
- Tab completion didn't work for subcommands
- Help text didn't show subcommands with
[command]suffix - Quoted forms like
"providers lock"weren't supported
Fix (Part 1 — argument parsing): Added modular helper functions (parseCompoundSubcommand, parseQuotedCompoundSubcommand, parseSeparateCompoundSubcommand, processTerraformCompoundSubcommand) with configurable subcommand lists for workspace, state, providers, and write commands. Supports both quoted ("providers lock") and separate (providers lock) forms.
Fix (Part 2 — Cobra command tree registration): Registered compound subcommands as proper Cobra child commands:
cmd/terraform/state.go—list,mv,pull,push,replace-provider,rm,showas children ofstateCmdcmd/terraform/providers.go—lock,mirror,schemaas children ofprovidersCmdcmd/terraform/workspace.go—list,select,new,delete,showas children ofworkspaceCmdcmd/terraform/utils.go—newTerraformPassthroughSubcommand()helper creates Cobra child commands that delegate to the parent command's execution flow
The legacy compound subcommand parsing in processArgsAndFlags is retained as a fallback for the interactive UI path (which bypasses Cobra) and backward compatibility.
Files: internal/exec/cli_utils.go, internal/exec/cli_utils_test.go, cmd/terraform/utils.go, cmd/terraform/state.go, cmd/terraform/providers.go, cmd/terraform/workspace.go, cmd/terraform/subcommands_test.go
Per-subcommand compat flags for compound terraform subcommands
Added per-subcommand compat flag definitions for all 15 compound terraform subcommands, registered them with the command registry, and documented them in the website docs.
Compat flags registered per subcommand:
| Subcommand | Native Terraform Flags |
|---|---|
state list
| -state, -id
|
state mv
| -lock, -lock-timeout, -ignore-remote-version
|
state pull
| (none) |
state push
| -force, -lock, -lock-timeout, -ignore-remote-version
|
state replace-provider
| -auto-approve, -lock, -lock-timeout, -ignore-remote-version
|
state rm
| -lock, -lock-timeout, -ignore-remote-version
|
state show
| -state
|
providers lock
| -platform, -fs-mirror, -net-mirror, -enable-plugin-cache
|
providers mirror
| -platform
|
providers schema
| -json
|
workspace list
| (none) |
workspace select
| -or-create
|
workspace new
| -lock, -lock-timeout, -state
|
workspace delete
| -force, -lock, -lock-timeout
|
workspace show
| (none) |
Note: Terraform's
-dry-runonstate mv/state rmis intentionally excluded to avoid conflict with Atmos's--dry-runflag.
Files: cmd/terraform/compat_flags.go, cmd/terraform/state.go, cmd/terraform/providers.go, cmd/terraform/workspace.go, cmd/terraform/subcommands_test.go
Website documentation for compound subcommands
Added dedicated documentation pages for 15 terraform compound subcommands across 3 command families, each with detailed "Native Terraform Flags" sections documenting all supported terraform flags per subcommand:
providers/—lock,mirror,schemastate/—list,mv,pull,push,replace-provider,rm,showworkspace/—list,select,new,delete,show
Each page follows the existing documentation pattern with frontmatter, Intro component, Screengrab, Usage, Examples, Arguments, Flags, Native Terraform Flags, and See Also sections.
Updated screengrabs
Regenerated all CLI command screengrabs to reflect current help text including the new compound subcommand [command] suffixes.
references
- Closes #2018
Fix Artifactory store and improve store documentation @osterman (#2038)
what
- Fixed Artifactory store integration by adding
Flat=trueparameter to JFrog SDK downloads and proper directory path handling - Corrected store documentation to match actual implementation: fixed field names, store type names, and removed unsupported backends
- Added comprehensive integration tests for Artifactory store with mock HTTP server
- Added blog post announcing the fix
why
Customer reported retrieval issues with Artifactory store. Investigation revealed two problems:
- Store code was missing JFrog SDK configuration needed for proper file downloads
- Documentation contained errors that did not match the actual implementation (unsupported backends, incorrect field names)
The Artifactory GetKey method lacked the same configuration that the Get method had, causing downloads to fail. Documentation had outdated examples with unsupported stores (Vault, AWS Secrets Manager) and wrong field names (backend/config instead of type/options).
Customer-reported issue
Customer logs showed the exact problem this PR fixes:
[Info] Downloading "atmos_store/dev/myapp/private_ip" to "/tmp/atmos-artifactory.../dev/myapp/private_ip"
...
Error: failed to read file: open /tmp/atmos-artifactory.../private_ip: no such file or directory
Root cause: Without Flat=true, the JFrog SDK preserves the directory structure when downloading:
- SDK downloads to:
/tmp/atmos-artifactory.../dev/myapp/private_ip(nested path) - Code expects:
/tmp/atmos-artifactory.../private_ip(flat path)
The fix: Adding downloadParams.Flat = true tells the SDK to download files directly to the temp directory with just the base filename, matching what the code expects.
The Get method already had this configuration (which is why !store with stack/component/key worked), but GetKey was missing it.
references
- All Artifactory store integration tests now pass
- Documentation is consistent with actual supported backends:
aws-ssm-parameter-store,azure-key-vault,google-secret-manager,redis,artifactory - Mock server properly validates JFrog SDK integration patterns including AQL search, checksum validation, and file path handling
Summary by CodeRabbit
-
Bug Fixes
- Fixed Artifactory retrieval to correctly handle nested paths and ensure consistent download behavior for Get/GetKey.
-
Documentation
- Updated Artifactory store guidance, repository recommendations, store backend identifiers, tutorials, examples, and added a blog post describing the fix and configuration guidance.
-
Tests
- Added comprehensive Artifactory integration tests and a deterministic Artifactory mock server for testing.
✏️ Tip: You can customize this high-level summary in your review settings.
fix: Config isolation for --chdir flag @osterman (#1941)
what
When using --chdir to change to a directory with its own atmos.yaml, Atmos now correctly uses ONLY that local config. Parent directory and git root searches are now properly treated as fallbacks and are skipped when local config exists.
- Fixed config loading to respect local config isolation when using
--chdir - Updated PRD to clarify parent/git-root searches are fallbacks
- Added comprehensive unit and CLI tests for config isolation behavior
- Updated test framework to properly handle
--chdirflag in tests
why
Previously, atmos --chdir path/to/project describe config would unexpectedly include configuration from parent directories and the git root, causing wrong component paths and stack settings to be used in monorepo environments and test scenarios.
This fix ensures --chdir behaves as expected: as if you had run the command directly from that directory, searching parent directories and git root only as fallbacks when no local config exists.
references
Related to the PRD on config discovery behavior (docs/prd/git-root-discovery-default-behavior.md).
Summary by CodeRabbit
-
Bug Fixes
- Local Atmos configs now take precedence, preventing parent/git-root configs from being merged when a local config exists (improves --chdir isolation).
-
Documentation
- New blog post explaining config-loading order with --chdir, examples, and how to explicitly import parent configs.
-
Tests
- Added/expanded tests, fixtures, and snapshots to validate chdir config isolation and expected CLI output (including telemetry notice).
✏️ Tip: You can customize this high-level summary in your review settings.
docs: clarify dependencies section is for tool dependencies only @osterman (#2045)
what
- Removed misleading component dependency examples that showed unsupported syntax
- Clarified that the
dependenciessection currently supports tool version requirements only - Added admonition directing users to
settings.depends_onfor component execution order - Updated frontmatter, intro, and use cases to reflect tool-only focus
- Added reference link to
settings.depends_ondocumentation
why
The documentation previously conflated two separate concepts: tool dependencies (currently implemented via /dependencies/tools) and component dependencies (only available via settings.depends_on). The examples showing component dependency syntax were misleading since they're not yet supported in the /dependencies section. This change prevents user confusion and guides them to the correct feature.
references
This fixes documentation confusion around component dependencies vs tool dependencies. The plan is to consolidate these features in a future release, so this admonition acknowledges that intent.
Summary by CodeRabbit
- Documentation
- Clarified dependencies documentation to emphasize tool version requirements as the primary focus
- Expanded tool dependency configuration guidance, including configuration scopes, version formats, and inheritance behavior
- Added information directing users to settings for managing component execution order
- Updated related documentation references to include component dependencies guidance
✏️ Tip: You can customize this high-level summary in your review settings.
refactor: move toolchain from root to pkg/toolchain @osterman (#2041)
## what- Move toolchain package from repository root to
pkg/toolchainto align with project architecture guidelines - Update 90 import statements across 145 files to reference
github.com/cloudposse/atmos/pkg/toolchain - Regenerate mocks with updated import paths
- Update documentation references in PRD files
why
The toolchain package was incorrectly placed at the repository root in PR #1686. Project architecture guidelines (CLAUDE.md) specify that all business logic packages belong in pkg/. Moving toolchain to pkg/toolchain ensures consistency with other business logic packages like config, stack, component, store, git, and auth.
references
Aligns with project architecture guidelines in CLAUDE.md: All business logic belongs in pkg/ packages, not at the repository root.
Summary by CodeRabbit
- Chores
- Internal package reorganization for improved code structure and maintainability. No user-facing functionality changes or behavioral impact.
✏️ Tip: You can customize this high-level summary in your review settings.
docs: auth realm isolation PRD @Benbentwo (#2033)
what
- Added comprehensive PRD for credential namespace isolation feature
- Addresses credential collision issue when same identity names are used across different repositories
- Documents hybrid namespace approach with environment variable, config file, and automatic path hash precedence
why
When engineers work with multiple customer repositories that use identical identity names (e.g., core-root/terraform), AWS credentials collide and cause cross-contamination. This PRD outlines the design for isolating credentials using repository-specific namespaces, preventing accidental use of the wrong customer's credentials.
references
- DEV-3960: Fix caching issue with super user identities between customers
Summary by CodeRabbit
- Documentation
- Added three PRDs defining credential realm isolation: realm concept, selection precedence (env/config/automatic), naming/validation and sanitization rules.
- Documented new per-realm credential storage layout and provider-specific Azure path and environment wiring.
- Added migration guidance (breaking path change, no automatic migration), user-facing messaging, security considerations, testing guidance, and success metrics.
✏️ Tip: You can customize this high-level summary in your review settings.