Skip to main content

Workflows

Workflows are a way of combining multiple commands into one executable unit of work.

You can use Atmos Custom Commands in Atmos Workflows, and Atmos Workflows in Atmos Custom Commands

Simple Example

Here's an example workflow called eks-up which runs a few commands that will bring up the EKS cluster:

workflows:
eks-up:
description: |
Bring up the EKS cluster.
steps:
- command: terraform apply vpc -auto-approve
- command: terraform apply eks/cluster -auto-approve
- command: terraform apply eks/alb-controller -auto-approve

Retry Configuration

The retry section accepts the following parameters. All parameters are optional - omit any parameter to disable that feature or use unlimited behavior.

max_attempts
Maximum number of retry attempts. Omit for unlimited retries. Must be greater than zero if specified.
max_elapsed_time
Total time budget for all attempts combined (e.g., 10m, 1h). This is the cumulative time across all retry attempts plus backoff delays, not a per-attempt timeout. Omit for no time limit. Must be greater than zero if specified.
backoff_strategy
The backoff strategy between retries: constant, linear, or exponential. Default: constant.
initial_delay
Delay before the first retry (e.g., 5s, 100ms). Omit for no delay. Cannot be negative.
max_delay
Maximum delay between retries, caps exponential/linear growth (e.g., 30s). Omit for no cap. Must be greater than zero if specified.
multiplier
Multiplier for exponential or linear backoff (e.g., 2.0). Omit to use the default multiplier (2.0). Must be greater than zero if specified.
random_jitter
Jitter factor between 0.0 and 1.0 to add randomness to delays. Omit for no jitter.
Configuration Philosophy
  • Omitting a parameter disables that feature or makes it unlimited
  • Explicitly setting a parameter to zero is an error (invalid configuration)
  • This allows minimal configs like retry: { max_attempts: 3 } to work without surprises

Example: Retry Indefinitely

To retry indefinitely until success, omit both max_attempts and max_elapsed_time:

workflows:
deploy:
steps:
- command: terraform apply vpc -auto-approve
retry:
initial_delay: 5s
backoff_strategy: exponential
max_delay: 60s
# max_attempts: omitted = unlimited retries
# max_elapsed_time: omitted = no time limit

This will keep retrying with exponential backoff (capped at 60s between attempts) until either:

  • The command succeeds
  • The workflow is cancelled (e.g., Ctrl+C)

Example: Limited Retries, No Time Limit

workflows:
eks-up:
description: Bring up the eks cluster
steps:
- command: terraform apply vpc -auto-approve
retry:
max_attempts: 3
backoff_strategy: exponential
initial_delay: 3s
multiplier: 2
# max_elapsed_time: omitted = no time limit
- command: terraform apply eks/cluster -auto-approve
- command: terraform apply eks/alb-controller -auto-approve

Example: Time-Limited Retries

retry:
max_elapsed_time: 10m # Stop after 10 minutes total
initial_delay: 5s
backoff_strategy: exponential
# max_attempts: omitted = unlimited attempts within time budget
note

The workflow name can be anything you want, and the workflow can also accept command-line parameters (e.g. stack name)

If you define this workflow in the file workflow1.yaml, it can be executed like this to provision the vpc, eks/cluster and eks/alb-controller Atmos Components into the tenant1-ue2-dev Atmos Stack:

atmos workflow eks-up -f workflow1 --stack tenant1-ue2-dev
tip

Refer to atmos workflow for the complete description of the CLI command

Workflow File Auto-Discovery

Atmos can automatically discover workflow files, eliminating the need to specify --file for uniquely named workflows.

Running Workflows Without --file

If your workflow name is unique across all workflow files, Atmos automatically finds and runs it:

# Just specify the workflow name - Atmos finds the file automatically
atmos workflow eks-up --stack tenant1-ue2-dev

This is equivalent to:

# Explicitly specifying the file (still supported)
atmos workflow eks-up -f workflow1 --stack tenant1-ue2-dev

How Auto-Discovery Works

When you run atmos workflow <name> without --file:

  1. Scans workflow directory - Atmos searches all YAML files in your configured workflows.base_path
  2. Finds matching workflows - Looks for workflows with the specified name
  3. Auto-selects if unique - If only one file contains that workflow name, it runs automatically
  4. Prompts if multiple - If multiple files have the same workflow name, shows an interactive selector (TTY) or an error with hints (CI/non-TTY)

Interactive Selection for Duplicate Workflow Names

If multiple workflow files contain the same workflow name, Atmos presents an interactive selector:

