github cloudposse/atmos v1.221.0-rc.7

pre-release13 hours ago
feat: describe affected evaluates all provisioned component sections @osterman (#2573) ## what
  • Fix atmos describe affected so it detects changes in every provisioned component section, not just vars/env/settings/metadata/source/provision.
  • Newly evaluated sections: providers, required_providers (provider versions), required_version, hooks, generate, backend, backend_type, remote_state_backend, remote_state_backend_type, auth, command, and dependencies — including scalar sections (previously only map sections were compared).
  • Add a configurable describe.affected.sections setting in atmos.yaml that fully replaces the evaluated set (e.g. to track a custom section or narrow the list); metadata/settings are always evaluated.
  • Refactor the three component processors to a single table-driven comparison, add a documented "Evaluated sections" list, tests, a changelog blog post, and a roadmap milestone.

why

  • The comparison ran against a hand-maintained allow-list that had drifted out of sync with what Atmos actually merges into a component, so changes to providers, hooks, provider versions, backend, etc. were silently missed — a false negative that could let CI pipelines skip components that genuinely changed.
  • The table is now tied (via comments) to the sections written in stack_processor_merge.go, and the new config setting gives users an escape hatch so the bug class can't quietly return.
  • locals, overrides, inheritance, and retry are intentionally excluded (they either fold into other sections or are execution-time only).

references

Summary by CodeRabbit

  • New Features

    • Describe now evaluates and reports changes across a comprehensive set of top-level component sections (including scalar sections) with per-section reasons; first changed section becomes the headline reason.
    • Added configurable describe.affected.sections to fully replace the default evaluated set (metadata/settings remain always evaluated).
  • Documentation

    • Blog and CLI/config docs updated with evaluated-sections details, output reason entries, and configuration examples.
  • Tests

    • Added tests for section evaluation, equality behavior, remote-locator logic, and override/no-false-positive cases.
  • Chores

    • Updated snapshots, roadmap, CI workflow pins, link-checker exclusions, and changelog guidance.
feat(hooks): terraform init lifecycle hooks + --skip-hooks before-* fix @osterman (#2574) ## what
  • Fix --skip-hooks for before- hooks.* Previously it only skipped after-* hooks; before-terraform-plan/apply/deploy hooks ran regardless. Now --skip-hooks (skip all) and --skip-hooks=name1,name2 (skip by name) are honored symmetrically for before and after events.
  • Add before-terraform-init and after-terraform-init lifecycle hooks for the atmos terraform init command. after-terraform-init is new; before-terraform-init was documented but never dispatched to user hooks — now it fires. They run through the same runHooks/RunAll path, so the skip fix applies to them too.
  • Add tests (real parsed Cobra flag, not viper.Set), strengthen hook-inheritance coverage with a fixture proving top-level terraform.hooks: is inherited by every component (and components.terraform.hooks: is not), update the Hooks docs, blog post, and roadmap.

why

  • --skip-hooks is a global flag bound to Viper inside RunE, but before-* hooks run earlier in PreRunE — so viper.GetString("skip-hooks") never saw the CLI value and before-hooks fired anyway. The flag is now resolved directly from the parsed command (Viper/ATMOS_SKIP_HOOKS fallback), mirroring how --ci and --verbose are read in PreRunE.
  • Init had no user-hook surface at all: init.go wired no hooks and the BeforeTerraformInit event was never dispatched. Wiring PreRunE/PostRunE on the init command (like plan/apply/deploy) closes the lifecycle gap so teams can validate tooling, vendor sources, or notify systems around terraform init declaratively.
  • The previous skip tests injected via viper.Set with a nil command, sidestepping the exact flag-binding lifecycle that was broken — which is how the bug shipped; the new tests fail against the old implementation.

references

  • Hooks documentation: /stacks/hooks
  • Note: before-/after-terraform-init fire on the explicit atmos terraform init, not the implicit init that plan/apply run.

Summary by CodeRabbit

  • New Features
    • Added Terraform init lifecycle event: after-terraform-init (alongside before-terraform-init); Terraform-scoped default hooks can be inherited by Terraform components.
  • Bug Fixes
    • Fixed --skip-hooks precedence so CLI flag reliably overrides env/config and consistently skips before/after hook phases.
    • Clarified hook scope handling so misplaced hook keys aren’t incorrectly applied.
  • Documentation
    • Blog, docs, and roadmap updated to describe init hook events and skip-hooks behavior.
  • Tests
    • Expanded coverage for hook inheritance, scope, init wiring, event filtering, and skip-hooks CLI behavior.
  • Chores
    • CI Codecov step made non-fatal for transient upload errors.
feat(auth): share single OIDC session across aws/iam-identity-center providers @Benbentwo (#2553) ## what
  • Refactors the aws/iam-identity-center (AWS SSO) provider so that multiple providers pointing at the same SSO portal (identical start_url + region) share a single OIDC token — one browser flow now unlocks every provider instead of one flow per provider.
  • Adds silent refresh-token renewal via ssooidc:CreateToken with grant_type=refresh_token, so a single browser interaction holds for the full portal session (~8h) rather than re-prompting every hour.
  • Introduces an in-process sessionTokenStore (keyed by sha1(start_url|region)) with per-session mutexes that single-flight concurrent device-auth flows; re-keys the on-disk cache from aws-sso/<provider>/token.json to aws-sso/sessions/<sha1>.json in the AWS SDK ssocreds-compatible format.
  • Adds the design PRD (docs/prd/aws-sso-session-support.md), a changelog blog post, and a shipped roadmap milestone under the Unified Authentication initiative.

why

  • A common setup has one provider per environment (dev/staging/prod) all backed by the same corporate SSO portal; previously atmos auth login launched the browser flow once per provider, contradicting AWS's own "credentials have been shared successfully" single-sign-in experience.
  • The legacy flow re-ran the full browser interaction on every ~1h access-token expiry and keyed its cache by provider name, so renaming a provider silently invalidated a still-valid token — both are eliminated here with zero atmos.yaml config changes.

references

Summary by CodeRabbit

  • New Features

    • Shared AWS SSO sessions across providers for the same portal (start URL + region), reducing duplicate logins and browser prompts.
    • Silent refresh via refresh tokens to renew credentials without a browser; per-session locking prevents concurrent device-auth flows.
    • Session-keyed on-disk cache (compatible with AWS SDK patterns); logout clears shared session data; added session telemetry.
  • Documentation

    • Product spec and blog post describing session sharing, cache format, refresh behavior, and rollout plan.
  • Tests

    • Added/updated tests validating session sharing, cache semantics, isolation, refresh logic, and concurrency.
feat: implement !append YAML function for list concatenation @osterman (#1513) ## what - Implements the `!append` YAML function that allows fine-grained control over list merging behavior in Atmos stack configurations - Lists tagged with `!append` will be concatenated with base values instead of replaced - Adds comprehensive unit tests and integration test fixtures

why

  • Resolves the ongoing challenge of needing to concatenate lists on a case-by-case basis
  • Currently, users have to fall back to using maps instead of lists when they need append behavior
  • This is particularly important for fields like depends_on where appending is often the desired behavior rather than replacement
  • The !append tag provides opt-in, per-field control that works alongside the global list_merge_strategy setting

Key Features

  • Opt-in behavior: Only lists explicitly tagged with !append use append mode
  • Works alongside global settings: The !append tag works independently of the global list_merge_strategy setting
  • Nested support: Works with deeply nested configurations
  • Backward compatible: No impact on existing configurations without the tag

Example Usage

# base.yaml
components:
  terraform:
    eks:
      settings:
        depends_on:
          - vpc
          - iam-role

# override.yaml
components:
  terraform:
    eks:
      settings:
        depends_on: !append  # This tag indicates append mode
          - rds
          - elasticache
          
# Result: depends_on = [vpc, iam-role, rds, elasticache]

Testing

  • ✅ All unit tests pass
  • ✅ Build succeeds without errors
  • ✅ Linting passes with no issues
  • ✅ Code follows Atmos conventions and patterns

references

  • Linear issue: DEV-2980
  • Documentation: !append YAML function
  • Changelog: blog post append-yaml-function; roadmap milestone updated (Extensibility initiative)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a !append YAML function to append items to lists during configuration merging (per-field, preserves order, supports nested lists/maps, interacts with global list-merge strategies).
  • Tests
    • Added comprehensive unit and integration tests covering append-tag helpers, parsing, merging, and end-to-end scenarios.
  • Documentation
    • Added docs, examples, blog post, and index updates explaining !append usage and behavior.
  • Chores
    • Updated website roadmap/metadata and package config; added a sentinel error alias.

🚀 Enhancements

fix(stacks): honor component list_merge_strategy in metadata.inherits… @JaseKoonce (#2565)

what

  • settings.list_merge_strategy set on a component now applies when merging lists via metadata.inherits

  • Adds tests covering append, replace, and merge strategies across single and multi-level inheritance
    chains

why

  • Component-level list_merge_strategy was only honored on the import/stack merge path (fixed in #2480).
    The metadata.inherits resolution path always used the global atmosConfig, so per-component overrides were
    silently ignored

  • A component with list_merge_strategy: append inheriting two bases would get last-wins ([from_b]) instead
    of the expected accumulated result ([from_a, from_b])

references

Summary by CodeRabbit

  • Improvements

    • Component inheritance now applies per-component list merge strategies during metadata-based inheritance so inherited lists are accumulated, replaced, or merged by index according to the inheriting component’s settings across multi-level chains.
  • Tests

    • Added integration tests and fixture scenarios validating append, replace, multi-level append, and merge-by-index behaviors for metadata inheritance.

Don't miss a new atmos release

NewReleases is sending notifications on new releases.