steps
The steps field is an ordered array of step objects. Atmos executes the steps in the order they appear.
workflows:
deploy:
steps:
- name: plan
type: atmos
command: terraform plan vpc
- name: apply
type: atmos
command: terraform apply vpc -auto-approve
Each array item is a step — the unit of work Atmos runs, whether it executes a command or renders interactive UI. The type field selects step behavior. Fields such as title, columns, prompt, retry, and timeout are parameters on that same step object; they are not separate steps.
steps:
- name: building
type: spin
title: Building application
command: npm run build
timeout: 60s
In this example, spin is the value of steps[].type. The fields title, command, and timeout configure that spin step.
Common Fields
name- Optional step identifier. Atmos generates names like
step1when omitted. Names are used by--from-stepand by templates such as{{ .steps.plan.value }}. type- Step behavior selector. Type
atmosis the default for command steps. See type. command- Command text for command-running step types such as
atmos,shell,spin, andcontainerrun actions. stack- Step-level stack override for
type: atmossteps. identity- Step-level auth identity. See identity.
when- Optional condition that decides whether the step runs. Built-in predicate keywords are evaluated first; other non-empty scalar strings are evaluated as CEL.
env- Step-level environment variables. See env.
working_directory- Step-level working directory override. See working_directory.
retry- Retry policy for the step. See retry.
output- Step-level output mode override. See output.
show- Step-level display settings override. See show.
outputs- Declared outputs derived from the step result. See outputs.
when- Condition controlling whether the step runs. Omitted means success-only: the step runs while the workflow status is still
success. Usewhen: alwaysfor cleanup steps that must run after a previous step fails, such as stopping an emulator, restoring a backup file, or removing Terraform state.
Type-specific fields are documented with type.
Referencing values from other steps
A named step's result is available to later steps as {{ .steps.<name>.value }}
(and {{ .steps.<name>.values }} for multi-value steps). These templates — along
with {{ .env.* }} and {{ .flags.* }} and Sprig/Gomplate functions — resolve
in shell, atmos, and exec step commands and in a step's env:
values, the same way they do for custom command steps:
workflows:
deploy:
steps:
- name: component
type: choose
prompt: "Component"
options: [vpc, eks]
- type: atmos
command: terraform apply {{ .steps.component.value }} -auto-approve
env:
COMPONENT: "{{ .steps.component.value }}"
Interactive Steps in CI (non-TTY)
Interactive step types (choose, input, confirm, filter, file, write) prompt for input and need a terminal. When Atmos runs without a TTY — most commonly in CI — a step behaves based on whether it has a default:
- With a
default, the step uses the default value without prompting. - Without a
default, the step fails withinteractive terminal required for step. This preserves the previous behavior, so an unattended run never proceeds with an unintended value.
This lets the same workflow prompt locally and run unattended in CI. Source the default from the environment with the !env function (!env VAR fallback):
steps:
- name: account
type: choose
prompt: "Account"
options: [dev, prod]
default: !env STACK_ACCOUNT dev
- type: shell
command: 'echo "Deploying {{ .steps.account.value }}"'
Workflow step default, prompt, options, and placeholder evaluate the !env and !exec YAML functions. (Custom commands defined in atmos.yaml resolve these during config load.) The captured value — entered interactively or taken from the default — is available to later steps as {{ .steps.<name>.value }}.
Conditional Execution
Use when to skip a workflow step unless a condition is true. Bare predicate keywords keep their existing behavior:
steps:
- name: plan
type: atmos
command: terraform plan vpc
when: ci
Any other non-empty scalar string is evaluated as a CEL expression:
steps:
- name: prod-ci-check
type: shell
command: ./scripts/check-prod.sh
when: stack == "prod" && ci
Use the explicit !cel tag when the value is intended to be CEL or could look ambiguous:
steps:
- name: prod-ci-check
type: shell
command: ./scripts/check-prod.sh
when: !cel 'stack == "prod" && ci'
Workflow step CEL expressions can use ci, status, stack, component, workflow, step, and env. Predicate keywords win over CEL for bare strings, so when: ci uses the built-in predicate while when: !cel 'ci' evaluates CEL. status starts as success and becomes failure after a previous step fails.
Cleanup Steps
Atmos continues evaluating structured steps after a failure so failure-aware cleanup can run:
steps:
- type: shell
name: start-emulator
command: atmos emulator up aws -s dev --ephemeral
- type: shell
name: record-or-test
command: atmos terraform apply demo -s dev -auto-approve
- type: shell
name: stop-emulator
when: always
command: atmos emulator down aws -s dev
- type: shell
name: validate
command: atmos terraform output demo -s dev
If record-or-test fails, stop-emulator still runs because it declares
when: always. The validate step is skipped because omitted when means
success-only. The workflow still exits with the original failure; cleanup does
not make the failed workflow look successful.