feat: add support for PR artifacts in --use-version flag @osterman (#2040)
what
- Extend
--use-versionflag to support PR numbers using thepr:NNNNformat (e.g.,--use-version pr:2038) or auto-detected all-digit format (--use-version 2038) - Enable users to test Atmos features from PRs by automatically downloading and installing build artifacts from successful CI runs
- Add smart GitHub token detection with multiple fallback strategies (ATMOS_GITHUB_TOKEN, GITHUB_TOKEN, gh CLI)
- Implement TTL caching (1 minute) to minimize GitHub API calls when repeatedly using PR versions
- Add semver validation for
--use-versionflag to provide clear error messages for invalid inputs - Provide clear, actionable error messages for common failure scenarios (missing token, failed CI, unsupported platforms, invalid version format)
why
- Testing PR features currently requires installing Go, running
go install(which has proxy issues), or manually downloading artifacts from GitHub Actions UI - This friction prevents contributors and users from easily validating changes before merge
- Enabling PR artifact installation via
--use-versionmakes testing as simple asatmos --use-version 2038 terraform plan - Supports the same workflow users already know with version management, but extended to PRs
- Semver validation prevents confusing silent failures when users typo version strings
Usage
# Explicit PR prefix
atmos --use-version pr:2040 version
# Auto-detected PR (all digits)
atmos --use-version 2040 version
# Valid semver
atmos --use-version 1.175.0 version
# Invalid format - now errors with helpful message
atmos --use-version abc version
# ✗ Error: invalid version format 'abc'
# 💡 Version must be a PR number, pr:NNNN, or semver (e.g., 1.2.3)Test plan
- Test valid PR:
./build/atmos --use-version 2040 version - Test invalid PR:
./build/atmos --use-version 999999 version(should error) - Test TTL caching: run twice within 1 minute
- Test invalid format:
./build/atmos --use-version abc version(should error) - Test invalid format:
./build/atmos --use-version abc123 version(should error) - Test semver:
./build/atmos --use-version 1.175.0 version(should work)
references
- New packages:
pkg/github/artifacts.go- GitHub API integration for PR artifact retrievalpkg/github/token.go- Smart token detection with gh CLI fallbacktoolchain/pr_artifact.go- PR artifact download and installation logictoolchain/version_spec.go- Version format parsing and validation
- Modified packages:
pkg/version/reexec.go- PR version detection in version switching
- Test coverage: Unit tests for all new functionality
🤖 Generated with Claude Code
Summary by CodeRabbit
-
New Features
- Install Atmos from PR artifacts (pr:NNNN) and SHAs via --use-version with platform-aware downloads, local caching, TTL checks, safe extraction, and progress indicators
- Improved version spec parsing and explicit --use-version re-exec handling
- Automatic GitHub token detection (env vars then gh CLI) and clearer, actionable error messages for auth/CI/platform issues
-
Documentation
- Added guide for PR/SHA artifact installation, authentication, and troubleshooting
-
Tests
- Extensive unit tests covering artifact retrieval, token handling, caching, extraction, and install flows
feat: add GCP authentication support @shirkevich (#2051)
what
- Add GCP auth providers:
gcp/adc(Application Default Credentials)gcp/workload-identity-federation(OIDC WIF for CI/CD)
- Add GCP identities:
gcp/service-account(impersonation via IAM Credentials API, delegates supported)gcp/project(project/region/zone context only)
- Add GCP auth context support in schema and environment export (
GOOGLE_OAUTH_ACCESS_TOKEN,GOOGLE_CLOUD_PROJECT, etc.) - Implement AWS-style file isolation for GCP:
- New path layout:
~/.config/atmos/gcp/<provider-name>/... - Provider-scoped ADC and gcloud config directories
- New path layout:
- Extend auth factory/identity wiring to support new GCP kinds
- Add IAM credentials service injection for testability
- Fix
auth whoamivalidation fallback for non-validated credentials (GCP)
why
- Extend the existing multi-cloud auth framework to GCP, matching AWS/Azure patterns.
- Provide secure CI/CD via WIF (no long-lived keys).
- Enforce consistent, provider-scoped file isolation aligned with the universal pattern (AWS reference).
- Ensure
auth whoamiworks for GCP credential types that don’t implement validation yet.
references
- Universal auth file isolation pattern:
docs/prd/auth-file-isolation-pattern.md - AWS reference implementation:
docs/prd/aws-auth-file-isolation.md - Azure isolation plan (consistency target):
docs/prd/azure-auth-file-isolation.md - GCP provider/identity docs updated in
website/docs/cli/configuration/auth/*
p.s. tested locally and in GitHub with WIF
Summary by CodeRabbit
-
New Features
- First-class GCP auth: ADC and Workload Identity Federation providers, Service Account and Project identities, GCPCredentials type, provider-scoped credential files, env helpers, static token via GOOGLE_OAUTH_ACCESS_TOKEN, auth-realm resolution, and pluggable provider/identity factory; keyring now stores GCP creds.
-
Bug Fixes
- Validate fallback for NotImplemented to accept unexpired creds; clearer whoami error guidance for GCP reauthentication scenarios.
-
Documentation
- New GCP docs, examples, blog post and roadmap update.
-
Tests
- Extensive unit tests for GCP flows, files, factories, providers, identities and credentials.
fix(auth): keep realm isolation opt-in for gcp to preserve legacy paths @shirkevich (#2085)
Summary
Align GCP auth behavior with #2075: realm isolation is opt-in and empty realm keeps backward-compatible paths.
What changed
- When neither
auth.realmnorATMOS_AUTH_REALMis set, GCP credential files now use legacy paths without a realm segment. - Updated GCP service-account realm handling to preserve empty realm behavior.
- Updated GCP path helpers/docs/comments to treat realm as optional in legacy mode.
- Updated tests to enforce empty-realm backward compatibility and removed auto-realm assumptions.
Why
PR #2075 restored backward-compatible behavior after #2043 by making realm isolation opt-in. This PR ensures GCP follows the same model and does not reintroduce always-on realm isolation semantics.
Summary by CodeRabbit
-
New Features
- Added support for legacy credential paths when realm is empty, enabling backward-compatible configurations.
- Enhanced GCP authentication with improved Application Default Credentials (ADC) handling.
-
Bug Fixes
- Relaxed realm requirement to allow empty values, improving flexibility in credential path management.
-
Tests
- Added comprehensive test coverage for GCP ADC authentication flows and realm handling scenarios.
fix: resolve AWS profile SSO interference and --identity flag regression @aknysh (#2087)
what
- Fix AWS
[default]profile interfering with SSO authentication by isolating AWS SDK config loading from~/.aws/config - Fix
--identityflag not accepting space-separated values (--identity my-identitywas broken, only--identity=my-identityworked) - Normalize
--identity <value>to--identity=<value>before Cobra/pflag parsing to support standard CLI conventions - Add comprehensive test coverage for both fixes
why
- Users reported that having a
[default]profile with SSO settings in~/.aws/configcaused misleading SSO authentication failures — the AWS SDK v2 loaded~/.aws/configvia a hardcoded$HOMEpath even after env var sanitization - The original isolation used
config.WithSharedConfigProfile("")which is a no-op in the AWS SDK v2 (empty string →found=false→ falls back to"default"profile). Replaced withconfig.WithSharedConfigFiles([]string{})which provides a non-nil empty slice that the SDK respects - Users reported that
--identity my-identity(space-separated) caused "Too many command line arguments" errors from Terraform/OpenTofu, forcing them to use--identity=my-identityorATMOS_IDENTITY=my-identityas workarounds - The
--identityflag was registered withNoOptDefValto support interactive selection mode (--identitywith no value), which caused pflag to treat it like a boolean flag and not consume the next argument as its value
references
- Fix documentation:
docs/fixes/2026-02-17-aws-default-profile-sso-interference.md - Fix documentation:
docs/fixes/2026-02-17-identity-flag-space-separated-value.md
fix: resolve retry configuration defaults with pointer types @osterman (#2039)
Fixes #2034 - retry configuration defaults causing failures with partial configs.Changes
- Changed
RetryConfigfields to pointer types (nil = unlimited, explicit zero = error) - Added
Validate()function to error on explicit zeros - Added retry support to shell workflow steps
- Created
examples/workflow-retries/demonstrating retry behavior with intentional failure - Updated documentation with definition lists and unlimited retry examples
Configuration Philosophy
- Omitting a parameter = unlimited/disabled (feature not activated)
- Explicitly setting to zero = validation error (invalid configuration)
Summary by CodeRabbit
-
New Features
- Added a Workflow Retries example demonstrating retry behavior and resume hints.
- Examples now favor a minimal-first, generalized structure and README template.
-
Improvements
- Retry configs support optional (unset vs explicit) fields, improved validation, and clearer retry semantics.
- Shell steps now honor retry settings; error output shows when max retries were reached plus the underlying error.
-
Documentation
- Retry configuration docs rewritten with detailed semantics, examples, and guidance.
-
Tests
- Expanded test coverage and updated CLI snapshots for retry scenarios.
fix: propagate templates.settings.env to gomplate datasources @aknysh (#2084)
what
- Fixed three interconnected bugs that prevented
templates.settings.envfrom propagating environment variables to gomplate datasources mapstructure:"-"tag onTemplatesSettings.Envsilently dropped the env field during the encode/decode/merge pipeline inProcessTmplWithDatasources- Viper lowercased env var keys (e.g.,
AWS_PROFILE→aws_profile) andcaseSensitivePathsdidn't includetemplates.settings.env - Stack manifest env vars were dropped at 4 caller decode sites in
utils.goanddescribe_stacks.go - Added deferred env cleanup to restore original env values after template processing, preventing pollution across components
- Updated dependency compatibility (
gocloud.dev,terraform-exec) after go.mod update
why
- Users configuring
templates.settings.envwith AWS credentials (e.g.,AWS_PROFILE,AWS_REGION) expected gomplate datasources (S3, SSM, Secrets Manager) to use those credentials, but env vars were never set in the OS environment - The
os.Setenvloop inProcessTmplWithDatasourcesnever executed becausetemplateSettings.Envwas always nil after mapstructure dropped it - Without env cleanup, env vars set for one component could leak into subsequent component processing
references
- Closes #2083
- Fix document:
docs/fixes/2026-02-16-gomplate-datasource-env-vars.md
Summary by CodeRabbit
-
Bug Fixes
- Fixed environment variable propagation in template datasources—vars from config and stack manifests are preserved during template processing.
- Improved case sensitivity handling for template environment variables.
- Removed an unnecessary debug log line.
-
New Features
- Terraform workspace selection accepts optional parameters.
-
Documentation
- Added docs describing datasource environment variable propagation and the fix.
-
Tests
- Added integration and unit tests covering env propagation and case sensitivity.
-
Chores
- Updated dependency licenses/versions and NOTICE entries.
- Component describe outputs now include a new deprecated field placeholder.
feat: add atmos ansible component support @RoseSecurity (#2042)
what
- Add Ansible as a first-class component type in Atmos, alongside Terraform, Helmfile, and Packer
- Implement
atmos ansible playbookcommand to execute Ansible playbooks with stack-based configuration - Implement
atmos ansible versioncommand to display Ansible version information - Add stack processor support for Ansible components with full inheritance, vars, env, settings, and auth sections
- Support automatic variable file generation passed to Ansible via
--extra-vars @<varfile> - Enable pass-through of native Ansible flags via
--separator - Add command aliases:
anforansible,pbforplaybook - Include comprehensive documentation in Docusaurus
why
- Ansible is widely used for configuration management and application deployment, complementing Terraform's infrastructure provisioning
- Users can now manage Ansible playbooks with the same stack-based configuration patterns they use for Terraform
- Enables consistent variable management across infrastructure (Terraform) and configuration (Ansible) layers
- Supports the same powerful features as other component types: inheritance, environment variables, settings, JIT provisioning, and validation
- Reduces context-switching by providing a unified CLI for infrastructure orchestration
usage
Configuration
Add to atmos.yaml:
components:
ansible:
base_path: "components/ansible"
command: "ansible-playbook" # optional
auto_generate_files: false # optionalStack Manifest
Define Ansible components in stack manifests:
components:
ansible:
webserver:
vars:
app_name: myapp
app_port: 8080
app_version: "1.0.0"
env:
ANSIBLE_HOST_KEY_CHECKING: "false"
settings:
ansible:
playbook: site.yml
inventory: inventory/productionCommands
# Show Ansible version
atmos ansible version
# Run playbook with settings from stack manifest
atmos ansible playbook webserver --stack prod
# Specify playbook explicitly (overrides stack settings)
atmos ansible playbook webserver -s prod --playbook deploy.yml
# Specify both playbook and inventory
atmos ansible playbook webserver -s prod -p site.yml -i hosts.ini
# Dry run (shows commands without executing)
atmos ansible playbook webserver -s prod --dry-run
# Pass native Ansible flags via -- separator
atmos ansible playbook webserver -s prod -- --check
atmos ansible playbook webserver -s prod -- --verbose --limit "web01,web02"
atmos ansible playbook webserver -s prod -- --tags "deploy,config"
# Use aliases for brevity
atmos an pb webserver -s prod
# Path-based component resolution
cd components/ansible/webserver
atmos ansible playbook . -s prodEnvironment Variables
ATMOS_ANSIBLE_PLAYBOOK=site.yml # Default playbook
ATMOS_ANSIBLE_INVENTORY=hosts.ini # Default inventoryreferences
Summary by CodeRabbit
-
New Features
- Native Ansible support: new ansible command with playbook/version subcommands, --playbook/-p and --inventory/-i flags, passthrough of native Ansible options, shell completions, provider-backed execution, JIT component provisioning, automatic varfile generation/cleanup, and env/stack-aware execution.
-
Documentation
- New CLI docs, usage pages, examples, blog post, and roadmap entry for Ansible workflows.
-
Tests
- Extensive unit and integration tests covering CLI, flags, completions, provider, executor, and stack processing.
-
Chores
- Added Ansible config keys/paths, help aliases/snapshots, and user-facing Ansible errors.
Restore public API for terraform-provider-utils component config @aknysh (#2078)
what
- Restore
ProcessComponentInStackandProcessComponentFromContextpublic functions that were deleted in v1.201.0 (PR #1774) - Add the functions to
pkg/describe(notpkg/component) to avoid an import cycle - These are the two functions that
cloudposse/terraform-provider-utilsdepends on for thedata "utils_component_config"data source - Add comprehensive tests for both functions (14 test cases)
why
- In v1.201.0 (PR #1774 — "Path-based component resolution for all commands"),
pkg/component/component_processor.gowas deleted entirely. This file containedProcessComponentInStackandProcessComponentFromContext, which are the public API consumed bycloudposse/terraform-provider-utils - The processing logic was moved to
internal/exec, which external Go modules cannot import - This blocks the provider from upgrading its Atmos dependency past v1.189.0
- Users running Atmos CLI v1.200+ with new features (
stores,hooks,gomplatetemplates,!terraform.state/!terraform.outputYAML tags) experience provider crashes ("Plugin did not respond") because the old v1.189.0 code in the provider cannot parse the newer configuration format - The crash affects all components using
cloudposse/stack-config/yaml//modules/remote-state, which callsdata "utils_component_config"internally — in one affected repo, this impacts 56 components - The functions are placed in
pkg/describeinstead ofpkg/componentbecauseinternal/execnow importspkg/component(for theComponentProviderinterface andComponentRegistry), which would create an import cycle
references
- Atmos issue doc:
docs/fixes/2026-02-15-restore-component-processor-public-api.md - PR #1774 — "Path-based component resolution for all commands" (deleted
pkg/component/component_processor.go) - Affected module:
cloudposse/stack-config/yaml//modules/remote-statev1.8.0
Summary by CodeRabbit
-
New Features
- Restored public APIs for processing component configurations via stack or contextual parameters.
-
Documentation
- Added detailed guidance on the restored public API, historical context, integration notes, and usage considerations.
-
Tests
- Added comprehensive tests for success and error scenarios, variable extraction, workspace presence, tenant variations, and cross-validation between entry points.