$ atmos workflow deploy

Multiple workflows found with name 'deploy'. Please choose:
> production.yaml - Deploy to production environment
staging.yaml - Deploy to staging environment
development.yaml - Deploy to development environment

You can still use --file to skip the prompt and specify exactly which file to use:

atmos workflow deploy --file production.yaml
note

The --file value is relative to your configured workflows.base_path. You can omit the .yaml extension - Atmos adds it automatically if not provided.

When to Use --file

The --file flag is optional for most workflows. You only need it when:

  • Multiple workflow files contain a workflow with the same name
  • You want to explicitly specify which file to use (e.g., in CI/CD scripts)
  • You're running in a non-interactive environment where prompts aren't available

Backward Compatibility

All existing workflows with explicit --file flags continue to work exactly as before:

# Explicit --file flag still works
atmos workflow deploy --file deploy.yaml

# Auto-discovery is purely additive
atmos workflow deploy

Configuration

To configure and execute Atmos workflows, follow these steps:

Configure Workflows in atmos.yaml

In atmos.yaml CLI config file, add the following sections related to Atmos workflows:

# Base path for components, stacks and workflows configurations.
# Can also be set using 'ATMOS_BASE_PATH' ENV var, or '--base-path' command-line argument.
# Supports both absolute and relative paths.
# If not provided or is an empty string, 'components.terraform.base_path', 'components.helmfile.base_path', 'stacks.base_path'
# and 'workflows.base_path' are independent settings (supporting both absolute and relative paths).
# If 'base_path' is provided, 'components.terraform.base_path', 'components.helmfile.base_path', 'stacks.base_path'
# and 'workflows.base_path' are considered paths relative to 'base_path'.
base_path: ""

workflows:
# Can also be set using 'ATMOS_WORKFLOWS_BASE_PATH' ENV var, or '--workflows-dir' command-line arguments
# Supports both absolute and relative paths
base_path: "stacks/workflows"

where:

base_path
The base path for components, stacks and workflows configurations
workflows.base_path
The base path to Atmos workflow files

Create Workflow Files

In atmos.yaml, we set workflows.base_path to stacks/workflows. The folder is relative to the root of the repository.

Refer to networking.yaml for an example.

We put the workflow files into the folder. The workflow file names can be anything you want, but we recommend naming them according to the functions they perform, e.g. create separate workflow files per environment, account, team, or service.

For example, you can have a workflow file stacks/workflows/workflows-eks.yaml to define all EKS-related workflows.

Or, you can have a workflow file stacks/workflows/workflows-dev.yaml to define all workflows to provision resources into the dev account. Similarly, you can create a workflow file stacks/workflows/workflows-prod.yaml to define all workflows to provision resources into the prod account.

You can segregate the workflow files even further, e.g. per account and service. For example, in the workflow file stacks/workflows/workflows-dev-eks.yaml you can define all EKS-related workflows for the dev account.

Use Workflow Schema

Workflow files must confirm to the following schema:

workflows:

workflow-1:
description: "Description of Workflow #1"
steps: []

workflow-2:
description: "Description of Workflow #2"
steps: []

Each workflow file must have the workflows: top-level section with a map of workflow definitions.

Each workflow definition must confirm to the following schema:

  workflow-1:
description: "Description of Workflow #1"
stack: <Atmos stack> # optional
steps:
- command: <Atmos command to execute>
name: <step name> # optional
type: atmos # optional
stack: <Atmos stack> # optional
identity: <identity name> # optional
- command: <Atmos command to execute>
name: <step name> # optional
stack: <Atmos stack> # optional
identity: <identity name> # optional
- command: <shell script>
name: <step name> # optional
type: shell # required for the steps of type `shell`
identity: <identity name> # optional

Schema Definitions

