Slim down toolchain example README @osterman (#2065)
what
- Reduced toolchain example README from 322 to 40 lines by removing duplicated reference documentation
- Cut registry types explanations, priority system details, use cases, troubleshooting, template variables table, and backward compatibility notes
- Focused the example on what it actually demonstrates: inline registry + Aqua fallback, custom commands with 4 dependency patterns, and workflows
- Updated file-browser DOCS_MAP to link toolchain example to the actual toolchain documentation instead of generic "Getting Started"
why
Example READMEs should document what the example demonstrates and link to the main docs, not re-document the reference material. The toolchain docs at /cli/configuration/toolchain already cover registry types, priority, template variables, troubleshooting, and all other reference topics comprehensively. This reduces duplication, keeps examples readable, and drives users to the authoritative documentation.
references
Follows the pattern of other well-maintained examples like demo-stacks (32 lines), demo-workflows (30 lines), and demo-vendoring (35 lines).
Summary by CodeRabbit
- Documentation
- Streamlined toolchain documentation with a focus on practical examples and action-oriented workflows, removing extensive configuration details for more concise guidance
- Expanded documentation navigation with three dedicated pages for Toolchain Configuration, Toolchain Registries, and Toolchain Commands, replacing the previous single Getting Started reference
feat: Add support for SSE-C encryption in !terraform.state lookups @mtb-xt (#2060)
what
- This PR adds support for SSE-C encryption in !terraform.state lookups.
why
- This would allow using S3-compatible state storage, that only supports SSE-C encryption (i.e. Hetzner Cloud)
- OpenTofu supports SSE-C encryption in remote state S3 backend.
references
- https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html
- https://docs.hetzner.com/storage/object-storage/howto-protect-objects/encrypt-with-sse-c
- https://opentofu.org/docs/v1.11/language/settings/backends/s3/#s3-state-storage
N.B.
Although AWS is deprecating SSE-C support in April 2026, for some other providers, like Hetzner Cloud, it's either SSE-C, or "store your state in plaintext".
Until atmos supports OpenTofu's state encryption, this is an OK-ish alternative, in my opinion...
Summary by CodeRabbit
-
New Features
- Added Server‑Side Encryption with Customer‑Provided Keys (SSE‑C) support for S3 remote state reads, configurable via backend attribute or environment variable.
-
Tests
- Added comprehensive test coverage for SSE‑C key handling, validation, MD5 headers, and precedence behavior.
-
Documentation
- Added docs and a blog post with usage examples, key format, and precedence rules.
-
Chores
- Updated public roadmap to mark SSE‑C support as shipped.
- Exposed a new public error indicating invalid SSE‑C customer keys.
Add: backend generation for Terraform Cloud/Enterprise when !terraform.output function is used. @gitbluf (#2058)
What
- Added Terraform Cloud backend support to
pkg/terraform/outputpackage - Added test coverage
Why
!terraform.outputfunction fails when components use Terraform Cloud/Enterprise backend becausegenerateBackendConfigfunction inpkg/terraform/outputpackage doesn't support cloud backend structure, causing the generation of the dependency component backend to default to the default backend resulting in an error.
Error output:
Error
Error: failed to get terraform output for component cluster in stack eks-cluster output cluster_version: failed to
execute terraform output for component cluster in stack eks-cluster terraform init failed: exit status 1 Error:
Unsupported backend type on backend.tf.json line 4, in terraform.backend: 4:
"cloud": { There is no explicit backend type named "cloud". To configure HCP
Terraform, declare a 'cloud' block instead.
Error
Error: exit status 1
- Terraform Cloud requires
terraform.cloudat top level, notterraform.backend.cloudlike other backend types
Currrent
{
"terraform": {
"backend": {
"cloud": {
"organization": "<org-name>",
"workspaces": {
"name": "terraform_workspace_name"
}
}
}
}
}
After the PR
"terraform": {
"cloud": {
"organization": "<org-name>",
"workspaces": {
"name": "terraform_workspace_name"
}
}
}
}
References
- Terraform Cloud backend documentation: https://developer.hashicorp.com/terraform/language/settings/terraform-cloud
- slack conversation
Summary by CodeRabbit
-
New Features
- Terraform Cloud backend support for !terraform.output with workspace-aware backend generation and token replacement; non‑Cloud backend behavior unchanged.
-
Tests
- Expanded cloud backend test coverage, including workspace token replacement scenarios and custom verification hooks.
-
Documentation
- Added blog post documenting Terraform Cloud backend behavior and example usage.
- Added a new blog author entry.
-
Chores
- Roadmap updated to mark Terraform Cloud backend support milestone as shipped.
feat: implement auth realm isolation with credential separation @Benbentwo (#2043)
What
Implement credential realm isolation for Auth to prevent credential collisions when engineers work with multiple repositories using identical identity names. Credentials are now stored in realm-isolated directories (~/.config/atmos/{realm}/), with realm computed from environment variables, configuration, or the config path hash.
Why
When multiple customer repositories use the same identity names (e.g., "aws-user", "dev-role"), Atmos credentials for different environments collide. Realm isolation ensures that credentials for "dev-role" from customer-A and customer-B are kept separate, preventing authentication failures and security issues.
Changes
- Add
SetRealm()method to Identity and Provider interfaces - Manager propagates realm to all identities/providers after construction
- All keyring backends include realm in credential keys (
atmos:{realm}:{alias}) - AWS file paths now always include realm:
~/.config/atmos/{realm}/aws/{provider}/{credentials,config} - Add
--all-realmsflag toatmos auth logoutto clear all Atmos credentials across all realms - Display realm and source in
atmos auth whoamioutput - Non-breaking: existing credentials in non-realm paths are discovered via workspace, users must re-authenticate
References
- Related to auth realm isolation PRD (#2033)
Summary by CodeRabbit
-
New Features
- Realm-scoped credential isolation to prevent credential collisions across repositories.
- New --all-realms flag to logout from all realms.
- CLI now shows active Realm (and its source) in atmos auth login and atmos auth whoami.
-
Configuration
- Realm precedence: ATMOS_AUTH_REALM env var → auth.realm in atmos.yaml → auto-generated from CLI config path.
-
Documentation
- Blog post and roadmap entry added.
-
Breaking Changes
- Credential storage/paths changed — re-authenticate with atmos auth login.
feat: Modernize Helmfile EKS integration @osterman (#1903)
what
- Make EKS integration opt-in by changing
use_eksdefault fromtruetofalse - Add
cluster_name_templatewith Go template syntax ({{ .vars.namespace }}-{{ .vars.stage }}-eks) - Add
cluster_nameconfig for explicit fixed cluster names - Add
--cluster-nameflag to override cluster name at runtime - Implement cluster name precedence: flag → config → template → pattern (deprecated)
- Deprecate
cluster_name_patternwith warning, recommendcluster_name_template - Deprecate
helm_aws_profile_patternwith warning, recommend--identityflag - Allow helmfile to work with existing kubeconfig (non-EKS: k3s, GKE, AKS)
why
These changes address DEV-2345 and DEV-2347 by modernizing the Helmfile EKS integration to be more flexible and align with Atmos's identity system. Users can now use helmfile with any Kubernetes cluster (not just EKS), have explicit control over cluster names, and use the standard --identity flag for AWS authentication instead of custom pattern configurations.
references
Summary by CodeRabbit
-
New Features
- Added
--cluster-nameCLI flag andcluster_name_templatefor flexible EKS cluster naming - Added
--identityflag for AWS authentication support
- Added
-
Configuration Changes
- EKS support is now opt-in;
use_eksdefaults to false - Established cluster name resolution precedence: flag → config → template → pattern
- EKS support is now opt-in;
-
Deprecations
helm_aws_profile_patterndeprecated; use--identityflag insteadcluster_name_patterndeprecated; usecluster_name_templateinstead
Detect deleted components in affected stacks @aknysh (#2063)
what
- Deleted Component Detection:
atmos describe affectednow detects components and stacks that have been deleted in HEAD (current branch) compared to BASE (target branch) - New Output Fields: Added
deleted(boolean) anddeletion_type(string:componentorstack) fields to the affected output schema - New Affected Reasons: Added
deletedanddeleted.stackas valid affected reasons - Integration Test Fixture: Added comprehensive test fixture at
tests/fixtures/scenarios/atmos-describe-affected-deleted-detection/ - Bug Fix: Fixed issue where stacks that only exist in BASE (not HEAD) were not being discovered during comparison - the code now re-scans BASE directory for stack config files instead of just converting HEAD paths
- Documentation: Updated
describe-affected.mdxwith new fields, reasons, and CI/CD workflow examples - GitHub Actions Guide: Added new section in
affected-stacks.mdxfor destroy workflow integration - Blog Post: Added changelog entry announcing the feature
- Roadmap: Updated CI/CD initiative with shipped milestone (progress: 80%)
why
- Resource Leaks: Previously, when components or stacks were removed from configuration, CI/CD pipelines had no automated way to detect these deletions and trigger
terraform destroy - Manual Destruction Required: Users had to manually identify and destroy removed components, which was error-prone and could lead to orphaned cloud resources
- Incomplete CI/CD: Pipelines couldn't fully automate the infrastructure lifecycle - they could only handle creation and modification, not deletion
- Audit Gaps: No automated tracking of what infrastructure was removed from configuration
How It Works
The algorithm now performs a second pass over BASE stacks to detect deletions:
-
For each stack in BASE:
- If stack doesn't exist in HEAD → all components marked as
deleted.stack - If stack exists in HEAD → check each component
- If component doesn't exist in HEAD → marked as
deleted
- If component doesn't exist in HEAD → marked as
- If stack doesn't exist in HEAD → all components marked as
-
Abstract components (
metadata.type: abstract) are not reported as deleted since they are blueprints and not provisioned
CI/CD Integration
Users can now separate apply and destroy workflows:
# Get modified components (for apply)
atmos describe affected --query '[.[] | select(.deleted != true)]'
# Get deleted components (for destroy)
atmos describe affected --query '[.[] | select(.deleted == true)]'Test Coverage
-
8 unit tests for deletion detection logic covering:
- Component deleted from stack
- Entire stack deleted
- Abstract components not reported
- Stack filter support
- Multiple component types
- Edge cases (no components section, no deletions)
-
2 integration tests using new fixture:
TestDescribeAffectedDeletedComponentDetectionTestDescribeAffectedDeletedComponentFiltering
references
- PRD:
docs/prd/describe-affected-deleted-detection.md - Related to CI/CD simplification initiative on roadmap
Summary by CodeRabbit
-
New Features
- Detects deleted components and stacks in describe-affected; adds two output fields: deleted and deletion_type.
-
Documentation
- Added PRD, blog post, CLI docs and CI/CD examples describing deleted-detection and destruction workflows.
-
Tests
- Added unit/integration tests and fixtures covering deletion scenarios, filtering, and abstract-component behavior.
-
Chores
- Bumped toolchain/dependencies and refreshed NOTICE license entries.
-
Mocks
- Added telemetry mock method to support feature-flag checks.
-
Errors
- Introduced a new sentinel error for no stack manifests found.
feat: add workflow environment variable support with hierarchical merging @Benbentwo (#2050)
what
- Add
envmap support at workflow and step levels in workflow YAML files - Environment variables are merged hierarchically with step-level overriding workflow-level for the same keys
- Support inheritance pattern where different keys from workflow and step levels are both available to the command
why
- Users need the ability to define common environment variables at the workflow level
- Step-level env vars allow overriding workflow defaults for specific steps
- Hierarchical merging provides a flexible, intuitive interface consistent with how
stackfields work
references
- Enables user feature request for workflow environment variable support
- Follows existing hierarchical pattern used for stack field overrides
Summary by CodeRabbit
-
New Features
- Workflow- and step-scoped environment maps added; variables merge hierarchically with step values taking precedence and identity/auth vars appended.
-
Bug Fixes
- Environment preparation now always starts from the system/global base environment and consistently preserves/merges it across steps.
-
Documentation
- CLI docs and a new blog post describe merge order, scoping, and precedence.
-
Tests
- Expanded unit and fixture tests covering merge, precedence, override, scoping, and auth interactions; tests now validate dynamic environment composition.
Promote key auth milestones to featured @osterman (#2062)
what
- Promote 6 key authentication milestones to featured status: atmos auth command framework, AWS SSO, GitHub OIDC, keyring backends, zero-config SSO, and automatic ECR authentication
- Remove planned Vault integration milestone from roadmap
- Update secrets-management initiative to shipped status (100% progress)
why
Vault integration is not planned for the Atmos product. The promoted auth milestones represent core shipped features that should be highlighted as featured accomplishments on the public roadmap.
Summary by CodeRabbit
- Documentation
- Updated product roadmap with improved prioritization and categorization for greater visibility.
- Marked Secrets Management and Secrets Masking initiatives as shipped and complete.
- Removed Vault integration milestone from Secrets Management roadmap.
feat: version-aware JIT source provisioning with TTL-based cleanup @osterman (#2010)
what
- Implement version-aware JIT source provisioning that automatically re-provisions workdirs when remote source version or URI changes
- Add incremental local sync using per-file checksum comparison (SyncDir) instead of full directory copy
- Support TTL-based cleanup for stale workdirs with
--expired,--ttl, and--dry-runflags - Move workdir metadata from
.workdir-metadata.jsonto.atmos/metadata.jsonfor better organization - Track
source_uri,source_version, andlast_accessedtimestamps in metadata
Additional Fixes
- Closes #2019 - Fix JIT provisioning gaps in generate commands
terraform generate varfile/terraform generate backend- now support JIT-sourced componentshelmfile generate varfile- now supports JIT-sourced componentspacker output- now supports JIT-sourced components
why
- Previously, changing a component's source version required manually cleaning the workdir before changes took effect
- Full directory copy was inefficient for local development with frequent small changes
- No mechanism existed to automatically clean up stale workdirs that accumulate over time
- Enhanced metadata enables intelligent provisioning decisions and better observability
- Generate commands failed with JIT-sourced components because they lacked source provisioning (#2019)
references
- New
pkg/durationpackage extracted for reusable duration parsing - Updated
workdir listandworkdir showcommands display version and access information - Blog post:
website/blog/2025-01-22-version-aware-jit-provisioning.mdx
Summary by CodeRabbit
- New Features
- JIT source provisioning now takes precedence over local components across all terraform commands when source and workdir are enabled.
- Automatic component refresh when version or source URI changes.
- TTL-based cleanup for stale workdirs using
--ttlflag (e.g.,--ttl=7d). - Enhanced workdir information displays source type, version, and last accessed timestamp.
- Incremental file synchronization—only changed files sync to workdirs.
🚀 Enhancements
fix: YAML strings ending with colons parsed incorrectly @aknysh (#2059)
what
- Fixed
EvaluateYqExpressionto correctly handle YAML strings ending with colons (e.g., AWS ARNs likearn:aws:secretsmanager:...:password::) - Added
isScalarStringpre-check to detect strings ending with colons before YAML parsing - Added
isMisinterpretedScalarpost-check to detect when YAML parser converts a scalar string into a map with null value - Added comprehensive test coverage (improved from 27.9% to 76.9%)
why
- The
!terraform.stateYAML tag was incorrectly parsing Terraform output values ending with colons (:or::), converting them from strings into nested map structures - This caused Terraform validation errors when variables were defined as
map(string)but received objects instead - AWS Secrets Manager ARNs require trailing
::for JSON key access with default version, making this a common issue for ECS task definitions
references
- Closes #2031
Summary by CodeRabbit
- Bug Fixes
- Improved YAML parsing to correctly handle string values with special characters (such as trailing colons) that were previously misinterpreted as complex data structures.
fix: improve describe affected detection for YAML functions and source/provision sections @aknysh (#2061)
what
- Fix YAML functions (
!terraform.state,!terraform.output) failing when processing BASE stacks that reference components not present in HEAD - Fix
describe affectednot detecting changes tosourceandprovisionsections
why
Fix 1: YAML functions ignore BASE paths
When running describe affected, YAML functions like !terraform.state would fail with "Could not find component" errors when:
- BASE (main branch) has a component that doesn't exist in HEAD (PR branch)
- A stack in BASE references that component via
!terraform.stateor!terraform.output
Root cause: YAML functions created a new AtmosConfiguration from the current working directory (HEAD) instead of using the modified configuration pointing to BASE.
Fix: Pass AtmosConfig through the YAML function resolution chain instead of nil.
Fix 2: Source and provision sections not detected
Changes to source and provision sections were silently ignored:
source.versionchanges (e.g., upgrading vendored module versions) were not detectedprovision.workdir.enabledchanges were not detected
Root cause: Only metadata, vars, env, settings, and component folder files were checked.
Fix: Add source and provision section checks with affected reasons stack.source and stack.provision.
references
- Test fixtures added for both scenarios
- Documentation:
docs/fixes/2026-02-07-describe-affected-yaml-functions-ignore-base-paths.md - Documentation:
docs/fixes/2026-02-07-describe-affected-source-provision-sections.md
Summary by CodeRabbit
Release Notes
-
Bug Fixes
- Fixed describe-affected to detect changes in source versioning and workdir configurations for components
- Resolved YAML function resolution to properly handle base path lookups in describe-affected
-
Chores
- Updated Atmos CLI version to 1.206.0
- Updated Go module dependencies
fix: terraform plan-diff respects metadata.component and workdir @aknysh (#2056)
what
- Fixed
atmos terraform plan-diffto properly resolvemetadata.componentwhen looking for planfiles - The command now calls
ProcessStacks()to resolveFinalComponentfrommetadata.componentbefore constructing the component path - Added support for workdir and source vendoring: when workdir is enabled, plan-diff now correctly looks for planfiles in the workdir path (e.g.,
.workdir/terraform/<stack>-<component>/) - Added comprehensive test coverage for plan-diff comparison and formatting functions
- Added test fixtures and documentation
why
- When a component instance name differs from the actual component (e.g.,
foobar-atmos-prowithmetadata.component: foobar),plan-diffwas looking in the wrong directory - Expected: Look for planfile in
components/terraform/foobar/ - Actual (bug): Was looking in
components/terraform/foobar-atmos-pro/orcomponents/terraform/ - When source vendoring + workdir is enabled, planfiles are stored in
.workdir/path, not the base component path - This caused failures in CI workflows using
github-action-atmos-terraform-applywhen comparing planfiles for components withmetadata.componentset or workdir enabled
changes
| File | Change |
|---|---|
internal/exec/terraform_plan_diff.go
| Added ProcessStacks call + workdir path support
|
internal/exec/terraform_plan_diff_comparison.go
| Use shared u.SliceContainsString utility
|
internal/exec/terraform_plan_diff_test.go
| Added workdir and source vendoring tests |
docs/fixes/plan-diff-metadata-component.md
| Documentation of fix |
references
- Documentation:
docs/fixes/plan-diff-metadata-component.md
Summary by CodeRabbit
-
Bug Fixes
- Plan-diff now properly respects metadata.component configuration for correct component path resolution.
-
Documentation
- Added comprehensive documentation detailing the plan-diff metadata.component fix, including root cause analysis and testing guidance.
-
Tests
- Expanded test coverage for plan-diff scenarios, including metadata component resolution, error handling, and plan file operations.
fix: Terraform shell command not working from Atmos interactive UI @aknysh (#2055)
what
- Fix
terraform shellcommand when invoked from the Atmos interactive UI (TUI) - Route
terraform shelldirectly toExecuteTerraformShell()from the UI dispatcher, bypassingExecuteTerraform() - Add
AuthManagerpropagation toterraform shellfor YAML functions like!terraform.state - Add
--identityflag support toterraform shellcommand - Extract testable helpers (
shellInfoFromOptions,resolveWorkdirPath,shellOptionsForUI) from inline logic - Add auth orchestration functions (
createAndAuthenticateAuthManager,getMergedAuthConfig,storeAutoDetectedIdentity) toutils_auth.go
why
- The Atmos interactive UI dispatches commands through
ExecuteTerraform(), which had no handler for theshellsubcommand. Sinceterraform shellis an Atmos-only command (not a native Terraform subcommand), it fell through and attempted to executeterraform shellas a native command, which doesn't exist, resulting in:Terraform has no command named "shell" AuthManagerwas not being passed toProcessStacksin the shell command, causing!terraform.stateand!terraform.outputYAML functions to fail with authentication errors- The
--identityflag was missing fromterraform shell, preventing users from specifying which AWS identity to use for authentication
references
- Closes #2017
Summary by CodeRabbit
-
New Features
- Added
--identityflag (alias-i) to the terraform shell command to specify AWS identity.
- Added
-
Improvements
- Shell execution now surfaces identity in dry-run output, uses improved workdir resolution, and routes the UI path through the interactive shell flow.
- Enhanced authentication handling with merged global/component auth and auto-detected identity fallback.
-
Documentation
- CLI docs updated with
--identityflag and examples.
- CLI docs updated with
-
Tests
- Extensive unit tests for auth merging, identity handling, shell options mapping, and workdir logic.