github cloudposse/atmos v1.210.0-rc.1

pre-releaseone hour ago

🚀 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/

🤖 Generated with Claude Code

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.

Don't miss a new atmos release

NewReleases is sending notifications on new releases.