description
The workflow description
stack
Workflow-level Atmos stack (optional). If specified, all workflow steps of type atmos will be executed for this Atmos stack. It can be overridden in each step or on the command line by using the --stack flag (-s for shorthand)
steps
A list of workflow steps which are executed sequentially in the order they are specified
command
The command to execute. Can be either an Atmos CLI command (without the atmos binary name in front of it, for example command: terraform apply vpc), or a shell script. The type of the command is specified by the type attribute
name
Step name (optional). It's used to find the first step from which to start executing the workflow when the command-line flag --from-step is specified. If the name is omitted, a friendly name will be generated for you consisting of a prefix of step and followed by the index of the step (the index starts with 1, so the first generated step name would be step1).
type
The type of the step. Can be atmos, shell, or any of the interactive step types like input, confirm, choose, filter, markdown, spin, and more. Type atmos is implicit for command steps. Type shell is required for shell scripts. See the Step Types section for all available types
stack
Step-level Atmos stack (optional). If specified, the command will be executed for this Atmos stack. It overrides the workflow-level stack attribute, and can itself be overridden on the command line by using the --stack flag (-s for shorthand)
identity
Step-level identity for authentication (optional). If specified, Atmos will authenticate using this identity before executing the step. The subprocess will receive environment variables pointing to temporary credential files (e.g., AWS_SHARED_CREDENTIALS_FILE, AWS_CONFIG_FILE, AWS_PROFILE). See Authentication for more details
note

A workflow command of type shell can be any simple or complex shell command or script. You can use YAML Multiline Strings to create complex multi-line shell scripts.

Interactive Workflows

Atmos supports 25+ step types for building interactive CLI wizards. Use input, confirm, choose, and filter to collect user input, markdown and success/info/warn/error for rich output, spin for progress spinners, and alert/title/env/exit for terminal control. See the Step Types section below for complete documentation.

Step Types

Atmos supports 25+ step types across five categories: Command, Interactive, UI Messages, Output, and Terminal. These step types enable building sophisticated CLI wizards and interactive deployment pipelines.

Step Types Overview

CategoryStep TypesDescription
Commandatmos, shellExecute Atmos or shell commands
Interactiveinput, confirm, choose, filter, file, writeCollect user input
UI Messagessuccess, info, warn, error, markdownDisplay formatted messages
Outputspin, table, pager, format, join, styleFormat and display output
Terminalalert, title, clear, env, exitTerminal control and workflow management

Interactive Step Types

Interactive steps require a TTY (terminal) to run. In CI environments, use --dry-run to preview workflows or set default values.

input

Prompts for single-line text input.

steps:
- name: message
type: input
prompt: "Enter deployment message"
placeholder: "e.g., Fix for ticket JIRA-123"
default: "Routine deployment"
prompt
The prompt text to display
default
Default value if user presses enter
placeholder
Placeholder text shown in the input field
password
Set to true to mask input for sensitive values

confirm

Prompts for yes/no confirmation.

steps:
- name: confirm_prod
type: confirm
prompt: "Deploy to production?"
default: false
prompt
The confirmation question
default
Default value (true or false)

choose

Single selection from a list of options.

steps:
- name: environment
type: choose
prompt: "Select target environment"
options:
- dev
- staging
- prod
default: dev
prompt
The selection prompt
options
List of options to choose from
default
Default selected option

filter

Filterable selection with optional multi-select support.

steps:
- name: components
type: filter
prompt: "Select components to deploy"
multiple: true
limit: 5
options:
- vpc
- eks
- rds
- s3
- lambda
prompt
The selection prompt
options
List of options to filter/select from
multiple
Allow multiple selections (default: false)
limit
Maximum number of visible options
tip

Use {{ .steps.NAME.values }} to access the array of selected values when multiple: true.

file

File picker for selecting files from the filesystem.

steps:
- name: config_file
type: file
prompt: "Select a configuration file"
path: "./configs"
extensions:
- yaml
- yml
- json
prompt
The file selection prompt
path
Starting directory for file browsing
extensions
List of allowed file extensions

write

Multi-line text editor for longer input.

steps:
- name: notes
type: write
prompt: "Enter deployment notes"
placeholder: |
Describe the changes being deployed...

- Change 1
- Change 2
prompt
The editor prompt
placeholder
Placeholder text shown in the editor

UI Message Step Types

These steps display formatted messages to the user. They use the Atmos UI theme for consistent styling.

success

Displays a success message with a green checkmark icon.

steps:
- name: done
type: success
content: "Deployment completed successfully!"

info

Displays an informational message with a blue info icon.

steps:
- name: status
type: info
content: "Processing {{ .steps.count.value }} items..."

warn

Displays a warning message with a yellow warning icon.

steps:
- name: caution
type: warn
content: "This action cannot be undone!"

error

Displays an error message with a red error icon.

steps:
- name: failed
type: error
content: "Configuration validation failed"

markdown

Renders markdown content with full formatting support.

steps:
- name: intro
type: markdown
content: |
# Deployment Wizard

Welcome to the interactive deployment workflow!

This wizard will guide you through:
- **Environment selection**
- **Component configuration**
- **Deployment verification**
content
Markdown content to render. Supports Go templates for dynamic content.

