github cloudposse/atmos v1.223.0-rc.8

pre-release5 hours ago
feat(workflows): interactive steps run in CI via non-TTY defaults @sgtoj (#2714) ## What

Interactive workflow and custom-command step types (choose, input, confirm, filter, file, write) now fall back to their configured default value when running without a TTY (e.g. in CI) instead of failing with interactive terminal required for step. Without a default, the historical TTY-required error is preserved, so an unattended run never proceeds with an unintended value.

workflows:
  build-manifests:
    steps:
      - name: account
        type: choose
        prompt: "Account"
        options: [dev, prod]
        default: !env STACK_ACCOUNT dev   # prompts locally; uses env/`dev` in CI
      - name: tag
        type: input
        prompt: "Release tag"
        default: !env RELEASE_TAG latest
      - type: shell
        command: atmos kube build "{{ .steps.account.value }}" --tag "{{ .steps.tag.value }}"

Two parts:

  1. Non-TTY default fallback (pkg/runner/step) — a shared BaseHandler.resolveInteractive decides prompt vs. default vs. error, and BaseHandler.ResolveDefault centralizes default resolution. The now-unused CheckTTY is removed. Because workflows, custom commands, hooks, and the task runner share the step handler registry, one change covers them all.
  2. !env / !exec in workflow step fields (internal/exec) — workflow step default/prompt/options/placeholder evaluate the context-free !env and !exec YAML functions (workflow manifests otherwise leave them as literal !env ... strings; custom commands already resolve them during config load). Stack-dependent functions are intentionally left untouched.

Why

Interactive steps make workflows and custom commands friendly to run by hand but unrunnable in CI, forcing teams to maintain a second, prompt-free copy of the same automation. A configured default is an explicit opt-in to a non-interactive value, so honoring it when there is no TTY is safe. Leaving default unset keeps the guard for steps where a human must choose.

Depends on

Consuming a captured value in a later shell/atmos step ({{ .steps.*.value }}) relies on the workflow command/env: templating fix in #2711 (already merged), which this builds on.

Testing

  • Unit tests for each interactive handler: non-TTY returns the default (single/multi/confirm/template-resolved), and still errors without a default.
  • Unit tests for !env/!exec field resolution (and passthrough of plain/template/stack-dependent values), including nested steps.
  • End-to-end (built binary): a workflow and a custom command both run unattended via !env defaults, feed values into a shell step, and a no-default step still errors (exit 1).

References

  • PRD: docs/prd/interactive-steps-non-tty-defaults.md
  • Changelog: website/blog/2026-07-08-interactive-steps-ci-defaults.mdx
  • Roadmap: Workflows Overhaul milestone in website/src/data/roadmap.js

Summary by CodeRabbit

  • New Features
    • Interactive workflow and custom-command steps now use configured default values in non-TTY environments (such as CI) for choose, input, confirm, filter, file, and write.
    • default/prompt/placeholder/options support !env and !exec, and resolved values are available to later steps.
    • filter multi-select defaults accept comma-separated values.
  • Bug Fixes
    • Non-interactive runs without a default still fail safely.
  • Documentation
    • Added CI/non-TTY guidance with examples for interactive step defaults.
  • Tests
    • Expanded unit tests for !env/!exec resolution and non-TTY default behavior.

🚀 Enhancements

feat(terraform): add --log-order to apply, deploy, and destroy @cmharden (#2674) ## what - Add `--log-order stream|grouped` to `atmos terraform apply`, `deploy`, and `destroy` (previously `plan`-only). - Bring `deploy` to concurrency parity with `apply`: add `--max-concurrency` and `--failure-mode`, and add `deploy` to the scheduler's concurrency allowlist so those flags (and grouped logs) actually take effect. - Rename the internal plan-specific log-order identifiers to generic (`PlanLogOrder`→`LogOrder`, `TerraformPlanLogOrder`→`TerraformLogOrder`, consts drop `Plan`). - New env vars: `ATMOS_TERRAFORM_{APPLY,DEPLOY,DESTROY}_LOG_ORDER`, plus deploy's `ATMOS_TERRAFORM_DEPLOY_{MAX_CONCURRENCY,FAILURE_MODE}`. - Docs updated for the three commands.

why

  • plan could order concurrent per-component logs, but apply/deploy/destroy could not — atmos terraform apply --all --log-order grouped failed with "unknown flag". Grouped output (contiguous per-component blocks) is what
    makes concurrent --all runs debuggable.
  • The scheduler adapter already buffered grouped output for any subcommand; only the flag exposure — and deploy's
    missing allowlist entry — stood in the way. Renaming the plan-specific identifiers reflects that this is a
    scheduler-level concern shared by four commands.

notes

  • Backward compatible: the --log-order flag name, stream/grouped values, and ATMOS_TERRAFORM_PLAN_LOG_ORDER
    are unchanged; the renamed field is internal/untagged.
  • --log-order grouped engages only under --max-concurrency > 1 (matches plan).
  • Happy to add a changelog entry / roadmap update in your preferred format if you'd like — left those to maintainer
    discretion.

Summary by CodeRabbit

  • New Features
    • Added --log-order (stream default, grouped) to Terraform apply, deploy, and destroy, with corresponding environment variables.
    • Added deploy concurrency controls: --max-concurrency (default 1) and --failure-mode (fail-fast/keep-going).
  • Bug Fixes
    • Improved grouped log ordering for concurrent non-plan operations (apply, deploy, destroy).
    • Corrected and standardized log-order handling/validation across commands.
  • Documentation
    • Updated Terraform command docs and CLI help for the new flags.
  • Tests
    • Added unit coverage for flag registration, option mapping, and grouped/non-plan behavior.
fix(auth): atmos.Component() nested lookups could lose/reuse wrong identity @osterman (#2712) ## what
  • Fixes internal/exec/terraform_nested_auth_helper.go so the nested-auth cache (nestedAuthManagerCache, added in #2652/#2656) never caches a result resolved through authContextWrapper — its GetChain() always returns an empty slice by design, so two different real identities propagated this way could otherwise collide on the same cache key and silently reuse the wrong identity's AuthManager.
  • Fixes internal/exec/template_funcs_component.go (atmos.Component()) so it resolves a nested target's own auth: section (via resolveAuthManagerForNestedComponent) instead of always reusing the enclosing component's credentials verbatim — bringing it in line with how !terraform.state/!terraform.output already behave.
  • Adds regression tests for both (TestBuildComponentAuthCacheKey_AuthContextWrapperNeverCaches, TestResolveComponentFuncAuthManager) and a docs/fixes write-up.

why

  • A user reported atmos list instances regressing from v1.221.0 to v1.222.0 under GitHub Actions/OIDC auth (no ambient AWS credentials): a Go template calling atmos.Component(...) to fetch a nested component's terraform output failed with no valid credential sources found ... no EC2 IMDS role found — meaning the subprocess got zero AWS credential material and fell through to the (nonexistent, off-EC2) instance-metadata provider.
  • Both defects were introduced or exposed by the per-component/nested auth-caching optimizations added in v1.222.0 (#2652, #2656) and match the same symptom already fixed once this cycle in the terraform-hooks path (docs/fixes/2026-06-27-store-hook-inherit-default-identity.md).
  • The user's own component topology (nested target with no auth: override of its own) isn't fully explained by these two fixes alone; that residual uncertainty and a debug-log diagnostic for further narrowing are documented in docs/fixes/2026-07-09-atmos-component-nested-auth-cache-collision.md.

references

Summary by CodeRabbit

  • Bug Fixes
    • Fixed nested component authentication so nested atmos.Component() calls use the correct identity for the nested target.
    • Prevented incorrect auth reuse between nested calls by addressing nested auth caching collisions.
    • Improved nested Terraform output handling so !terraform.output respects nested auth defaults and properly propagates auth-disabled behavior.
  • Documentation
    • Added a documentation page describing the nested auth cache collision regression and the resolution.
  • Tests
    • Added/updated coverage for nested auth resolution, cache-key behavior, and AuthDisabled propagation.

Don't miss a new atmos release

NewReleases is sending notifications on new releases.