github cloudposse/atmos v1.210.0

5 hours ago
docs: Clarify imports, inheritance, and variable merge order @osterman (#2146)

what

  • Added Blueprint Configuration design pattern documentation for reusable deployment templates that bundle components with sensible defaults
  • Added Variable Merge Order guide explaining how Atmos resolves variables through imports, inheritance, and overrides with clear examples of the scope-level priority system
  • Clarified that overrides are file-scoped (preventing cross-team leakage) vs regular vars which apply globally
  • Updated multi-cloud configuration examples with clearer directory hierarchies and inline comments explaining AWS/Azure/GCP organizational boundaries
  • Enhanced cross-references throughout docs to link related concepts together

why

  • Developers commonly struggle with variable resolution, especially understanding that scope level beats import order (component-level vars override global-level vars regardless of file)
  • The Blueprint Configuration pattern is increasingly common but lacked first-class documentation
  • Stack organization examples (AWS orgs, Azure subscriptions, GCP projects) were unclear about naming conventions and hierarchy reasoning
  • Variable merge semantics needed a dedicated guide to prevent configuration bugs in large multi-team deployments

references

Related to improving Atmos documentation clarity around stack configuration patterns and variable resolution.

Summary by CodeRabbit

  • Documentation

    • Added Blueprint Configuration guide and reorganized Imports, Templates, Overrides, and multi‑cloud pattern docs with clearer merge/order, scope, and inheritance guidance
    • Clarified import/override precedence and added troubleshooting tips and examples; improved migration docs with embedded examples
  • New Features

    • Introduced a native Terraform migration example with example stacks, components, and usage instructions
  • Other

    • Test snapshots updated and now include a telemetry notice; new example tests added
feat: Add structured component dependencies with cross-type and file monitoring @osterman (#2193)

what

  • Introduce a new dependencies.components format in stack configurations for declaring explicit component dependencies
  • Add ComponentDependency struct with component, stack, kind, and path fields
  • Support cross-type dependencies (terraform components can depend on helmfile, packer, or plugin components via the kind field)
  • Support file/folder dependencies for external config and source code monitoring (kind: file / kind: folder)
  • Enable Go template support for dynamic stack references in dependency declarations
  • Implement dependency inheritance with append merge behavior during stack inheritance
  • Update describe dependents and describe affected commands to resolve dependencies from the new format
  • Restructure documentation from single dependencies.mdx into dependencies/ directory with dedicated component dependencies page
  • Add blog post announcing the feature

why

  • The existing settings.depends_on format is limited: it uses a map with numeric keys, requires separate namespace/tenant/environment/stage fields instead of stack templates, and mixes file/folder tracking with component dependencies
  • Cross-type dependencies (e.g., terraform depending on helmfile) were not possible with the old format
  • File and folder dependency monitoring needed a cleaner syntax (kind: file + path vs legacy file field)
  • Stack templates ({{ .vars.tenant }}-{{ .vars.environment }}-prod) provide a more flexible and readable way to reference cross-stack dependencies
  • The new list-based format (dependencies.components: [...]) is more intuitive than the map-based settings.depends_on format
  • Legacy settings.depends_on continues to work for backward compatibility

references

  • PRD: docs/prd/component-dependencies.md
  • Blog post: website/blog/2026-01-02-dependencies-components.mdx
  • Documentation: /stacks/dependencies/components

Summary by CodeRabbit

  • New Features

    • Structured component dependencies: add a components list with component, stack, kind (component/file/folder), and path; supports cross-stack, cross-type, and file/folder triggers with append-merge semantics.
  • Documentation

    • Comprehensive docs, examples, migration guide, updated docs pages, and a blog post covering usage and behavior.
  • Tests

    • Extensive unit/integration tests and fixtures validating new format, inheritance, append-merge, and migration scenarios.
  • Deprecation

    • Legacy settings.depends_on marked deprecated with migration instructions.
Skip release documentation check on draft PRs @[copilot-swe-agent[bot]](https://github.com/apps/copilot-swe-agent) (#2186)

Draft PRs were failing the changelog/roadmap check and receiving bot comments even though they're explicitly WIP. The check should only enforce release documentation requirements on PRs that are ready for review.

Changes

  • changelog-check.yml
    • Add ready_for_review to trigger types so the check runs when a draft is converted to ready
    • Short-circuit check-labels with requires_docs=false when isDraft == true, suppressing all downstream steps (blog check, roadmap check, PR comment, and failure)
# Skip checks for draft PRs entirely
IS_DRAFT=$(gh pr view "$PR_NUMBER" --json isDraft --jq '.isDraft')
if [ "$IS_DRAFT" = "true" ]; then
  echo "requires_docs=false" >> $GITHUB_OUTPUT
  echo "✅ PR is a draft - release documentation check skipped"
  exit 0
fi

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

feat(templates): add global `ignore_missing_template_values` to `atmos.yaml` @nitrocode (#2158)

what

  • Add IgnoreMissingTemplateValues field to TemplatesSettings struct in pkg/schema/schema.go
  • Use global setting as fallback in ProcessYAMLConfigFiles (top-level file call) in stack_processor_utils.go
  • Use global setting as fallback when processing imports via importStruct.IgnoreMissingTemplateValues in stack_processor_utils.go
  • Use global setting in validate_stacks.go calls
  • Add test TestGlobalIgnoreMissingTemplateValues to verify the feature works
  • Update documentation in templates.mdx and imports.mdx
  • Add blog post announcement at website/blog/2026-03-09-global-ignore-missing-template-values.mdx
  • Update roadmap dx initiative with new shipped milestone
  • Fix macOS ARM64 test failures (gomonkey SIGBUS): DI refactor for processTerraformComponent, runtime skips for other gomonkey tests
  • Fix website build error: removed blank line inside <dd> tag in imports.mdx that caused MDX parsing to fail

usage

# atmos.yaml
templates:
  settings:
    ignore_missing_template_values: true  # applies to all imports globally
Original prompt

This section details on the original issue you should resolve

<issue_title>Global ignore_missing_template_values option for imported catalogs</issue_title>
<issue_description>### Describe the Feature

Upgrading from atmos 1.168.0 to latest version, the ignore_missing_template_values  (link) seems to be the method found. It would be nice to set this at a global level instead of on every imported catalog otherwise we have to update 100s of catalogs and references.

e.g. instead of this

import:
  - path: "<path_to_atmos_manifest2>"
    context: {}
    skip_templates_processing: false
    ignore_missing_template_values: true

maybe this in atmos.yaml or similar

settings:
  ignore_missing_template_values: true

Expected Behavior

See above

Use Case

See above

Describe Ideal Solution

See above

Alternatives Considered

No response

Additional Context

<agent_instructions>Think deeply. Use PR template. Use semantic commits. Use semantic PR title. Consider the problem and the proposal and see if it makes sense. It's possible that the global config be in a different yaml location. Please consider different options and select the optimum solution for developer/agent/user experience. Be surgical. </agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Add global --ai and --skill flags for AI-powered command analysis @aknysh (#2171)

what

  • Add global --ai flag that enables AI-powered analysis of output for any Atmos command
  • Add global --skill <name> flag that provides domain-specific context to the AI (requires --ai)
  • Add animated spinner with skill name visibility (👽 Analyzing with AI using skill 'atmos-terraform'...)
  • Show skill name in success message (✓ AI analysis complete (skill: atmos-terraform))
  • Support ATMOS_AI and ATMOS_SKILL environment variables for CI/CD
  • Update AI example with --ai and --skill flag usage and terminal output examples

why

  • Users need to interpret complex command output (Terraform plans, validation errors, stack descriptions) — adding --ai to any command provides instant AI analysis with zero workflow changes
  • The --skill flag gives the AI deep domain expertise (e.g., Terraform best practices) for more accurate and actionable analysis, with the skill's full system prompt sent to the AI provider
  • Showing the skill name in spinner and success messages gives users confidence about which skill was sent to the AI provider

See it in action

Plan analysis — AI summarizes Terraform plan changes:

$ atmos terraform plan vpc -s ue1-prod --ai

Plan: 1 to add, 0 to change, 0 to destroy.

✓ AI analysis complete

  ## Terraform Plan Summary:  vpc  in  ue1-prod

  ### Plan Succeeded — 1 Resource to Create

   Metric     │ Value
  ────────────┼───────
   To Add     │ 1
   To Change  │ 0
   To Destroy │ 0

  A  null_resource.vpc  will be created with CIDR  10.10.0.0/16 ,
  3 availability zones, and NAT Gateways enabled.

Error explanation — AI explains what went wrong and how to fix it:

$ atmos terraform plan vpc -s ue1-pro --ai

✓ AI analysis complete

  ## Component Not Found Error

   Atmos cannot locate the  vpc  component within the  ue1-pro  stack.

  ## Root Causes

    1. Wrong stack name —  ue1-pro  may not exist (try  ue1-prod )
    2. Missing import — The stack manifest doesn't import the vpc catalog entry
    3. Missing component definition — vpc  is not declared under  components.terraform

  ## Quick Fix

   Check                           │ Command
  ─────────────────────────────────┼────────────────────────────────────
   Stack name is correct           │  atmos list stacks
   Component is defined in stack   │  atmos list components -s ue1-pro
   No YAML syntax errors           │  atmos validate stacks

Domain expertise with --skill — AI uses Terraform knowledge for deeper analysis:

$ atmos terraform plan vpc -s ue1-network --ai --skill atmos-terraform

✓ AI analysis complete (skill: atmos-terraform)

  ## ✅ Plan Succeeded — 1 Resource to Create

   The  vpc  component in stack  ue1-network  planned successfully.

  ### 📋 What Will Be Created

   Resource            │ Type            │ Key Configuration
  ─────────────────────┼─────────────────┼─────────────────────────────────
    null_resource.vpc  │  null_resource  │ VPC CIDR  10.1.0.0/16 , 3 AZs, NAT enabled

  ### ⚠️ Warnings — Undeclared Variables

   Terraform found 3 variables in the generated  tfvars.json  that have no
   corresponding  variable  block. Fix options:

    1. Declare the variables in your module
    2. Remove unused vars from the stack config
    3. Suppress:  atmos terraform plan vpc -s ue1-network -- -compact-warnings

  ### 🚀 Next Steps

   atmos terraform apply vpc -s ue1-network --from-plan

Environment variables for CI/CD:

ATMOS_AI=true ATMOS_SKILL=atmos-terraform atmos terraform plan vpc -s ue1-prod

references

Summary by CodeRabbit

  • New Features

    • Global --ai flag to enable AI-powered post-command analysis and summaries
    • --skill flag to provide domain-specific analysis context (supports multiple skills; requires --ai)
    • ATMOS_AI and ATMOS_SKILL environment variables supported for persistent configuration
  • Documentation

    • Extensive docs, examples, and a blog post describing AI analysis usage, flags, and workflows
  • Tests

    • Added broad test coverage for AI flags, analysis, capture, and skill handling
chore: loosen issue templates and add AI prompt type @osterman (#2179)

what

  • Enable blank/freeform issues for users who want to submit without templates
  • Make bug report optional except for "Describe the Bug" field
  • Make feature request optional except for "Describe the Feature" field
  • Add new "AI Prompt (Feature Request)" template as first-class issue type for AI-powered feature requests
  • Remove legacy markdown issue templates (.md files) in favor of YAML versions

why

Users need flexibility to submit simple issues without required fields. The new AI Prompt template enables users to submit feature ideas as natural language prompts for AI assistants to help scope and implement, treating this as a first-class workflow rather than buried in feature requests.

references

User feature request to loosen requirements and support freeform issues with AI prompt submission.

Summary by CodeRabbit

  • New Features

    • Added a new issue template for submitting AI-generated feature requests
    • Enabled creation of blank issues without a template
    • Added new "ai-prompt" label for categorizing AI-prompted features
  • Chores

    • Updated issue templates to make select fields optional in bug reports and feature requests
Add AI-assisted section to homepage @osterman (#2166)

what

  • Added a new AI-assisted section on the Atmos homepage positioned between the hero and "See Atmos in Action" demo
  • Implemented a visually striking AI badge with animated Atmos Pro gradient text ("AI" / "Assisted" in a rounded rectangle with violet glow)
  • Added three capability cards: Interactive AI Chat, Skills Marketplace (21+ skills), and MCP Server integration
  • All content links to the /ai documentation page (both the badge and "Explore Atmos AI" CTA)
  • Animations fade in on scroll and fade out when scrolling back up (no once: true constraint)

why

  • Highlights Atmos AI as a shipped feature (Q1 2026) directly on the homepage for better discoverability
  • Uses the Atmos Pro color theme (animated gradient) to maintain visual consistency with the brand
  • Positioned below the hero fold to maintain the intentional above/below-fold reveal effect already established on the page
  • Encourages users to explore AI capabilities with clear CTAs

references

  • Repurposed visual design from Cloud Posse www project's bento-box AI component
  • Uses existing Atmos design patterns: Framer Motion animations, plain CSS styling, dark/light mode support

Summary by CodeRabbit

  • New Features
    • Added an AI section to the landing page with animated capability cards, an interactive AI badge, call-to-action, theme-aware styling, and responsive layout.
  • Documentation
    • Streamlined the AI example README into a concise task-focused guide and clarified AI docs messaging about supported providers and credential handling.
  • Style
    • Adjusted hero-demo vertical spacing and applied transparent backgrounds for Bash/SH code blocks in the terminal component.

🚀 Enhancements

fix: prevent stack overflow when abstract components have metadata.component @aknysh (#2214)

what

  • Fix fatal error: stack overflow crash when abstract components define metadata.component pointing to the same Terraform component directory as a real component that inherits from them
  • Add visited-set cycle detection to processBaseComponentConfigInternal to detect and report circular component references as clear errors instead of Go runtime crashes
  • Skip component chain resolution for abstract components whose promoted top-level component key creates circular references during Phase 2 metadata inheritance processing
  • metadata.component values on abstract components are still properly inherited by real components through metadata inheritance — only the recursive chain traversal is skipped

why

  • Users reported that atmos describe stacks -s <stack> crashes with fatal error: stack overflow on Atmos versions above v1.200.0 when abstract components have metadata.component set
  • The crash is caused by an interaction between two processing phases: Phase 1 promotes metadata.component to a top-level component key via mergeComponentConfigurations, and Phase 2 (metadata inheritance from PR #1812) re-processes this enriched data with a different cache key, causing fresh recursion that creates a circular reference between the abstract and real components
  • The simple component == baseComponent guard at the function entry is insufficient because the cycle involves multiple component name pairs alternating through two recursive call sites (component chain and inherits chain)
  • Abstract components can't be deployed, so following their promoted component key for chain resolution is functionally a no-op — but their metadata.component value should still be inherited by child components (which it is, via the metadata merge at the end of the function)

references

  • Fix doc: docs/fixes/2026-03-16-metadata-component-abstract-stack-overflow.md
  • Root cause: metadata inheritance feature (PR #1812, v1.201.0+) added Phase 2 ProcessBaseComponentConfig call in describe_stacks.go that operates on processed maps with promoted component keys
  • New sentinel error: ErrCircularComponentInheritance in errors/errors.go

Tests added (10 test cases across 5 test functions)

  • TestProcessBaseComponentConfig_CycleDetection (4 cases): direct cycle, cycle via inherits, 3-node cycle (A→B→C→A), valid chain (no false positive)
  • TestProcessBaseComponentConfig_AbstractComponentSkip: reproduces the exact user-reported pattern with abstract + real components sharing the same metadata.component
  • TestProcessBaseComponentConfig_DeepChainNoFalsePositive: 3-level inheritance chain works without false cycle detection
  • TestProcessBaseComponentConfig_AbstractMetadataComponentInherited: verifies metadata.component on abstract base is properly inherited by real components through metadata inheritance
  • TestProcessBaseComponentConfig_AbstractMetadataComponentNotInherited_WhenDisabled: confirms metadata.component is NOT inherited when metadata inheritance is disabled

Summary by CodeRabbit

  • Bug Fixes

    • Detects and stops circular component inheritance, surfacing a clear circular-inheritance error.
    • Skips resolving inherited metadata for abstract components to avoid false-positive cycles and infinite recursion.
  • Documentation

    • Added a detailed article on the circular-inheritance scenario, root cause, fixes, workarounds, and compatibility notes.
    • Updated auth-context appendix link.
  • Tests

    • Added extensive tests for cycle detection, abstract-component behavior, metadata inheritance, and deep/diamond inheritance chains.
feat: Native CI/CD integration for Terraform plan/apply/deploy lifecycle @goruha (#2079)

Summary

Adds first-class CI/CD support directly into the Atmos CLI. Running atmos terraform plan vpc -s prod in GitHub Actions now automatically produces rich job summaries, commit status checks, output variables, and stored planfile verification — no external actions required. The same command works identically locally and in CI.

What's Included

CI Framework (pkg/ci/)

  • Provider registry with auto-detection of CI environment (GitHub Actions, generic CI)
  • Plugin architecture for command-specific CI behaviors (Terraform plugin)
  • Lifecycle hooks: before.terraform.{plan,apply,deploy} / after.terraform.{plan,apply,deploy}
  • Configuration via ci: section in atmos.yaml with per-feature toggles

GitHub Provider (pkg/ci/providers/github/)

  • Job summaries written to $GITHUB_STEP_SUMMARY with resource badges, collapsible diffs, and destruction warnings
  • Commit status checks via Status API — shows "Plan in progress" while running, "3 to add, 1 to change, 0 to destroy" on completion
  • Per-operation statuses (add/change/destroy) created only when resource counts > 0
  • Output variables exported to $GITHUB_OUTPUT (has_changes, has_additions, has_destructions, plan_summary, output_*)

Generic Provider (pkg/ci/providers/generic/)

  • Prints summaries, checks, and outputs to stdout — useful for local development and any CI without native integration

Planfile Storage (pkg/ci/artifact/, pkg/ci/plugins/terraform/planfile/)

  • Multi-backend artifact storage: GitHub Artifacts, S3, local filesystem
  • Bundled tar format with plan + lock file + metadata
  • CLI commands: atmos terraform planfile {upload,download,list,show,delete}
  • Component/stack addressing: atmos terraform planfile list vpc -s dev
  • Automatic upload after plan, automatic download before deploy

Terraform CI Plugin (pkg/ci/plugins/terraform/)

  • Output parsing: resource counts, warnings, errors, changed resource lists
  • Markdown summary templates for plan and apply results (customizable via Go templates)
  • Terraform output export as CI variables after successful apply

Plan Verification (internal/exec/terraform_verify_plan.go)

  • deploy command downloads stored planfile, generates fresh plan, compares semantically
  • Fails with drift error if plans don't match; applies verified plan if they match
  • Prevents applying stale plans in CI pipelines

Documentation (website/docs/ci/)

  • Native CI overview, job summaries, planfile storage feature docs
  • CLI command reference for all planfile subcommands
  • CI configuration reference (website/docs/cli/configuration/ci/)

Configuration

ci:
  enabled: true
  summary:
    enabled: true
  output:
    enabled: true
  checks:
    enabled: true
    context_prefix: "atmos"

Test plan

  • Unit tests for CI providers, plugins, artifact storage, output parsing
  • Golden snapshot tests for summary templates
  • Integration test: atmos terraform plan vpc -s dev --ci produces summary and outputs
  • Planfile upload/download/list/show/delete CLI commands
  • Plan verification: stored vs fresh plan comparison
  • Status checks created and updated with correct URLs
  • Website builds with no broken links

References

  • PRDs: docs/prd/native-ci/
Suggest profiles when no auth config; clean up legacy keyring entries @osterman (#2154)

what

  • Fix: Propagate auth realm through CopyGlobalAuthConfig and buildGlobalAuthSection so that ExecuteTerraform (both single-component and --all paths) uses the correct realm for credential storage. This is the root cause fix for #2187.
    • CopyGlobalAuthConfig in pkg/auth/config_helpers.go was missing Realm and RealmSource fields — when --all iterates components, each call to CopyGlobalAuthConfig produced an auth config with an empty realm
    • buildGlobalAuthSection in internal/exec/utils_auth.go was not including realm in the auth map — the deep-merge path lost the realm value
  • When running atmos auth list with no providers/identities configured, Atmos now checks if profiles exist and suggests using the --profile flag to load auth configuration from profile-specific atmos.yaml files
  • After successfully caching credentials under the current realm, legacy (pre-realm) keyring entries are automatically cleaned up to prevent realm mismatch warnings
  • Uses the error builder pattern with ErrAuthNotConfigured sentinel error for rich, helpful error messages
  • Improved error message when identity kind is empty (not configured in active profile)

why

When running atmos terraform plan -s <stack> --all, credentials were stored without the auth realm in the path, causing realm mismatch warnings. Single-component runs (atmos terraform plan <component> -s <stack>) worked correctly because they used a different code path that preserved the realm. The two-line root cause fix ensures realm propagation through both paths.

Users working with profile-based configurations (like infra-live) need better guidance when auth config is not in the base atmos.yaml. Suggesting available profiles reduces friction and helps users discover the correct workflow.

The keyring cleanup prevents accumulated migration warnings when users upgrade to realm-aware credential management and transition between different credential storage locations.

testing

  • Unit tests verify Realm/RealmSource are copied in CopyGlobalAuthConfig (including deep-copy mutation safety)
  • Unit tests verify realm is included/excluded in buildGlobalAuthSection based on whether it's set
  • Integration tests verify realm propagation through getMergedAuthConfigWithFetcher (the --all code path)
  • Tests confirm no-realm configurations continue to work correctly (backward compatibility)
  • Tests for profile suggestion, legacy credential cleanup, and empty identity kind error messages
  • Updated golden snapshots reflecting realm now appearing in describe component output

references

  • Addresses the use case where auth providers/identities live in configuration profiles rather than the base atmos.yaml
  • Closes #2187

Summary by CodeRabbit

  • New Features

    • Auth list now suggests available profiles and shows a --profile usage hint when no auth providers or identities are configured.
  • Improvements

    • Automatic cleanup of legacy credential files and keyring entries after successful authentication to prevent realm-mismatch warnings.
    • Auth configuration now preserves and exposes a realm value where applicable; CLI describe output snapshots updated.
  • Bug Fixes

    • Clearer, actionable error when an identity is missing its kind, including guidance to list/select profiles.
  • Tests

    • Expanded tests for profile suggestions, realm propagation, merging, and legacy cleanup edge cases.
fix: resolve stack context for `locals` enabling `!terraform.state` and other YAML functions @aknysh (#2207)

what

  • Bug fix: !terraform.state (2-arg form) in locals now correctly derives the stack name from the file path, fixing the "stack is required" error reported in #2080
  • New unit tests: 7 new unit tests in stack_processor_utils_test.go covering computeStackFileName, deriveStackNameForLocals, !env + Go template conditionals, and !terraform.state mock-based tests (2-arg and 3-arg forms)
  • New integration tests: 3 new CLI integration tests in cli_locals_test.go for Go template conditionals with !env (set/empty) and the worker component example
  • New test fixture: tests/fixtures/scenarios/locals-conditional/ with isolated stack files and unique env var names to avoid stack cache interference
  • Updated example: examples/locals/ updated to showcase all locals features concisely — basic locals, dependency resolution, settings/vars access, Sprig pipe functions, complex maps, and multiple components (myapp + myapp-worker)
  • Updated docs: website/docs/stacks/locals.mdx rewritten with processing pipeline details, cross-component references (!terraform.state 2-arg and 3-arg forms), environment variable conditionals (!env + Go template if), Gomplate/Atmos template function support, and updated best practices
  • Fix documentation: comprehensive fix doc at docs/fixes/2026-03-15-locals-terraform-state-missing-stack-context.md with root cause analysis, architecture details, and test results

why

  • Root cause: extractLocalsFromRawYAML() in stack_processor_utils.go passed "" as currentStack to ProcessStackLocals. The 2-arg form of !terraform.state (e.g., !terraform.state vpc .vpc_id) uses currentStack as the stack name, so it failed with "stack is required" when used inside locals
  • Fix: Added deriveStackNameForLocals() and computeStackFileName() functions that derive the stack name from the file path using the same logic as describe locals, making the 2-arg form work correctly in locals
  • The example and documentation were outdated and didn't cover the full feature set of locals (YAML functions, conditionals, cross-component references)

references

Summary by CodeRabbit

  • Bug Fixes

    • Fixed 2-argument !terraform.state in file-scoped locals so stack-aware lookups resolve correctly.
  • Documentation

    • Major locals doc overhaul: processing pipeline, YAML functions, dependency ordering, and clearer examples for conditionals.
  • New Features / Examples

    • Expanded examples: worker component, new vars/outputs, Sprig and Gomplate usage, and environment-driven conditional flows.
  • Tests

    • Added fixtures and extensive unit/integration tests covering locals, stack derivation, and template conditionals.
  • Chores

    • Bumped many dependencies, updated license references, and updated example tooling version.
fix: allow custom commands to merge into built-in namespaces at any level @osterman (#2191)

what

  • Custom commands in atmos.yaml can now be merged into built-in command namespaces at any nesting depth
  • Built-in commands are preserved when custom commands collide (no silent replacement)
  • When a custom command with steps conflicts with an existing command, a warning is emitted explaining which steps are ignored
  • Added comprehensive tests verifying namespace merging, collision handling, and deep nesting

why

Custom commands silently failed when sharing a namespace with built-in commands. For example, users couldn't define mcp aws install because the built-in mcp command existed. The root causes were:

  1. Top-level collision detection only: The old code only checked for collisions at the top level (topLevel=true branch) using a separate getTopLevelCommands() map
  2. No non-top-level detection: When recursing into nested subcommands, there was no collision check at all, allowing Cobra's AddCommand to silently replace existing subcommands

This fix generalizes collision detection to all nesting depths by using a universal findSubcommand(parent, name) check that works on any cobra command's children.

how

  • Removed the topLevel bool parameter from processCustomCommands()
  • Replaced top-level-only collision detection with findSubcommand() that checks the parent command's subcommands at any level
  • Extracted command creation logic into createCustomCommand() helper to reduce nesting complexity (fixes golangci-lint nestif warning)
  • When a collision is detected, the existing command is reused and nested custom subcommands are merged into it
  • All call sites and tests updated to use the new signature

Summary by CodeRabbit

  • Bug Fixes

    • Custom commands that collide with built-in commands are now merged into existing namespaces; when collisions occur, custom execution steps are skipped and a user-facing warning is shown.
    • Flag and shorthand conflicts are validated earlier to prevent registration issues and clearer UI feedback.
  • Tests

    • Added tests covering collision handling, namespace merging, and deep-nesting preservation of built-in handlers.
fix: Add Azure sovereign cloud support (GCC High, China) @aknysh (#2192)

what

  • Add cloud_environment setting to all Azure auth providers (azure/device-code, azure/oidc, azure/cli) for sovereign cloud support
  • Create centralized CloudEnvironment registry (pkg/auth/cloud/azure/cloud_environments.go) with endpoint definitions for Azure Commercial, US Government (GCC High), and China (Mooncake)
  • Replace 12 hardcoded Azure endpoints across 6 subsystems with cloud-environment-aware lookups
  • Fix !terraform.state YAML function for GCC High by reading the Terraform azurerm backend environment field to resolve the correct blob storage URL suffix
  • Add comprehensive tests for sovereign cloud support (100% coverage on new code)
  • Update documentation: providers reference, Azure authentication tutorial, and stacks auth page

why

  • Azure Government (GCC High) users reported that !terraform.state fails because Atmos hardcodes blob.core.windows.net as the blob storage suffix, which doesn't resolve in sovereign clouds (should be blob.core.usgovcloudapi.net)
  • Authentication providers hardcode login.microsoftonline.com and public cloud API scopes, preventing sovereign cloud users from authenticating
  • The fix centralizes all cloud-specific endpoints in a single registry, making it easy to support additional clouds in the future
  • Backward compatible: cloud_environment defaults to public, so existing Azure Commercial users are unaffected

references

Summary by CodeRabbit

  • New Features

    • Added cloud_environment option to select Azure clouds (public, usgovernment, china); auth flows, CLI/profile handling, token scopes, MSAL cache, console URLs, and backend storage endpoints adapt to the chosen cloud. Default remains public.
  • Documentation

    • Expanded docs with sovereign-cloud guidance, examples, Terraform backend alignment, per-cloud scopes, and portal/URL notes.
  • Tests

    • Added comprehensive sovereign-cloud tests for auth flows, token/cache behavior, portal URLs, and backend handling.
fix: toolchain path resolution, constraint solving, and uninstall improvements @osterman (#2172)

Summary

Comprehensive improvements to the toolchain subsystem covering binary path resolution, semver constraint resolution, and uninstall reliability.

Toolchain binary path resolution

  • Resolve toolchain executables to absolute paths before execution (fixes exec.LookPath failures)
  • Centralize PATH construction via ToolchainEnvironment to eliminate scattered resolution logic
  • Fix cross-platform path handling for Windows CI

Semver constraint resolution

  • Resolve semver constraints (e.g., ^1.10.0) to concrete versions before tool install
  • Cache-first resolution: skip network call when an installed version already satisfies the constraint
  • Show resolved version on cache hit (e.g., "Using opentofu 1.11.5 (satisfies ^1.10.0)")
  • Add spinner during network-based constraint resolution
  • Add retry with exponential backoff (3 attempts) for transient network errors (stream cancel, connection reset, timeouts)
    • Hybrid error detection: gates on registry.ErrHTTPRequest sentinel, then string-matches for transient patterns

Uninstall improvements

  • Fix blank tool names in uninstall output caused by glamour linkify interpreting @ as email autolinks — backtick-wrap tool specs
  • Add --all flag to atmos toolchain uninstall to remove tools installed via component dependencies.tools (not just .tool-versions)
  • ListAllInstalledTools() scans install directory two levels deep to discover all installed tools

Testing

  • Add CI test cases for examples/toolchain (describe component, show dependencies, command detection)
  • Add glamour regression tests at both goldmark and formatter levels
  • Make TestForWorkflow_WithToolVersions deterministic with mockgen
  • Fix cross-platform test assertions

Test plan

  • go build ./... compiles cleanly
  • go test ./pkg/dependencies/... -count=1 passes
  • go test ./pkg/toolchain/... -count=1 passes
  • go test ./pkg/ui/... -count=1 passes
  • Pre-commit hooks pass (golangci-lint, go-fumpt, go mod tidy)
  • Manual: atmos toolchain uninstall --all removes dependency-installed tools
  • Manual: constraint resolution retries on transient network failure
fix: disable YAML function processing in list instances @milldr (#2170)

What

Disable YAML function processing (processYamlFunctions) in atmos list instances while keeping template processing enabled.

Why

atmos list instances calls ExecuteDescribeStacks with processYamlFunctions: true, which triggers execution of YAML functions like !terraform.output and atmos.Component(). These shell out to tofu/terraform, causing failures when those binaries aren't in $PATH — even though listing instances doesn't need to resolve function values.

Template processing is kept enabled because templates can create additional stacks and components that should be included as instances.

Ref

  • Reported in Slack: atmos list instances fails with exec: "tofu": executable file not found in $PATH
  • The tree-format code path in the same file already correctly disables both flags

Summary by CodeRabbit

  • Changes

    • YAML functions in template processing have been disabled while maintaining support for core template operations and stack handling.
    • Updated how stacks are processed and described to reflect this change.
  • Tests

    • Updated multiple test cases to reflect the modified template processing behavior and stack validation logic.

Don't miss a new atmos release

NewReleases is sending notifications on new releases.