Output Step Types

spin

Displays a spinner while executing a command.

steps:
- name: building
type: spin
title: "Building application..."
command: "npm run build"
timeout: 60s
title
Text displayed next to the spinner
command
Shell command to execute
timeout
Maximum time for command execution (e.g., 30s, 5m)

table

Displays data in a formatted table.

steps:
- name: environments
type: table
title: "Available Environments"
columns:
- name
- region
- status
data:
- name: dev
region: us-east-1
status: active
- name: staging
region: us-west-2
status: active
title
Table title
columns
List of column names
data
Array of row objects with values for each column

join

Joins multiple strings together with a separator.

steps:
- name: combined
type: join
separator: ", "
options:
- "{{ .steps.header.value }}"
- "{{ .steps.body.value }}"
- "{{ .steps.footer.value }}"
options
Array of strings to join (supports templates)
separator
String to join values with (default: newline)
content
Alternative: single template string to resolve and return as-is

pager

Displays content in a scrollable pager.

steps:
- name: show_logs
type: pager
title: "Build Logs"
content: "{{ .steps.build.metadata.stdout }}"

Or load from a file:

steps:
- name: show_readme
type: pager
title: "README"
path: "./README.md"
markdown: true
title
Title displayed at the top of the pager
content
Content to display (supports templates)
path
Path to file to display (alternative to content)
markdown
Render content as markdown (default: auto-detect from .md/.markdown extension)

format

Formats and outputs text using Go templates.

steps:
- name: summary
type: format
content: |
Environment: {{ .steps.env.value }}
Components: {{ .steps.components.values | join ", " }}
content
Go template string to render and output

style

Applies terminal styling to content using lipgloss.

steps:
- name: banner
type: style
content: "Deployment Complete"
foreground: "#00ff00"
border: rounded
padding: "1 2"
bold: true
content
Text to style (supports templates)
foreground
Text color (hex or named)
background
Background color (hex or named)
border
Border style: normal, rounded, thick, double, hidden
border_foreground
Border color
padding
Padding (CSS-like: "1", "1 2", "1 2 1 2")
margin
Margin (CSS-like format)
width
Fixed width in characters
height
Fixed height in lines
align
Text alignment: left, center, right
bold
Bold text
italic
Italic text
underline
Underlined text
strikethrough
Strikethrough text
faint
Dimmed text
markdown
Render content as markdown before styling

linebreak

Outputs blank lines for visual spacing.

steps:
- name: spacer
type: linebreak
count: 2
count
Number of blank lines to output (default: 1)

log

Outputs structured log messages at various levels.

steps:
- name: debug_info
type: log
level: debug
content: "Processing component"
fields:
component: "{{ .steps.select.value }}"
stack: "{{ .env.ATMOS_STACK }}"
level
Log level: trace, debug, info, warn, error
content
Log message (supports templates)
fields
Structured key-value pairs to include

Terminal Step Types

Terminal step types control the terminal environment and workflow execution flow.

alert

Plays a terminal bell sound to notify the user. Useful at the end of long-running workflows.

steps:
- name: notify
type: alert
content: "Workflow complete!" # Optional message
content
Optional message to display after the bell (supports templates)
tip

Use alert at the end of long-running workflows to notify users when the workflow completes, even if they've switched to another window.

title

Sets the terminal window title. Useful for showing workflow progress in the title bar.

steps:
- name: set_title
type: title
content: "Deploying to {{ .steps.env.value }}..."

- name: deploy
type: atmos
command: terraform apply vpc

- name: restore_title
type: title # Empty content restores original title
content
Title text (supports templates). If empty, restores the original title.
note

Respects settings.terminal.title configuration. Some terminals may not support title changes.

clear

Clears the current terminal line. Useful for cleaning up dynamic output.

steps:
- name: clear_line
type: clear

No parameters required.

env

Sets environment variables for subsequent steps in the workflow.

steps:
- name: get_env
type: choose
prompt: "Select environment"
options: [dev, staging, prod]

- name: set_env
type: env
vars:
DEPLOY_ENV: "{{ .steps.get_env.value }}"
AWS_REGION: us-east-1
TF_VAR_environment: "{{ .steps.get_env.value }}"

- name: deploy
type: atmos
command: terraform apply vpc
vars
Map of environment variable names to values (supports templates)
tip

Use env to pass user input or computed values to subsequent shell/atmos commands as environment variables.

exit

Exits the workflow immediately with a specific exit code.

