github cloudposse/atmos v1.204.0

latest release: v1.204.1-rc.0
8 hours ago
feat: Improve source provisioner UX with spinners and interactive delete @osterman (#1965)

what

  • Added spinner feedback during auto-provisioning in vendorToTarget()
  • Introduced PromptForConfirmation() to pkg/flags/interactive.go for reusable destructive action confirmation prompts
  • Updated delete command to prompt interactively instead of requiring --force flag
  • Delete operation now shows spinner during deletion with consistent visual feedback
  • Added blog post and roadmap milestone documenting the enhancement

why

These changes improve UX consistency across the CLI by providing:

  • Better visual feedback during vendoring operations with spinners matching other long-running operations
  • Interactive confirmation prompts for destructive actions that gracefully degrade in non-TTY environments
  • A reusable pattern for other commands that need confirmation prompts

references

Related to source provisioner improvements for better developer experience with JIT vendoring.

Summary by CodeRabbit

  • New Features

    • Interactive confirmation for destructive actions (requires TTY unless --force).
    • Interactive component/stack selection added to pull, delete, describe, and list; positional args now optional.
    • Shell completion for component and stack names.
    • Progress spinners for vendoring, provisioning and deletion flows; clearer interactive/error messaging.
  • Tests

    • Expanded coverage for prompts, confirmations, non‑TTY flows, provisioning detection, and completion helpers.
  • Documentation

    • UX docs updated with TTY vs non‑TTY guidance and force behavior.

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

fix: announcement bar responsive wrapping @osterman (#1966)

what

  • Override Docusaurus default fixed 30px height on the announcement bar at desktop widths
  • Allow the announcement bar to wrap gracefully to multiple lines at mid-range viewport widths instead of clipping text

why

  • At viewport widths between 997px and ~1400px, the announcement bar was clipping the text to a single 30px line
  • Very wide screens displayed correctly (text fit on one line), and mobile displayed correctly (height: auto)
  • The fix enables responsive text wrapping at mid-range widths where the message needs multiple lines

references

  • Docusaurus AnnouncementBar default styles: website/node_modules/@docusaurus/theme-classic/src/theme/AnnouncementBar/styles.module.css

Summary by CodeRabbit

  • Style
    • Improved announcement bar layout and text wrapping on desktop viewports (997px and above) for better content visibility and presentation.

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

docs: nest role_arn under assume_role @kyledecot (#1963)

what

Fixes minor error w/ docs so that role_arn is properly nested under assume_role.

why

Docs incorrectly had role_arn at the top-level of s3 backend configuration.

references

https://developer.hashicorp.com/terraform/language/backend/s3

Summary by CodeRabbit

Release Notes

  • Documentation
    • Updated Terraform S3 backend configuration examples to reflect the new nested assume_role structure for specifying IAM role access.

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

feat: Add source provisioning example @osterman (#1962)

what

  • Added examples/source-provisioning/ demonstrating the source provisioner feature for Just-in-Time component vendoring
  • Includes separate dev and prod stacks using different module versions
  • Demonstrates workdir isolation for terraform execution
  • Simple, focused example showing one feature without catalog complexity

why

  • Provides a working reference for users learning source provisioning
  • Complements existing test fixtures and documentation with a clean runnable example
  • Enables quick validation that source provisioning works end-to-end

references

Summary by CodeRabbit

  • Documentation
    • Added source provisioning example with comprehensive README documentation and configuration samples demonstrating just-in-time component vendoring across development and production environments.

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

docs: refactor terraform usage page @osterman (#1952)

what

  • Refactored terraform usage.mdx from 871 to 149 lines into a focused overview page
  • Added Multi-Component Operations sections to terraform-plan, terraform-apply, terraform-deploy, and terraform-destroy command pages
  • Moved 300+ lines of multi-component examples and flag documentation to individual command pages
  • Eliminated 765 lines of duplicate content across documentation

why

The terraform usage page served as both a landing page and comprehensive reference, resulting in massive duplication. Multi-component operations documentation now lives in individual command pages where it's directly relevant, improving maintainability and following the pattern used by other command groups like describe.

references

Issue: Terraform usage page was not refactored after subcommands were broken out into separate pages.

Summary by CodeRabbit

  • Documentation
    • Added comprehensive multi-component operations documentation for terraform apply, deploy, and plan commands, covering filtering flags and deployment modes including affected components and query-based selection.
    • Reorganized terraform usage documentation with a new Command Modes section, streamlined examples, and improved navigation for single and multi-component workflows.

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

feat: Add data-driven roadmap slide deck with pagination @osterman (#1953)

what

  • Created a new data-driven slide deck at /slides/roadmap that visualizes the Atmos product roadmap
  • Featured initiatives appear first, followed by other initiatives with progress bars
  • Paginated milestone viewer with clickable dots and Shift+Left/Right keyboard navigation
  • Styled milestones with status icons, badges for releases/docs, inline code formatting
  • Progress bar visualization for initiative completion percentages

why

  • Provides a modern, interactive way to present the Atmos roadmap to stakeholders and the community
  • Data-driven from roadmapConfig ensures the slides stay in sync with product planning
  • Paginated milestones allow initiatives to showcase multiple achievements without cluttering slides
  • Keyboard navigation provides power-user experience alongside mouse interaction

references

  • Roadmap data source: website/src/data/roadmap.js
  • Slide deck system: website/src/components/SlideDeck/

Summary by CodeRabbit

  • New Features

    • Added "Atmos Roadmap 2025-2026" interactive slide deck with paginated milestone lists, status badges, progress bars, links, and presenter notes.
    • Milestone pagination supports Shift+ArrowLeft/Right; holding Shift while paging no longer advances slides.
  • Style

    • Extensive visual and responsive styling for slides: badges, icons, progress bars, pagination dots, typography, and layout refinements.
  • Other

    • Updated roadmap theme title to "Reducing Tool Fatigue".

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

feat: stack name identity with zero-config filename fallback @osterman (#1934)

what

  • Enforce single stack name identity - each stack now has exactly ONE valid identifier
  • Add filename-based identity - stacks work with just filenames when no naming config exists (zero-config for newcomers)
  • Improve error messages - when using an invalid stack name, error now says "invalid stack" and provides hints suggesting the correct name and how to list available stacks
  • Fix ProcessStacks to recognize the stack manifest name field when matching stacks
  • Add JSON schema documentation for the name field
  • Add PRD documenting the stack name identity rules
  • Add CLI smoke tests with golden snapshots

why

Issue 1: Manifest name not recognized

When a stack manifest has name: "my-explicit-stack", users expect to use that name in commands:

atmos tf plan vpc -s my-explicit-stack

Previously this failed with "Could not find the component vpc in the stack".

Issue 2: Multiple names worked (incorrect)

After the initial fix, ALL of these worked for the same stack:

atmos tf plan vpc -s my-explicit-stack  # explicit name
atmos tf plan vpc -s prod-ue1           # generated from name_template
atmos tf plan vpc -s legacy-prod        # filename

This is incorrect - a stack should have exactly ONE valid identifier.

Issue 3: Misleading error message

When using an invalid stack name (e.g., filename when explicit name exists), the error said "invalid component" instead of "invalid stack":

**Error:** invalid component

Could not find the component vpc in the stack legacy-prod.

New: Zero-config for newcomers

When no name, name_template, or name_pattern is configured, stacks are now identified by their filename. This lets newcomers get started without any naming configuration:

# stacks/prod.yaml - no naming config needed
components:
  terraform:
    vpc:
      vars:
        cidr: "10.0.0.0/16"
# Just works!
atmos terraform plan vpc -s prod

Stack Name Identity Rule

Each stack has exactly ONE valid identifier based on precedence:

Priority Source When Valid
1 name field in manifest If set, ONLY this name works
2 name_template result If set (and no explicit name), ONLY this works
3 name_pattern result If set (and no template/name), ONLY this works
4 Filename Only if nothing else is configured

Evidence

atmos list stacks - shows canonical names
my-legacy-prod-stack
no-name-prod

Note: my-legacy-prod-stack is shown (explicit name), not legacy-prod (filename).

atmos describe component vpc -s no-name-prod - filename works when no naming config
{
  "atmos_component": "vpc",
  "atmos_stack": "no-name-prod",
  "atmos_stack_file": "no-name-prod",
  "stack": "no-name-prod",
  "workspace": "no-name-prod"
}
atmos describe component vpc -s my-legacy-prod-stack - explicit name works
{
  "atmos_component": "vpc",
  "atmos_stack": "my-legacy-prod-stack",
  "atmos_stack_file": "legacy-prod",
  "atmos_manifest": "legacy-prod",
  "stack": "my-legacy-prod-stack",
  "workspace": "my-legacy-prod-stack"
}

Note: atmos_stack is my-legacy-prod-stack (explicit name), while atmos_stack_file shows legacy-prod (the actual filename).

atmos describe component vpc -s legacy-prod - FAILS with helpful suggestions
# Error

**Error:** invalid stack

## Explanation

Stack legacy-prod not found.

## Hints

💡 Did you mean my-legacy-prod-stack?

💡 Run atmos list stacks to see all available stacks.

This is correct - legacy-prod.yaml has name: my-legacy-prod-stack, so only that identifier is valid. The error now correctly identifies this as an invalid stack (not component) and provides hints suggesting the correct name and how to list available stacks.

atmos terraform plan vpc -s legacy-prod - FAILS with helpful suggestions
# Error

**Error:** invalid stack

## Explanation

Stack legacy-prod not found.

## Hints

💡 Did you mean my-legacy-prod-stack?

💡 Run atmos list stacks to see all available stacks.

Changes

  • errors/errors.go: Add ErrInvalidStack sentinel error
  • internal/exec/utils.go: Enforce single-identity matching in findComponentInStacks; return helpful error with suggestion when filename is used for stack with explicit name; enable filename fallback in processStackContextPrefix
  • internal/exec/stack_manifest_name_test.go: Add tests for identity enforcement, filename fallback, and improved error messages
  • tests/test-cases/stack-manifest-name.yaml: Add CLI smoke tests with golden snapshots for stack name identity
  • pkg/datafetcher/schema/atmos/manifest/1.0.json: Add schema documentation for name field
  • docs/prd/stack-name-identity.md: PRD documenting the specification (status: Implemented)
  • website/blog/2026-01-06-stack-name-identity.mdx: Blog post documenting the changes
  • website/src/data/roadmap.js: Add "Filename-based stack identity" to DX roadmap

References

Summary by CodeRabbit

  • New Features

    • Single canonical stack identity with precedence (name → name_template → name_pattern → filename), zero‑config filename naming, and clearer "Did you mean…?" suggestions for invalid stacks.
  • Documentation

    • Added product requirements and a blog post explaining identity rules, examples, migration guidance, and UX notes.
  • Tests

    • Expanded test suites and updated snapshots to validate naming precedence, listing/describe behavior, and suggestion messages.
  • Chores

    • Roadmap updated and CLI telemetry notice added to outputs.

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

chore: Upgrade Docusaurus from 3.6.3 to 3.9.2 @osterman (#1926)

what

  • Upgrades all Docusaurus packages to version 3.9.2 (latest stable)
  • Updates package.json and pnpm-lock.yaml dependencies

why

The upgrade includes support for DocSearch v4 with AI-powered search features, improved i18n configuration options for multi-domain deployments, React 19 compatibility fixes, and new build APIs.

references

Summary by CodeRabbit

  • New Features

    • Ask AI conversational search now integrated into documentation, powered by DocSearch v4 and ChatGPT for natural language queries and contextual answers.
  • Documentation

    • Added Algolia search indexing setup guide and Ask AI feature announcement blog post.
  • Chores

    • Updated documentation framework dependencies and roadmap entries.

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

feat: Add robots.txt for search engine indexing @osterman (#1943)

what

  • Adds robots.txt to website/static/ for search engine indexing
  • Includes Algolia crawler verification token
  • Explicitly allows all crawlers with User-agent: * and Allow: /
  • References sitemap for efficient crawler discovery

why

  • Improves search engine discoverability of the Atmos documentation
  • Enables Algolia crawler verification for site search functionality
  • Maximizes indexing potential by explicitly allowing all crawlers

references

  • Algolia crawler verification: 10F61B92D9EB1214

Summary by CodeRabbit

  • Chores
    • Added web crawler configuration to improve site indexing and point crawlers to the sitemap.
    • Updated deployment configuration to make the site base URL configurable via an environment variable, enabling PR-specific preview hosts during builds.

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

Add generate section inheritance and auto-generation support @osterman (#1878)

what

  • Add generate section to stack config inheritance pipeline with full support for base components, component-level overrides, and component overrides
  • Implement atmos terraform generate files command with --all, --dry-run, and --clean flags for generating auxiliary configuration files
  • Add auto_generate_files: true configuration option to automatically generate files during terraform operations
  • Extension-aware serialization: .json, .yaml, .yml files serialize in their respective formats, .tf and .hcl files generate valid HCL
  • Go template support: String values in generate sections are processed as Go templates with full access to component context
  • Update all integration test snapshots to reflect new auto_generate_files configuration field

why

Teams often need to generate auxiliary configuration files alongside Terraform components—files like .tool-versions, terragrunt.hcl shims for gradual migration, or environment-specific locals. This feature brings file generation directly into Atmos's declarative configuration model, maintaining the principle that infrastructure configuration should be fully described in YAML and reproducible from stack manifests. The inheritance support ensures teams can define common generate patterns in base components while allowing component-specific customization.

references

  • Implements declarative file generation PRD
  • Feature branch: osterman/generate-section-prd

Summary by CodeRabbit

  • New Features

    • Added declarative file generation for Terraform components via new generate sections in stack configurations.
    • New atmos terraform generate files command to automatically create auxiliary configuration files.
    • Support for extension-aware serialization (JSON, YAML, HCL, Terraform).
    • Go template processing for dynamic content in generated files.
    • Dry-run mode to preview generated files without writing.
    • Multi-level configuration inheritance for generated files.
    • Auto-generation toggle via auto_generate_files configuration.
  • Documentation

    • Added comprehensive guides for declarative file generation and CLI usage.
  • Tests

    • Added extensive test coverage for file generation and cleanup workflows.

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

feat(auth): add PRD for native Okta authentication identity @RoseSecurity (#1924)

what

[!NOTE]
This is my first PRD, so any feedback is appreciated!

Add PRD for native Okta authentication as a first-class identity provider in Atmos. Unlike the existing SAML-based integration, this introduces dedicated okta/* providers enabling:

  • OAuth 2.0 Device Authorization Grant for CLI authentication
  • Direct Okta API access with automatic token refresh
  • AWS/Azure/GCP federation via OIDC (AssumeRoleWithWebIdentity)
  • XDG-compliant credential storage (~/.config/atmos/okta/)

why

  • Provides implementation reference following established auth patterns (AWS, Azure PRDs)
  • Addresses user requests for native Okta support without browser-based SAML

Test plan

  • PRD follows universal file isolation pattern
  • Code samples reviewed for Atmos conventions
  • Implementation checklist is complete and actionable

references

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive Okta PRD defining goals, use cases (AWS OIDC federation, API access, multi-cloud), technical specification, token/file isolation and storage guidance, phased implementation roadmap, testing and security considerations, example policies, and an implementation checklist.
  • Chores
    • Added a roadmap milestone for Native Okta Authentication (Device Code Flow).

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

feat: Implement unified import adapter registry @osterman (#1897)

what

  • Added extensible ImportAdapter interface for pluggable import sources
  • Implemented ImportAdapterRegistry with lazy initialization and thread-safe registration
  • Created GoGetterAdapter handling http, https, git, s3, oci, and other remote schemes
  • Created LocalAdapter as default fallback for filesystem paths
  • Created MockAdapter for testing with mock:// scheme
  • Unified import handling via registry pattern instead of if/else chains
  • Removed obsolete functions (isRemoteImport, processRemoteImport, processLocalImport, downloadRemoteConfig)
  • Added comprehensive adapter tests with 90%+ coverage

why

  • Extensible design: New import sources (terragrunt://, etc) can be added without modifying core logic
  • Clear separation of concerns: Each adapter handles its own scheme
  • Testability: Mock adapter enables unit testing without external dependencies
  • Thread-safe: Lazy initialization with sync.Once prevents import cycles and race conditions
  • Reduced complexity: Unified registry replaces scattered conditional logic
  • Better error handling: Adapters can implement their own error strategies

references

  • Implements design from docs/prd/import-adapter-registry.md
  • Resolves circular dependency issues with lazy adapter initialization
  • Provides foundation for future adapters (terragrunt, etc)

Summary by CodeRabbit

  • New Features

    • Unified, extensible import adapter system enabling custom schemes, adapter-first routing, and improved handling of nested imports.
  • Tests

    • Expanded adapter-focused tests covering routing, error handling, nested imports, mock scenarios, and registry behavior.
  • Documentation

    • Added a detailed PRD for the Import Adapter Registry with architecture, examples, and phased rollout.
  • Chores

    • Bumped Atmos version in build/config and added a roadmap milestone for the adapter registry.

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

feat: Add multiple terraform output formats for CI integration @osterman (#1885)

Summary

  • Moved all terraform output execution logic from internal/exec/ to new pkg/terraform/output/ package
  • Implemented dependency injection pattern using ComponentDescriber interface to eliminate circular dependency
  • Created backward-compatible wrappers to maintain API compatibility
  • Added 39 comprehensive unit tests with 89 total passing tests

What Changed

  • Architecture: Package-based dependency injection removes circular dependency
  • Logic: No behavioral changes, same functionality with improved organization
  • Testing: Comprehensive unit test coverage with mocks for testability
  • Performance: Identical behavior, slight code organization improvements

Verification

  • make build passes
  • make lint passes (0 issues)
  • ✅ All 89 tests pass
  • ✅ No circular dependencies

Summary by CodeRabbit

  • New Features

    • terraform output: new --format (json,yaml,hcl,env,dotenv,bash,csv,tsv), --output-file, --uppercase and --flatten; supports single-output or all-outputs and write-to-file.
    • Automatic generation of Terraform backend and provider override files; improved workspace handling and a TTY-aware spinner for CLI feedback.
  • Tests

    • Extensive unit and integration tests covering formatting, executor, backend, environment and workspace behaviors.
  • Documentation

    • CLI docs and blog post for output formatting and examples.
    • Added “Concurrent Sessions (MANDATORY)” guidance.

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

feat: Add native Terraform provider caching with XDG support @osterman (#1882)

what

Atmos now automatically caches Terraform providers across all components using the TF_PLUGIN_CACHE_DIR environment variable with XDG-compliant default paths (~/.cache/atmos/terraform/plugins). This feature is enabled by default with zero configuration required, dramatically reducing terraform init times and network bandwidth.

why

In large Atmos projects with many components, each terraform init downloads the same providers repeatedly. For the AWS provider alone, this can mean downloading 300+ MB per component. With provider caching, Atmos downloads each provider version once and reuses it across all components - achieving 10-50x faster init times in testing.

references

This implements automatic provider caching with validation for invalid TF_PLUGIN_CACHE_DIR values (empty string or root path) and respects user overrides via environment variables or atmos.yaml configuration.

Summary by CodeRabbit

  • New Features

    • Zero‑config Terraform provider caching enabled by default with optional custom cache directory and new terraform clean --cache flag (supports --force, dry‑run, interactive and non‑TTY flows). Exposes ATMOS_COMPONENTS_TERRAFORM_PLUGIN_CACHE and ATMOS_COMPONENTS_TERRAFORM_PLUGIN_CACHE_DIR plus TF_PLUGIN_CACHE_DIR behavior.
  • Documentation

    • Added blog and CLI docs with examples, flags, and env var references.
  • Tests

    • Extensive unit and end‑to‑end tests for configuration, cache path resolution, init/reuse, and cleaning.

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

feat: Create pkg/runner with unified task execution @osterman (#1901)

what

  • Introduced pkg/runner package with unified Task type and CommandRunner interface
  • Tasks support flexible YAML parsing for both simple strings and structured syntax with timeout, retry, and identity config
  • Timeout enforcement via context.WithTimeout
  • Proper shell argument parsing using mvdan.cc/sh for quote handling
  • Updated custom commands to use the new Tasks type, enabling backward compatibility while supporting new syntax

why

Provides a shared execution layer for both custom commands and workflows, enabling code reuse and consistent task execution patterns across Atmos. Fixes DEV-3005.

references

Closes #DEV-3005

Summary by CodeRabbit

  • New Features

    • Unified task runner with structured per-step entries (timeout, retry, working_directory, stack) and support for shell and atmos task types.
  • Breaking Change

    • Command step format changed from simple string lists to structured Tasks — update custom command definitions accordingly.
  • Tests

    • Expanded tests and new mocks/helpers covering runner behavior, YAML decoding, task parsing, timeouts, overrides, and sequential execution.
  • Chores

    • Config decoding updated to handle the new task formats.
  • Documentation

    • Blog post documenting the unified task runner and Task formats.

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

🚀 Enhancements

Fix markdown rendering offset bug in toast messages @osterman (#1968)

what

  • Added trimLeftSpaces() function to properly handle leading space trimming when Glamour wraps spaces in ANSI escape codes
  • Updated toastMarkdown() and renderInlineMarkdownWithBase() to use ANSI-aware trimming
  • Multi-line toast messages now have consistent bullet point indentation with color enabled

why

Glamour wraps spaces in ANSI codes when color is enabled. The previous code used strings.TrimLeft() which isn't ANSI-aware and failed to remove leading spaces, causing inconsistent indentation in multi-line markdown output.

references

Fixes: Markdown rendering with inconsistent bullet list indentation in terminal UI messages

Summary by CodeRabbit

  • Bug Fixes

    • Improved trimming of leading/trailing spaces in styled/colored text so notifications, hints and inline markdown keep visual formatting intact.
  • User Experience

    • Backend provisioning now collects and shows backend warnings after the progress spinner completes to avoid interleaved output.
  • Tests

    • Added comprehensive tests covering whitespace trimming with styled/ANSI content.

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

feat: Automatic toolchain integration for custom commands and workflows @osterman (#1958)

what

New Feature: Automatic Toolchain Integration

  • Custom commands and workflows now automatically load tools from .tool-versions file
  • Workflow-specific dependencies can be declared in the workflow definition and override .tool-versions
  • Command-specific dependencies can be declared in the command definition
  • Tools are automatically installed and PATH is updated before execution
  • Component-level tool dependencies - Terraform/Helmfile/Packer components can declare tool dependencies that are resolved and installed before execution

Bug Fixes (Toolchain Bootstrap)

  • Fix atmos bootstrap failures for AWS CLI, jq, gum, and replicated by removing unconditional version prefix
  • Follow Aqua's actual behavior where version_prefix defaults to empty string, not "v"
  • Include ErrHTTP404 in 404 errors to enable version fallback mechanism
  • Fix template expansion in files.src for tools like Helm that use {{.OS}}-{{.Arch}} paths
  • Preserve all fields in resolveVersionOverrides for version-specific configs
  • Add darwin_all pattern support for universal macOS binaries

Bug Fixes (Workflows)

  • Fix workflow conditional stack processing - Workflows no longer require stacks configuration when --stack flag is not provided. Previously, running atmos workflow <name> would fail with "stack base path must be provided" even for simple shell workflows that don't use stacks. Now stacks are only validated when --stack is explicitly passed.

Bug Fixes (Batch Install UX)

  • Prevent .tool-versions duplication - Add SkipToolVersionsUpdate option to prevent duplicate entries when both InstallSingleTool and updateToolVersionsFile are called
  • Enable spinner during batch installs - Spinner now animates during downloads, not just after each tool completes
  • Reduce batch install message noise - Add ShowInstallDetails option to show only simple "Installed X" messages in batch mode, while single-tool mode retains verbose output (path, size, registered)
  • Add showProgressBar parameter - RunInstall now accepts showProgressBar to control spinner visibility for custom command installs

Bug Fixes (Error Handling)

  • Guard against nil error in ErrorBuilder.WithCause - Prevent panic when b.err is nil by using cause directly as the stored error
  • Preserve error hints through error chain propagation - Hints from cause errors are now properly preserved via GetAllHints()
  • Add alias configuration hint - When tool not found in registry, suggest adding an alias in atmos.yaml
  • Suppress PATH hint for dependency installs - Only show PATH export hint when running toolchain install directly

Documentation & Examples

  • Add documentation for toolchain integration in custom commands and workflows
  • Add examples/toolchain/ with working examples showing:
    • .tool-versions file with tool dependencies
    • Custom command with dependencies declaration
    • Workflow with dependencies declaration
    • Component-level tool dependencies - Mock component with opentofu: "^1.10.0" constraint
    • Inline registry with custom tool definitions (jq, yq)
    • SemVer constraint examples (^1.7.0, ~> 4.40.0)

Test Coverage

  • Add DependencyProvider interface for testability
  • Add 9 new tests for ensureToolchainDependencies() covering all code paths
  • Add tests for extraction edge cases (gzip, tar.gz, MIME type dispatch)
  • Add test for .tool-versions directory error path
  • Add workflow conditional stack processing tests:
    • TestWorkflowWithoutStacksConfig - workflows succeed without stacks config
    • TestWorkflowWithStackFlagRequiresStacksConfig - workflows fail when --stack passed but stacks not configured
    • TestWorkflowWithStackFlagAndStacksConfigured - workflows succeed when both are present
  • Coverage improvements: executor ~19% → 100%, extract functions to 100%

why

Toolchain Integration

Users managing infrastructure often need specific tool versions (terraform, kubectl, helm). The .tool-versions file is a standard way to declare these dependencies (used by asdf, mise). This PR enables Atmos to:

  1. Read .tool-versions and automatically install required tools
  2. Allow workflows to override versions for specific requirements
  3. Update PATH so commands execute with the correct tool versions
  4. Support component-level dependencies so different components can require different tool versions

Bootstrap Fixes

After PR #1948, multiple tools failed to install during bootstrap because version prefix handling didn't match Aqua's behavior. The code was unconditionally adding a "v" prefix when version_prefix was empty, breaking HTTP URLs (AWS CLI expects AWSCLIV2-2.32.31 not AWSCLIV2-v2.32.31).

Workflow Conditional Stack Processing

The workflow command was always requiring stacks configuration even when running simple shell workflows that don't reference any stacks. This was because InitCliConfig(info, true) unconditionally validated stacks. Now the second parameter is set based on whether --stack flag was provided, allowing workflows to run without any stacks configured.

Batch Install UX Improvements

The batch installer had several UX issues:

  • Duplicate entries - Both handleInstallSuccess and updateToolVersionsFile were writing to .tool-versions with different keys (e.g., "gum" vs "charmbracelet/gum")
  • No animation during downloads - Spinner only animated after each tool completed, leaving users with no feedback during 5-30 second downloads
  • Too noisy - Each tool produced 3 lines of output; reduced to 1 concise line in batch mode

Error Handling Robustness

  • ErrorBuilder.WithCause could panic if called with nil base error - now handles gracefully
  • Error hints from wrapped causes were being lost - now preserved through the chain

Example Usage

.tool-versions:

terraform 1.10.3
kubectl 1.32.0
helm 3.16.4

Workflow with override:

workflows:
  deploy:
    description: Deploy infrastructure
    dependencies:
      tools:
        terraform: "1.11.0"  # Override .tool-versions
    steps:
      - command: terraform init
      - command: terraform apply

Component with tool dependency:

components:
  terraform:
    mock:
      metadata:
        component: mock
      dependencies:
        tools:
          opentofu: "^1.10.0"  # Install OpenTofu before execution
      vars:
        message: "Hello from toolchain demo"

references

  • Related to bootstrap failures in PR #1948
  • Documentation: website/docs/core-concepts/custom-commands/commands.mdx
  • Documentation: website/docs/core-concepts/workflows/workflows.mdx
  • Examples: examples/toolchain/

Summary by CodeRabbit

  • New Features

    • Automatic tool management from .tool-versions in commands and workflows; injectable dependency provider; batch installs; richer install options (progress bar, PATH hint, skip .tool-versions update); explicit version_prefix support so templates/URLs and SemVer behave only when configured.
  • Bug Fixes

    • Better 404 detection for version fallbacks, more robust archive extraction and binary detection, and spinner suppressed during debug to avoid garbled output.
  • Documentation

    • New docs and many examples for toolchain integration.
  • Tests

    • Large expansion of unit and integration tests across installs, prefix handling, extraction, dependency flows, and UI helpers.

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

fix: Fix backend CRUD issues - create visibility, error messages, and false success bug @osterman (#1960)

what

  • Fix create command not appearing in subcommands list (Use field was wrong)
  • Add ErrorBuilder pattern for missing --stack flag with helpful context
  • Add ErrProvisioningNotConfigured sentinel error to errors/errors.go
  • Fix false success bug: ProvisionBackend now returns error when provisioning not configured (strict behavior)
  • Update all affected tests to expect errors instead of nil returns

why

The backend commands had multiple issues:

  1. create subcommand wasn't visible in help because Use: "<component>" doesn't include the command name
  2. Error messages said "required flag not provided" without indicating which flag or how to fix it
  3. Running create without provisioning configuration would show "Successfully provisioned" even though nothing was done (false success)
  4. Tests incorrectly expected nil returns when configuration was missing

These fixes ensure the backend commands are discoverable, errors are helpful and actionable, and operations fail-fast with clear context.

references

  • Fixes false success bug in backend provisioning
  • Improves error messages for CLI usability
  • Ensures backend create command is discoverable in help

Summary by CodeRabbit

  • New Features

    • Optional positional args with interactive prompting for backend commands; bracket-style usage.
    • Automatic, opt-in backend provisioning during Terraform init with progress spinner, backend existence/name detection, and clearer progress messages.
  • Bug Fixes

    • Clear, actionable error when backend provisioning is missing or disabled; improved provisioning error signaling.
  • Tests

    • Expanded unit, integration, and end-to-end tests for backend flows, S3 backend (fake S3), prompting, and provisioning scenarios.
  • Documentation

    • New blog post and reference updates describing automatic backend provisioning and prompting behavior.

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

fix: Workflow name showing `` in `atmos list workflows` @aknysh (#1964)

what

  • Fixed atmos list workflows command showing <no value> for workflow names
  • The workflow name column now correctly displays workflow names instead of <no value>

why

  • The default column template for "Workflow" used {{ .name }} but the data extractor uses "workflow" as the key
  • This mismatch caused Go templates to output <no value> when the .name field wasn't found in the data
  • Users were seeing output like:
    networking.yaml  <no value>  Run terraform plan on all vpc components...
    
    Instead of:
    networking.yaml  plan-all-vpc  Run terraform plan on all vpc components...
    

Changes

  1. cmd/list/workflows.go - Changed default column template from {{ .name }} to {{ .workflow }} to match the extractor's key
  2. pkg/list/column/column.go - Added explicit mapping for "workflow" key in buildTemplateContext() for consistency
  3. Tests - Added tests to verify default columns use the correct template keys

Testing

# Before fix
$ atmos list workflows
networking.yaml  <no value>  Run terraform plan...

# After fix  
$ atmos list workflows
networking.yaml  plan-all-vpc  Run terraform plan...

Summary by CodeRabbit

  • Bug Fixes

    • Fixed the Workflow column in workflow lists to display the correct data source.
  • New Features

    • Added support for configuring workflow columns and templates via atmos.yaml configuration file.

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

fix: Workflow command parsing for quoted arguments @aknysh (#1961)

what

  • Fixed workflow command parsing to correctly handle quoted arguments like -var="key=value"
  • Previously, strings.Fields() was used which doesn't handle shell quoting, causing quoted arguments to be passed with literal quote characters
  • Now uses shell.Fields() from mvdan.cc/sh/v3/shell which properly parses shell-style quoting

why

  • Workflow commands with -var="access_roles_enabled=false" were failing with:
    Error: Value for undeclared variable
    A variable named "\"access_roles_enabled" was assigned on the command line
    
  • The issue was that strings.Fields() splits on whitespace but preserves quote characters, so -var="enabled=false" was passed to Terraform with the literal quotes included
  • Running the same command directly from the CLI worked because the shell strips the quotes before passing to the process
  • shell.Fields() correctly parses shell quoting and strips quotes, matching the behavior users expect

Example

Before (broken):

# Workflow command
command: terraform deploy tfstate-backend -var="access_roles_enabled=false"

# Parsed as: ["terraform", "deploy", "tfstate-backend", "-var=\"access_roles_enabled=false\""]
# Terraform sees variable name as: "access_roles_enabled (with leading quote)

After (fixed):

# Same workflow command
command: terraform deploy tfstate-backend -var="access_roles_enabled=false"

# Parsed as: ["terraform", "deploy", "tfstate-backend", "-var=access_roles_enabled=false"]
# Terraform correctly sees variable name as: access_roles_enabled

Testing

Added comprehensive tests for the fix:

Unit Tests (internal/exec/workflow_test.go)

  • TestShellFieldsQuoteParsing - verifies shell.Fields() correctly parses various quoted argument patterns

Unit Tests (internal/exec/workflow_utils_test.go)

  • TestShellFieldsFallback - tests shell parsing with various argument patterns
  • TestExecuteWorkflow_WithQuotedVarFlag - tests -var="key=value" pattern in workflows
  • TestPrepareStepEnvironment_WithGlobalEnv - tests global env merging
  • TestExecuteWorkflow_* - multiple tests for stack overrides, dry run, from-step, identity precedence

Workflow Test Fixtures (tests/fixtures/scenarios/workflows/stacks/workflows/test.yaml)

  • terraform-var-double-quotes - -var="key=value" pattern
  • terraform-var-single-quotes - -var='key=value' pattern
  • terraform-var-multiple - multiple var flags
  • terraform-var-with-spaces - values containing spaces
  • terraform-var-equals-in-value - values containing =

references

  • Uses same approach as pkg/workflow/executor.go:332-337 which already had the correct implementation
  • mvdan.cc/sh/v3/shell is already a dependency used in other parts of the codebase

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Improved command argument parsing to correctly handle quoted strings and complex flags (e.g., Terraform -var with spaces and equals signs).
  • Tests

    • Expanded test coverage for quoted argument parsing and workflow execution scenarios.
    • Added test cases for various Terraform variable flag quoting patterns.
  • Dependencies

    • Updated Go module dependencies to latest patch versions.

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

fix: Fix Aqua registry factory and add darwin_all pattern support @osterman (#1948)

what

  • Fix nil registry factory by injecting real Aqua registry factory
  • Load configured registries from atmos.yaml in NewInstaller()
  • Add Asset field to AquaPackage for github_release types
  • Support platform-specific asset patterns (e.g., darwin_all)
  • Add test for replicated darwin_all override pattern
  • Move test fixtures to proper testdata directories
  • Refactor FindTool to reduce complexity and improve logging

why

The installer subpackage refactoring broke registry lookups because defaultRegistryFactory.NewAquaRegistry() was returning nil. Additionally, NewInstaller() wasn't loading configured registries from atmos.yaml, preventing custom registry support. This fix properly injects a working registry factory and loads configuration during initialization.

references

Fixes toolchain registry factory issues from the installer subpackage refactoring work.


🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Configurable toolchain registries with platform-specific overrides, OS/arch replacements, multi-file extraction and macOS .pkg handling
    • Enhanced CLI help and explicit telemetry notice across toolchain commands
  • Documentation

    • Added Aqua package manager README and expanded CLI docs with AWS CLI install example and templating/override guidance
  • Tests

    • Large expansion of fixtures, snapshots and unit/integration tests covering registries, install/info/download/extract flows, and overrides
  • Style

    • Minor workflow comment update (non-functional)

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

fix(provenance): add regression tests and fix flag inheritance @osterman (#1949)

what

  • Add comprehensive regression tests for line-level provenance tracking
  • Fix flag inheritance regression where custom commands could not define flags that already exist on parent commands
  • Custom commands can now declare --stack, --verbose, or other existing flags when the type matches
  • Type mismatches still produce clear error messages (e.g., defining --stack as bool when parent has it as string)

why

  • Provenance output format needs regression tests to prevent accidental breakage of import chains, depth tracking, and source attribution
  • PR #1947 introduced overly strict flag conflict checking that rejected valid use cases
  • Custom commands legitimately need to use flags like --stack and --verbose that are defined elsewhere
  • The fix allows flag inheritance when types match (skip re-registration) while still catching actual conflicts (type mismatch)

references

  • Fixes flag regression introduced in #1947
  • Adds test fixtures: tests/fixtures/scenarios/provenance-advanced/ and tests/fixtures/scenarios/flag-inheritance/
  • Test cases: tests/test-cases/provenance-snapshots.yaml and tests/test-cases/flag-inheritance.yaml

Summary by CodeRabbit

  • New Features

    • Custom commands now support flag inheritance with type-safety validation and conflict detection
    • Custom commands can define their own --version flags independent of the global version flag
    • Configuration provenance tracking now displays where each setting originates in the stack hierarchy
    • Enhanced atmos list components command shows unique components with stack counts
  • Configuration

    • Updated list command configuration structure in atmos.yaml under new list.components, list.instances, and list.stacks paths

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

fix: Resolve file-scoped locals in stack configurations @aknysh (#1939)

what

  • Fixed file-scoped locals feature that was documented but not functional (GitHub issue #1933)
  • Templates using {{ .locals.* }} now correctly resolve to their defined values
  • Added proper integration of locals extraction into the stack processing pipeline
  • Section-specific locals (terraform:, helmfile:, packer:) correctly override global locals
  • Component-level locals with inheritance support via metadata.inherits
  • Added atmos describe locals command to inspect and debug locals configurations
    • --stack flag is required - locals are file-scoped, so a specific stack must be specified
    • Component-level output: shows merged locals available to a specific component
    • Supports both logical stack names (e.g., prod-us-east-1) and file paths (e.g., deploy/prod)
    • Output follows Atmos schema format (direct stack manifest format, can be used as valid YAML)

Example Output

Stack Locals (by file path or logical name)

# Using file path
atmos describe locals --stack deploy/dev

# Using logical stack name (derived from atmos.yaml name_template)
atmos describe locals --stack dev-us-east-1
locals:
  environment: dev
  namespace: acme
  name_prefix: acme-dev
  full_name: acme-dev-us-east-1
  tags:
    Environment: dev
    Namespace: acme
terraform:
  locals:
    backend_bucket: acme-dev-tfstate
    tf_specific: terraform-only

The output is in direct stack manifest format - it can be redirected to a file and used as a valid stack manifest:

atmos describe locals -s dev --file locals.yaml

Component Locals

When a component is specified, the output shows the merged locals available to that component (global + section-specific + component-level + inherited from base components):

atmos describe locals vpc -s prod-us-east-1
components:
  terraform:
    vpc:
      locals:
        backend_bucket: acme-prod-tfstate
        environment: prod
        namespace: acme
        name_prefix: acme-prod
        vpc_type: production
        cidr_prefix: "10.0"

Query Specific Values

# Query the namespace from locals
atmos describe locals -s deploy/dev --query '.locals.namespace'
# Output: acme

# Output as JSON
atmos describe locals -s dev --format json

Component-Level Locals with Inheritance

Components can define their own locals: section that inherits from base components:

components:
  terraform:
    vpc/base:
      metadata:
        type: abstract
      locals:
        vpc_type: standard
        cidr_prefix: "10.0"

    vpc/prod:
      metadata:
        inherits:
          - vpc/base
      locals:
        vpc_type: production  # Overrides base
      vars:
        cidr: "{{ .locals.cidr_prefix }}.0.0/16"  # Uses inherited local

Locals resolution order: Global → Section → Base Component → Component

Manual Testing Results

Test Fixture: locals-logical-names

Stack-level locals (using logical stack name):

cd tests/fixtures/scenarios/locals-logical-names
atmos describe locals --stack dev-us-east-1
locals:
  env_prefix: acme-dev
  full_prefix: acme-dev-us-east-1
  namespace: acme
terraform:
  locals:
    backend_bucket: acme-dev-tfstate
    tf_only: terraform-specific-dev

Stack-level locals (using file path):

atmos describe locals --stack deploy/dev

Same output as above.

Stack-level locals (JSON format):

atmos describe locals -s dev-us-east-1 --format json
{
  "locals": {
    "env_prefix": "acme-dev",
    "full_prefix": "acme-dev-us-east-1",
    "namespace": "acme"
  },
  "terraform": {
    "locals": {
      "backend_bucket": "acme-dev-tfstate",
      "tf_only": "terraform-specific-dev"
    }
  }
}

Terraform component locals:

atmos describe locals vpc -s dev-us-east-1
components:
  terraform:
    vpc:
      locals:
        backend_bucket: acme-dev-tfstate
        env_prefix: acme-dev
        full_prefix: acme-dev-us-east-1
        namespace: acme
        tf_only: terraform-specific-dev

Helmfile component locals:

atmos describe locals nginx -s prod-us-west-2
components:
  helmfile:
    nginx:
      locals:
        env_prefix: acme-prod
        full_prefix: acme-prod-us-west-2
        hf_only: helmfile-specific-prod
        namespace: acme
        release_name: acme-prod-release

Test Fixture: locals-component-level

Standalone component with its own locals:

cd tests/fixtures/scenarios/locals-component-level
atmos describe locals standalone -s dev-us-east-1
components:
  terraform:
    standalone:
      locals:
        backend_bucket: acme-dev-tfstate
        computed_ref: acme-dev
        environment: dev
        name_prefix: acme-dev
        namespace: acme
        standalone_value: standalone-only
        tf_specific: terraform-only

Component inheriting from base with locals override (vpc/dev):

atmos describe locals vpc/dev -s dev-us-east-1
components:
  terraform:
    vpc/dev:
      locals:
        backend_bucket: acme-dev-tfstate
        cidr_prefix: "10.0"        # inherited from base
        environment: dev
        extra_tag: dev-only        # added in child
        name_prefix: acme-dev
        namespace: acme
        tf_specific: terraform-only
        vpc_type: development      # overridden from "standard"

Component inheriting from base without locals override (vpc/standard):

atmos describe locals vpc/standard -s dev-us-east-1
components:
  terraform:
    vpc/standard:
      locals:
        backend_bucket: acme-dev-tfstate
        cidr_prefix: "10.0"        # inherited from base
        environment: dev
        name_prefix: acme-dev
        namespace: acme
        tf_specific: terraform-only
        vpc_type: standard         # inherited from base

why

  • The file-scoped locals feature was announced in v1.203.0 but the implementation was incomplete
  • ProcessStackLocals() existed but was never called during stack processing
  • The .locals context was not provided to template execution, causing templates to remain unresolved
  • Users reported that {{ .locals.* }} templates showed raw template strings instead of resolved values

Technical Changes

  1. Added extractLocalsFromRawYAML() - Parses YAML and extracts/resolves locals before template processing
  2. Added extractAndAddLocalsToContext() - Helper to add resolved locals to template context
  3. Added LocalsContext.MergeForTemplateContext() - Merges all scope levels into flat map for templates
  4. Added section tracking flags - HasTerraformLocals, HasHelmfileLocals, HasPackerLocals to properly handle overrides
  5. Added atmos describe locals command - Command to inspect locals for a specific stack with schema-compliant output
  6. Added component-level locals extraction - ComponentLocals and BaseComponentLocals fields in stack processing
  7. Added component locals inheritance - Locals inherit from base components via metadata.inherits
  8. Direct output format - Output is in stack manifest format that can be used as valid YAML

Test Coverage

Category Count
Unit tests (stack_processor_utils_test.go) 16
Unit tests (stack_processor_locals_test.go) 41
Unit tests (describe_locals_test.go) 40+
Unit tests (cmd/describe_locals_test.go) 12
Integration tests (cli_locals_test.go) 26
Total 135+

Key test areas:

  • extractLocalsFromRawYAML - 95.8% coverage
  • ProcessStackLocals - 100% coverage
  • ExtractAndResolveLocals - 100% coverage
  • Deep import chain tests (4-level: base → layer1 → layer2 → final)
  • File-scoped behavior verification (locals NOT inherited across imports)
  • Component-level locals with inheritance
  • Logical stack name resolution
  • Direct output format validation

Test Fixtures

  • tests/fixtures/scenarios/locals-deep-import-chain/ - Tests file-scoped locals across deep import chains
  • tests/fixtures/scenarios/locals-logical-names/ - Tests logical stack name resolution
  • tests/fixtures/scenarios/locals-component-level/ - Tests component-level locals with inheritance

Documentation

  • CLI docs: website/docs/cli/commands/describe/describe-locals.mdx
  • Blog post: website/blog/2026-01-06-file-scoped-locals-fix.mdx
  • PRD: docs/prd/file-scoped-locals.md

references

Summary by CodeRabbit

  • New Features

    • Added a CLI command to describe merged locals per stack/component with format, file, and query options.
  • Bug Fixes

    • File-scoped locals are now resolved before template processing, don’t leak across imports, and are stripped from final outputs.
  • Documentation

    • New blog post and CLI docs explaining locals behavior, examples, and upgrade notes.
  • Tests

    • Extensive unit/integration tests and fixtures covering locals resolution, scopes, inheritance, circular deps, and deep-import chains.
  • UX

    • Improved CLI validation and clearer error messages (e.g., stack requirement).

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

fix(auth): normalize ATMOS_IDENTITY=false (issue #1931) @osterman (#1935)

what

  • Fix ATMOS_IDENTITY=false not being recognized in the legacy ProcessCommandLineArgs() code path
  • Create shared NormalizeIdentityValue() function in pkg/config/identity.go to centralize normalization logic
  • Add comprehensive tests for ATMOS_IDENTITY=false, 0, no, off in cli_utils_test.go
  • Refactor three duplicate normalizeIdentityValue() functions to use shared implementation

why

PR #1900 fixed ATMOS_IDENTITY=false normalization for the flag parsing path (pkg/flags/global_registry.go), but missed a separate code path in internal/exec/cli_utils.go that reads ATMOS_IDENTITY directly via os.Getenv().

Two independent code paths exist:

  1. Flag path (pkg/flags/global_registry.go): Used by Cobra commands with proper global flag inheritance - ✅ Fixed in PR #1900
  2. Legacy path (internal/exec/cli_utils.go:ProcessCommandLineArgs()): Used by terraform commands - ❌ Not fixed until this PR

The legacy path was added in PR #1720 (Oct 2025) without normalization. When PR #1900 fixed the flag path (Dec 2025), this code path was missed, causing the regression reported in issue #1931.

Verified with user's reproduction case:

# From issue #1931's auth_bug.tar.gz
ATMOS_IDENTITY=false atmos terraform plan myapp -s dev
# Before: "Error: identity not found" (treats "false" as identity name)
# After: Terraform plan runs successfully with auth disabled

Note: This class of problems (duplicate code paths for auth handling) should be eliminated by #1919, which refactors Atmos auth to use the command registry pattern. Once that lands, there will be a single, unified code path for identity/auth handling across all commands.

references

Closes #1931
Related: #1900 (partial fix), #1720 (introduced the unfixed code path), #1919 (architectural fix to prevent this class of bugs)

Summary by CodeRabbit

  • Refactor

    • Consolidated identity value normalization logic across the system. Identity values are now consistently processed to treat false-like representations (false, 0, no, off in various cases) uniformly, regardless of whether they originate from environment variables, configuration files, or command-line arguments.
  • Tests

    • Added test coverage for identity value normalization with comprehensive edge case handling.

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

Fix custom command flag conflicts with global flags @osterman (#1947)

what

  • Add validation to detect and prevent custom command flag conflicts with global persistent flags
  • Return actionable error messages instead of panicking when conflicts are detected
  • Query global flags dynamically to ensure new flags are automatically protected
  • Update existing tests to use non-conflicting flag names

why

When custom commands in atmos.yaml define flags that conflict with global flags, Cobra would panic with a stack overflow. This fix gracefully detects conflicts before flag registration and returns a clear error message using the ErrorBuilder pattern, giving users explicit guidance on how to resolve the issue.

references

No GitHub issues referenced. This is a critical bug fix improving stability and user experience when working with custom commands.

Summary by CodeRabbit

  • New Features

    • Runtime validation blocks custom commands from defining flag names or shorthands that conflict with global/parent reserved flags (including the identity flag); conflicts yield a clear reserved-flag error.
  • Changes

    • Added a public reserved-flag error sentinel.
    • Renamed debug flag from verbose to customDebug (shorthand d).
    • Example/fixture command renamed from terraform to tf-custom; CLI help listings updated accordingly.
  • Tests

    • Extensive unit and integration tests covering flag reservation, shorthands, nesting, inheritance, defaults, and error reporting.

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

fix: Resolve assume role issues and improve error handling @aknysh (#1938)

what

  • Fix panic when using !terraform.output with authentication enabled
  • Fix silent/confusing errors when referenced component is missing in template functions
  • Add comprehensive documentation for env template function behavior
  • Document base_path behavior change as a breaking change in changelog

why

Issue #1921: Panic in !terraform.output with Authentication

When using !terraform.output with AWS SSO authentication, Atmos panicked with:

panic: authContextWrapper.GetChain should not be called

Root Cause: The authContextWrapper.GetChain() method was implemented as a panic stub, but the auth system evolution now calls this method during nested component resolution.

Fix: Changed GetChain() to return an empty slice instead of panicking. An empty chain means no inherited identity from the wrapper, so nested components use their own defaults.

Issue #1030: Missing Component Results in Silent Failure

When using template functions like atmos.Component() or !terraform.output to reference components that are removed from configuration, Atmos produced confusing errors or silent failures.

Root Cause: The ErrInvalidComponent error chain was preserved when wrapping errors from DescribeComponent. This caused the component type fallback logic (detectComponentType()) to incorrectly trigger, producing misleading "component not found as Helmfile/Packer" errors instead of clear "referenced component missing" errors.

Fix: Added WrapComponentDescribeError() helper in errors/error_funcs.go that breaks the ErrInvalidComponent chain using %v instead of %w formatting, ensuring errors about referenced components are returned immediately with clear messages.

Env Template Function Analysis (Not a Bug)

Investigated user report that env template function returns empty strings while .vars.* works correctly. Analysis confirmed this is expected behavior:

  • The env function is from Sprig and calls os.Getenv()

  • When an env var is NOT set, it returns empty string (standard Go behavior)

  • .vars.* works because it comes from stack YAML config passed to template

  • User needs to ensure env vars are set before running atmos commands

  • Generated files (backend.tf.json) looking correct is from cached runs when vars WERE set

  • Closes #1909

Document base_path Behavior Change

A recent Atmos CLI change (v1.202.0) altered how base_path is interpreted in atmos.yaml. Previously, base_path: "" was implicitly treated as the current directory. Now it triggers git root discovery.

Impact: Users with multiple Atmos projects in a single repo, or where the Atmos project root differs from the git root, must update their configuration:

# Before (no longer works as expected)
base_path: ""

# After (explicit current directory)
base_path: "."

Fix: Added breaking change blog post to the changelog documenting:

  • The behavior change and affected versions
  • Who is affected (multi-project repos, non-git-root configs)
  • Migration steps with examples
  • Path resolution semantics table

references

closes #1030
closes #1921

Testing

  1. Unit tests: All new functionality covered with tests
  2. Error chain verification: Tests use assert.NotErrorIs() to verify chain is broken
  3. Regression test: TestAuthContextWrapper_GetChain_NoLongerPanics prevents future panics
  4. Env function tests: Document expected behavior when env vars are/aren't set

Summary by CodeRabbit

  • Bug Fixes

    • Prevented incorrect error propagation when describing missing components and eliminated panics during authenticated Terraform output handling, improving error stability and clarity.
  • Tests

    • Added regression tests for component error wrapping, auth-chain behavior, and template env-var rendering (populated and unset scenarios).
  • Documentation

    • Added a troubleshooting guide for Terraform output issues and a blog post explaining base_path behavior changes and migration guidance.
  • Diagnostics

    • Added debug logging for YAML/template function errors.

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

fix: Terraform state path for disabled workspaces @aknysh (#1929)

what

  • Fixed !terraform.state YAML function to use correct state file paths when Terraform workspaces are disabled (workspaces_enabled: false)
  • For S3 backend: state is now correctly read from <key> instead of <workspace_key_prefix>/default/<key>
  • For Local backend: state is now correctly read from terraform.tfstate instead of terraform.tfstate.d/default/terraform.tfstate
  • Added comprehensive unit tests for both S3 and local backend default workspace handling
  • Added integration tests with a new test fixture for workspaces-disabled scenario

why

  • When workspaces_enabled: false is set in atmos.yaml, Atmos sets the workspace to "default" but Terraform stores state at different paths for the default workspace vs named workspaces:
    • S3 backend: Default workspace stores state at <key>, not <workspace_key_prefix>/default/<key>
    • Local backend: Default workspace stores state at terraform.tfstate, not terraform.tfstate.d/default/terraform.tfstate
  • The !terraform.state YAML function was looking in the wrong locations, causing it to fail to find state files when workspaces are disabled
  • This aligns with Terraform's documented behavior for backend state storage

references

Summary by CodeRabbit

  • Bug Fixes

    • Fixed Terraform state lookup so default/disabled workspaces read state from the root terraform.tfstate location across backends (local, S3, Azure).
  • Tests

    • Added unit and end-to-end tests covering state reads and path resolution for default, empty, and named workspaces.
  • Documentation

    • Added fixtures and a blog post explaining behavior and upgrade notes when workspaces are disabled.

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

Don't miss a new atmos release

NewReleases is sending notifications on new releases.