steps:
- name: confirm
type: confirm
prompt: "Continue with deployment?"

- name: abort
type: exit
code: 1
content: "Deployment cancelled by user"
code
Exit code (default: 0). Use non-zero for error conditions.
content
Optional message to display before exiting (supports templates)
warning

The exit step immediately terminates the workflow. No subsequent steps will run.

Variable Passing Between Steps

Steps can access previous step results using Go templates. Each step result is stored in .steps.<name>.

{{ .steps.<name>.value }}
Primary value from the step (string)
{{ .steps.<name>.values }}
Array of values (for multi-select steps)
{{ .steps.<name>.metadata.<key> }}
Metadata like exit_code, stdout, stderr
{{ .steps.<name>.skipped }}
Whether the step was skipped
{{ .steps.<name>.error }}
Error message if the step failed
{{ .env.<VAR> }}
Environment variables

Output Modes

Control how command output is displayed using the output field at the workflow or step level.

workflows:
verbose-deploy:
output: log # Workflow-level default
steps:
- name: plan
type: atmos
command: terraform plan vpc
output: viewport # Step-level override
viewport
Display output in a scrollable pager
raw
Direct passthrough to terminal (default)
log
Grouped output with step headers
none
Suppress output (check exit code only)

Show Configuration

Control automatic formatting and progress display using the show field at the workflow or step level. All options default to false (opt-in).

workflows:
verbose-deploy:
description: Deploy with full visibility
show:
header: true # Display workflow description as styled header
flags: true # Show command-line flags (stack, identity, etc.)
count: true # Show step count prefix [1/5]
command: true # Show step command before execution
progress: true # Show progress bar (TTY only)
steps:
- name: plan
type: atmos
command: terraform plan vpc
show:
command: false # Override: don't show command for this step
header
Display the workflow description as a styled header before the first step executes
flags
Show command-line flag values under the header (e.g., stack: dev, identity: prod-admin)
command
Show each step's command before execution with a $ prefix for shell-like appearance
count
Show step count prefix (e.g., [1/5]) in step headers
progress
Show a right-aligned progress bar during execution (Docker-build style, TTY only)

Step-level show settings override workflow-level defaults via deep merge. Only set fields are overridden; unset fields inherit from the workflow.

TTY Requirements

Interactive steps require a terminal (TTY) to function. In non-interactive environments like CI/CD:

  • Use --dry-run to preview workflow steps without execution
  • Set default values in your workflow configuration
  • Use environment variables instead of interactive prompts
  • Consider using conditional logic to skip interactive steps in CI
  • The progress show option only renders in TTY mode

Executing Workflow from a Named Step

Each workflow step can be given an arbitrary name (step's identifier) using the name attribute. For example:

workflows:
test-1:
description: "Test workflow"
steps:
- command: echo Command 1
name: step1
type: shell
- command: echo Command 2
name: step2
type: shell
- command: echo Command 3
name: step3
type: shell
- command: echo Command 4
type: shell

The step's name can be used in the --from-step command-line flag to start the workflow execution from the step.

For example, the following command will skip the first two steps and will start executing the workflow from step3:

atmos workflow test-1 -f workflow1 --from-step step3

This is useful when you want to restart the workflow from a particular step.

For example:

  • You run the workflow first time with the command atmos workflow test-1 -f workflow1
  • step1 and step2 succeed, but step3 fails
  • You fix the issue with the step3 command
  • You don't want to execute step1 and step2 again (to not spend time on it, or if they are not idempotent)
  • You run the command atmos workflow test-1 -f workflow1 --from-step step3 to restart the workflow from step3

If the name attribute in a workflow step is omitted, a friendly name will be generated for you consisting of a prefix of step and followed by the index of the step. The index starts with 1, so the first generated step name would be step1.

The test-1 workflow defined above does not have the name attribute for the last workflow step. When we execute the atmos workflow commands, Atmos automatically generates the names for the steps where the name attribute is omitted. In this case, the generated name for the last step will be step4.

For example:

atmos workflow test-1 -f workflow1 --from-step step4
Executing the workflow 'test-1' from 'stacks/workflows/workflow1.yaml'

description: Test workflow
steps:
- name: step1
command: echo Command 1
type: shell
- name: step2
command: echo Command 2
type: shell
- name: step3
command: echo Command 3
type: shell
- name: step4
command: echo Command 4
type: shell

Executing workflow step: echo Command 4

Executing command: echo Command 4
Command 4

Executing workflow step: echo Command 5

Executing command: echo Command 5
Command 5

Workflow Examples

The following workflow defines four steps of type atmos (implicit type) without specifying the workflow-level or step-level stack attribute. Since the workflow does not specify the stack, it's generic and can be executed for any Atmos stack. In this case, the stack needs to be provided on the command line.

workflows:
terraform-plan-all-test-components:
description: |
Run 'terraform plan' on 'test/test-component' and all its derived components.
The stack must be provided on the command line:
`atmos workflow terraform-plan-all-test-components -f workflow1 -s <stack>`
steps:
# Inline scripts are also supported
# Refer to https://yaml-multiline.info for more details
- type: shell
command: |
echo "Starting the workflow execution..."
read -p "Press any key to continue... " -n1 -s
- command: terraform plan test/test-component
- command: terraform plan test/test-component-override
- command: terraform plan test/test-component-override-2
- command: terraform plan test/test-component-override-3
- type: shell
command: >-
echo "All done!"

To run this workflow for the tenant1-ue2-dev stack, execute the following command:

atmos workflow terraform-plan-all-test-components -f workflow1 -s tenant1-ue2-dev

The following workflow executes terraform plan on test/test-component-override-2 component in all stacks. In this case, the stack is specified inline for each workflow command.

workflows:
terraform-plan-test-component-override-2-all-stacks:
description: Run 'terraform plan' on 'test/test-component-override-2' component in all stacks
steps:
- command: terraform plan test/test-component-override-2 -s tenant1-ue2-dev
- command: terraform plan test/test-component-override-2 -s tenant1-ue2-staging
- command: terraform plan test/test-component-override-2 -s tenant1-ue2-prod
- command: terraform plan test/test-component-override-2 -s tenant2-ue2-dev
- command: terraform plan test/test-component-override-2 -s tenant2-ue2-staging
- command: terraform plan test/test-component-override-2 -s tenant2-ue2-prod
- type: shell
command: echo "All done!"

To run this workflow, execute the following command:

atmos workflow terraform-plan-test-component-override-2-all-stacks -f workflow1

The following workflow is similar to the above, but the stack for each command is specified in the step-level stack attribute.

workflows:
terraform-plan-test-component-override-3-all-stacks:
description: Run 'terraform plan' on 'test/test-component-override-3' component in all stacks
steps:
- command: terraform plan test/test-component-override-3
stack: tenant1-ue2-dev
- command: terraform plan test/test-component-override-3
stack: tenant1-ue2-staging
- command: terraform plan test/test-component-override-3
stack: tenant1-ue2-prod
- command: terraform plan test/test-component-override-3
stack: tenant2-ue2-dev
- command: terraform plan test/test-component-override-3
stack: tenant2-ue2-staging
- command: terraform plan test/test-component-override-3
stack: tenant2-ue2-prod

To run this workflow, execute the following command:

atmos workflow terraform-plan-test-component-override-3-all-stacks -f workflow1

Working with Atmos Stacks in Workflows

The Atmos stack used by the workflow commands of type atmos can be specified in four different ways:

Inline in the command itself

steps:
- command: terraform plan test/test-component-override-2 -s tenant1-ue2-dev

In the workflow-level stack attribute

workflows:
my-workflow:
stack: tenant1-ue2-dev
steps:
- command: terraform plan test/test-component

In the step-level stack attribute

steps:
- command: terraform plan test/test-component
stack: tenant1-ue2-dev

On the command line

atmos workflow my-workflow -f workflow1 -s tenant1-ue2-dev

Workflow Failure Handling and Resuming

When a workflow step fails, Atmos will:

  1. Display which step failed
  2. Show the exact command that failed
  3. Provide a ready-to-use command to resume the workflow from the failed step

Given this workflow:

stacks/workflows/networking.yaml
workflows:
provision-vpcs:
description: "Deploy vpc components"
steps:
- command: terraform plan vpc -s plat-ue2-dev
name: step-1
- command: terraform plan vpc -s plat-ue2-staging
name: step-2
- command: terraform plan vpc -s plat-ue2-prod
name: step-3

If step-2 fails, you'll see:

Step 'step-2' failed!

Command failed:
terraform plan vpc -s plat-ue2-staging

To resume the workflow from this step, run:
atmos workflow provision-vpcs -f networking --from-step step-2

Stack Precedence

The stack defined inline in the command itself has the lowest priority, it can and will be overridden by any other stack definition. The step-level stack will override the workflow-level stack. The command line --stack option will override all other stacks defined in the workflow itself. You can also use any combinations of the above (e.g. specify the stack at the workflow level, then override it at the step level for some commands, etc.).

While this provides a great flexibility in defining the stack for workflow commands, we recommend creating generic workflows without defining stacks in the workflow itself (the stack should be provided on the command line). This way, the workflow can be executed for any stack without any modifications and without dealing with multiple workflows that are similar but differ only by the environment where the resources are provisioned.

Using Authentication with Workflows

Workflow steps can specify an identity to authenticate before execution. This is useful when different steps require different levels of access or need to operate under different cloud accounts.

When an identity is specified, Atmos will:

  1. Authenticate using the specified identity (prompting for MFA if required)
  2. Write temporary credentials to a file
  3. Set environment variables pointing to the credential files (AWS_SHARED_CREDENTIALS_FILE, AWS_CONFIG_FILE, AWS_PROFILE, etc.)
  4. Execute the command with these environment variables

Example: Workflow with Authentication

stacks/workflows/deploy.yaml
workflows:
deploy-with-auth:
description: Deploy infrastructure with different identities
steps:
# Deploy foundation resources as superadmin
- command: terraform apply vpc -s plat-ue2-prod
identity: superadmin
name: deploy-vpc

# Deploy application resources as developer
- command: terraform apply app -s plat-ue2-prod
identity: developer
name: deploy-app

# Run a shell script with authentication
- command: |
echo "Current AWS identity:"
aws sts get-caller-identity
type: shell
identity: superadmin
name: verify-identity

To execute this workflow:

atmos workflow deploy-with-auth -f deploy

Mixed Authentication

Different steps can use different identities, or no identity at all:

stacks/workflows/mixed-auth.yaml
workflows:
mixed-auth-workflow:
description: Workflow with mixed authentication
steps:
# Step without authentication (uses ambient credentials)
- command: terraform plan vpc -s plat-ue2-dev
name: plan-without-auth

# Step with superadmin identity
- command: terraform apply vpc -s plat-ue2-prod
identity: superadmin
name: apply-with-superadmin

# Step with different identity
- command: terraform apply monitoring -s plat-ue2-prod
identity: monitoring-admin
name: apply-with-monitoring-admin
tip

Configure identities in your atmos.yaml under the auth section. See the Authentication documentation for configuration details.

Setting a Default Identity for All Steps

You can use the --identity flag to set a default identity for all workflow steps that don't specify their own:

# Apply superadmin identity to all steps without their own identity
atmos workflow deploy-all -f workflows --identity superadmin

Precedence: Step-level identity field > --identity flag > no authentication

Example:

workflows:
deploy-mixed:
steps:
# This step uses the --identity flag value (if provided)
- command: terraform plan vpc
name: plan-vpc

# This step ALWAYS uses developer identity (overrides --identity flag)
- command: terraform apply app
identity: developer
name: apply-app

# This step uses the --identity flag value (if provided)
- command: terraform apply monitoring
name: apply-monitoring

Running atmos workflow deploy-mixed -f workflows --identity superadmin will:

  • Execute plan-vpc step as superadmin
  • Execute apply-app step as developer (step-level identity overrides)
  • Execute apply-monitoring step as superadmin

Using Toolchain Tools

Workflows automatically have access to tools defined in your project's .tool-versions file. The toolchain ensures the correct versions are installed and available in PATH when your workflow executes.

Automatic Tool Access

If your project has a .tool-versions file:

terraform 1.10.0
kubectl 1.32.0
helm 3.16.0

Workflow steps can use these tools directly:

stacks/workflows/deploy.yaml
workflows:
deploy:
description: Deploy infrastructure
steps:
# Atmos commands (type: atmos is implicit)
- name: plan-vpc
command: terraform plan vpc
- name: apply-vpc
command: terraform apply vpc -auto-approve

# Shell commands for non-Atmos tools
- name: apply-k8s
command: kubectl apply -f manifests/
type: shell

When the workflow runs:

  1. Atmos reads .tool-versions to identify required tools
  2. Missing tools are automatically installed
  3. PATH is updated to include toolchain binaries
  4. Workflow steps execute with the correct tool versions

Declaring Workflow Dependencies

Use the dependencies field at the workflow level to require additional tools or override versions from .tool-versions:

stacks/workflows/validate.yaml
workflows:
validate:
description: Validate infrastructure
dependencies:
tools:
tflint: "^0.54.0"
checkov: "latest"
steps:
# Atmos command (type: atmos is implicit)
- name: validate
command: terraform validate vpc

# Shell commands for toolchain tools
- name: lint
command: tflint --recursive
type: shell
- name: security
command: checkov -d .
type: shell

Dependencies declared in the workflow take precedence over .tool-versions.

Version Constraints

Dependencies support SemVer constraints:

ConstraintMeaningExample
1.10.3Exact versionOnly version 1.10.3
~> 1.10.0Pessimistic (patch)Includes 1.10.x but not 1.11.0
^1.10.0Compatible (minor)Includes 1.x.x but not 2.0.0
latestLatest availableMost recent version
tip

Use .tool-versions for project-wide tool defaults and workflow dependencies for workflow-specific version requirements. This gives you flexibility while maintaining consistency across your team.

Try It

Explore working examples that demonstrate workflows in action.

Example: Demo Workflows

Run multiple Atmos commands in sequence with a single command.

Learn more about Workflows.

What You'll See

  • Workflow definitions in stack manifests
  • Chaining multiple atmos terraform commands
  • Parameterized workflows with arguments

Try It

cd examples/demo-workflows

# List available workflows
atmos workflow list

# Run a workflow
atmos workflow deploy -s dev

Key Files

FilePurpose
atmos.yamlConfigures workflow base path
stacks/workflows/Workflow definitions

Interactive Workflows Demo

This example demonstrates Atmos's powerful interactive workflow step types. These step types enable building sophisticated CLI wizards and interactive deployment pipelines.

Prerequisites

  • Atmos CLI installed
  • Terminal with TTY support (interactive mode)

Quick Start

cd examples/interactive-workflows

# Run the main deployment workflow
atmos workflow deploy -f interactive

# Run the component selection workflow
atmos workflow select-components -f interactive

# Run the full deployment pipeline
atmos workflow full-deploy -f interactive

Available Workflows

deploy

Basic deployment wizard that:

  • Displays a markdown welcome message
  • Prompts for environment selection
  • Shows confirmation for production
  • Collects deployment notes
  • Displays a summary

select-components

Multi-select workflow demonstrating:

  • Filter step with multiple selection
  • Variable passing to show selection count

select-config

File picker workflow that:

  • Scans for YAML/JSON files
  • Displays file selection UI
  • Shows the selected file path

credentials

Secure input workflow with:

  • Warning message
  • Username input
  • Password input (masked)

write-notes

Text editor workflow:

  • Multi-line text input
  • Markdown rendering of notes

build

Spinner workflow that:

  • Shows progress during command execution
  • Displays success message

show-environments

Table display workflow:

  • Renders structured data as table
  • Custom columns

format-output

Output formatting workflow:

  • Join array values with separator
  • Display formatted result

full-deploy

Complete pipeline combining:

  • Markdown intro
  • Environment selection
  • Multi-component selection
  • Notes collection
  • Confirmation
  • Summary display

Step Types Demonstrated

TypeDescriptionExample Usage
markdownRender markdown contentWelcome messages, documentation
chooseSingle selection from listEnvironment selection
filterFilterable selection (single/multi)Component selection
inputSingle-line text inputNames, messages
confirmYes/No confirmationProduction safeguards
writeMulti-line text editorNotes, descriptions
fileFile pickerConfig file selection
toastStyled message with iconStatus updates, completion notices
spinSpinner with commandLong-running tasks
tableTabular data displayEnvironment lists
joinJoin array to stringFormat selections
logStructured loggingDebugging, monitoring
styleStyled text with bordersSummary boxes

Variable Passing

Steps can access previous step results using Go templates:

steps:
- name: select_env
type: choose
prompt: "Select environment"
options: [dev, staging, prod]

- name: show_env
type: toast
level: info
content: "You selected: {{ .steps.select_env.value }}"

Available Template Variables

  • {{ .steps.<name>.value }} - Primary value from step
  • {{ .steps.<name>.values }} - Array of values (multi-select)
  • {{ .steps.<name>.metadata.<key> }} - Metadata (exit_code, stdout, stderr)
  • {{ .steps.<name>.skipped }} - Whether step was skipped
  • {{ .steps.<name>.error }} - Error message if failed
  • {{ .env.<VAR> }} - Environment variables

Output Modes

Control how command output is displayed:

workflows:
my-workflow:
output: log # log | raw | viewport | none
steps:
- name: step1
type: shell
command: "echo hello"
output: viewport # Step-level override

CI/CD Considerations

Interactive steps require a TTY. In CI environments:

  • Use --dry-run to preview workflows
  • Set default values in configuration
  • Use environment variables instead of prompts.