Atmos Custom Command YAML Syntax Reference
Complete reference for all fields in the commands section of atmos.yaml.
Top-Level Structure
Custom commands are defined as a list under the commands key in atmos.yaml:
# atmos.yamlcommands:- name: command-1description: "First command"steps:- "echo hello"- name: command-2description: "Second command"steps:- "echo world"
Command Definition Fields
commands:- name: string # Required: Command namedescription: string # Optional: Help text descriptionverbose: boolean # Optional: Print commands before execution (default: true)identity: string # Optional: Authentication identity nameworking_directory: string # Optional: Working directory for stepsarguments: [] # Optional: Positional argumentsflags: [] # Optional: Named flagsenv: [] # Optional: Environment variablescomponent_config: # Optional: Component configuration accesscomponent: stringstack: stringdependencies: # Optional: Tool dependenciestools: {}commands: [] # Optional: Nested subcommandssteps: [] # Required (unless has subcommands): Execution steps
name (Required)
The command name as used on the command line. Must be unique among sibling commands.
- name: hello# Usage: atmos hello- name: set-eks-cluster# Usage: atmos set-eks-cluster
For nested subcommands, the name forms the command path:
- name: terraformcommands:- name: provision# Usage: atmos terraform provision
Multi-word names are also supported:
- name: ansible run# Usage: atmos ansible run
description (Optional)
Human-readable description shown in atmos help and atmos <command> --help.
Supports multiline YAML strings.
- name: deploydescription: |Deploy infrastructure components.Example usage:atmos deploy vpc -s plat-ue2-devatmos deploy eks/cluster -s plat-ue2-prod
verbose (Optional)
Controls whether step commands are printed before execution. Default: true.
- name: set-eks-clusterverbose: false # Suppress command echo
identity (Optional)
Authentication identity to use before executing steps. Atmos authenticates and sets up credential environment variables for all steps.
- name: deploy-infraidentity: superadmin
Override at runtime with --identity <name> or skip with --identity "".
The --identity flag is automatically added to all custom commands.
working_directory (Optional)
Working directory where steps execute.
- name: buildworking_directory: !repo-root . # Git repository root# Or:working_directory: /tmp # Absolute pathworking_directory: scripts/build # Relative to base_path
Path resolution rules:
- Absolute paths are used as-is
- Relative paths resolve against the Atmos
base_path !repo-rootor!repo-root .resolves to the git repository root
Arguments
Positional arguments are defined as a list under arguments:
arguments:- name: string # Required: Argument namedescription: string # Optional: Help textrequired: boolean # Optional: Whether argument is required (default: false)default: string # Optional: Default value if not provided
Access in Templates
Arguments are accessed via {{ .Arguments.<name> }}:
arguments:- name: componentdescription: Component namerequired: truesteps:- "echo Component: {{ .Arguments.component }}"
Required vs Optional
If required: true and no value is provided, the command fails unless a default is specified.
arguments:- name: namedescription: Name to greetrequired: truedefault: "John Doe" # Used when argument is omitted
Multiple Arguments
Arguments are positional and matched in order:
arguments:- name: componentdescription: Component namerequired: true- name: environmentdescription: Target environmentdefault: dev
atmos mycommand vpc staging # component=vpc, environment=stagingatmos mycommand vpc # component=vpc, environment=dev (default)
Flags
Named flags are defined as a list under flags:
flags:- name: string # Required: Flag name (used as --name)shorthand: string # Optional: Single-character shorthand (used as -x)description: string # Optional: Help textrequired: boolean # Optional: Whether flag is required (default: false)type: string # Optional: "bool" for boolean flags (default: string)default: string|bool # Optional: Default value
Access in Templates
Flags are accessed via {{ .Flags.<name> }}:
flags:- name: stackshorthand: sdescription: Stack namerequired: true- name: verbosetype: booldefault: falsesteps:- "echo Stack: {{ .Flags.stack }}"- |{{ if .Flags.verbose }}echo "Verbose mode"{{ end }}
String Flags
flags:- name: environmentshorthand: edescription: Target environmentrequired: true- name: regionshorthand: rdescription: AWS regiondefault: us-east-1
atmos mycommand --environment prod --region us-west-2atmos mycommand -e prod -r us-west-2
Boolean Flags
Boolean flags are declared with type: bool. When present on the command line without a value,
they are set to true. They render as lowercase true or false in templates.
flags:- name: dry-runshorthand: dtype: booldescription: Dry run mode- name: forcetype: booldefault: falsedescription: Force operation- name: auto-approvetype: booldefault: truedescription: Auto-approve changes
atmos mycommand --dry-run # dry-run=trueatmos mycommand -d # dry-run=trueatmos mycommand --auto-approve=false # auto-approve=false (explicit override)
Flag Defaults
Both string and boolean flags support defaults:
flags:- name: environmentdefault: "development" # String default- name: forcetype: booldefault: false # Boolean default- name: auto-approvetype: booldefault: true # Boolean default (true)
Trailing Arguments
Arguments after -- on the command line are accessible via {{ .TrailingArgs }}:
- name: ansible runarguments:- name: playbookdefault: site.ymlrequired: truesteps:- "ansible-playbook {{ .Arguments.playbook }} {{ .TrailingArgs }}"
atmos ansible run -- --limit web --check# Runs: ansible-playbook site.yml --limit web --check
Environment Variables
The env section defines environment variables available to all steps. Values support
Go template syntax.
env:NAME: string # Value supports Go templates
Examples
env:ATMOS_COMPONENT: "{{ .Arguments.component }}"ATMOS_STACK: "{{ .Flags.stack }}"AWS_REGION: "{{ .ComponentConfig.vars.region }}"KUBECONFIG: "/dev/shm/kubecfg.{{ .Flags.stack }}-{{ .Flags.role }}"
Environment variables are accessible in steps as standard shell variables ($ATMOS_COMPONENT).
Component Config
The component_config section instructs Atmos to resolve the full configuration for a component
in a stack. This makes all component sections available via {{ .ComponentConfig }}.
component_config:component: string # Required: Component name (supports Go templates)stack: string # Required: Stack name (supports Go templates)
Usage
component_config:component: "{{ .Arguments.component }}"stack: "{{ .Flags.stack }}"
Available Fields
After resolution, the following are available:
| Template Variable | Description |
|---|---|
{{ .ComponentConfig.component }} | Terraform component path |
{{ .ComponentConfig.backend }} | Backend configuration map |
{{ .ComponentConfig.backend.bucket }} | Backend bucket name |
{{ .ComponentConfig.backend.region }} | Backend region |
{{ .ComponentConfig.workspace }} | Computed workspace name |
{{ .ComponentConfig.vars }} | All component variables |
{{ .ComponentConfig.vars.namespace }} | Namespace variable |
{{ .ComponentConfig.vars.tenant }} | Tenant variable |
{{ .ComponentConfig.vars.environment }} | Environment variable |
{{ .ComponentConfig.vars.stage }} | Stage variable |
{{ .ComponentConfig.vars.region }} | Region variable |
{{ .ComponentConfig.settings }} | Component settings |
{{ .ComponentConfig.env }} | Environment variable config |
{{ .ComponentConfig.metadata }} | Component metadata |
{{ .ComponentConfig.deps }} | Component dependencies |
Dependencies
Declare tool dependencies auto-installed before execution:
dependencies:tools:tool-name: "version"
Version Formats
| Format | Meaning | Example |
|---|---|---|
"1.10.3" | Exact version | Only 1.10.3 |
"~> 1.10.0" | Pessimistic (patch) | 1.10.x but not 1.11.0 |
"^1.10.0" | Compatible (minor) | 1.x.x but not 2.0.0 |
"latest" | Latest available | Most recent version |
Example
dependencies:tools:tflint: "0.54.0"checkov: "3.0.0"tfsec: "1.28.0"
Tools are installed to the configured toolchain.install_path and resolved via configured registries.
Nested Subcommands
Commands can contain nested commands for hierarchical structures:
commands:- name: listdescription: List resourcescommands:- name: stacksdescription: List all stackssteps:- atmos describe stacks --sections=none | grep -e "^\S" | sed s/://g- name: componentsdescription: List componentsflags:- name: stackshorthand: sdescription: Stack namesteps:- >{{ if .Flags.stack }}atmos describe stacks --stack={{ .Flags.stack }} --format=json --sections=none |jq ".[].components.terraform" | jq -s add | jq -r "keys[]"{{ else }}atmos describe stacks --format=json --sections=none |jq ".[].components.terraform" | jq -s add | jq -r "keys[]"{{ end }}
atmos list stacksatmos list components -s plat-ue2-dev
Nesting can go multiple levels deep.
Steps (Required)
Steps are the work to execute. String steps are shorthand for simple shell commands. For anything with output, prompts, orchestration, container actions, CI behavior, or nontrivial control flow, use structured steps with the same native step types supported by workflows.
steps:- type: atmoscommand: terraform plan {{ .Arguments.component }} -s {{ .Flags.stack }}- type: shellcommand: |if [ "{{ .Flags.verbose }}" = "true" ]; thenecho "Checking {{ .Arguments.component }} in {{ .Flags.stack }}"fi./scripts/check-plan.sh "{{ .Arguments.component }}" "{{ .Flags.stack }}"- type: toastlevel: successcontent: Plan complete
Steps execute sequentially. If a step fails, subsequent steps are not executed.
Go templates work in both structured steps and shell scripts, so flags and arguments can still be
passed into scripts with {{ .Flags.<name> }} and {{ .Arguments.<name> }}. The point is not to
ban shell; it is to keep shell steps focused on script logic and use native steps for Atmos commands,
output rendering, orchestration, and CI-aware behavior.
Large multiline shell steps and repeated echo statements are a maintainability warning. Prefer
atmos for Atmos commands, toast/markdown/table/pager/format/log for user-facing output,
parallel/matrix/wait for orchestration, and container/emulator/http for native operations.
Shell is still valid for short glue commands, external CLIs, terminal-native sessions, or checked-in
scripts.
Go Template Functions Available
| Expression | Description |
|---|---|
{{ .Arguments.<name> }} | Positional argument value |
{{ .Flags.<name> }} | Flag value |
{{ .TrailingArgs }} | Arguments after -- |
{{ .ComponentConfig.<path> }} | Resolved component config |
{{ if .Flags.name }}...{{ end }} | Conditional block |
{{ if not .Flags.name }}...{{ end }} | Negated conditional |
{{ if eq .Flags.type "value" }}...{{ end }} | Equality check |
{{ else if eq .Flags.type "other" }} | Else-if branch |
{{ else }} | Else branch |
Complete Example
# atmos.yamlcommands:- name: deploy-stackdescription: |Deploy all components in a stack in the correct order.Example:atmos deploy-stack -s plat-ue2-devatmos deploy-stack -s plat-ue2-prod --dry-runidentity: infrastructure-adminflags:- name: stackshorthand: sdescription: Target stackrequired: true- name: dry-runshorthand: dtype: booldescription: Preview without applyingdefault: false- name: verboseshorthand: vtype: booldescription: Verbose outputdefault: falsedependencies:tools:terraform: "^1.10.0"env:DEPLOY_STACK: "{{ .Flags.stack }}"steps:- |{{ if .Flags.verbose }}echo "Deploying stack: {{ .Flags.stack }}"echo "Dry run: {{ .Flags.dry-run }}"{{ end }}- |{{ if .Flags.dry-run }}echo "DRY RUN: Would deploy vpc to {{ .Flags.stack }}"echo "DRY RUN: Would deploy eks/cluster to {{ .Flags.stack }}"echo "DRY RUN: Would deploy app to {{ .Flags.stack }}"{{ else }}atmos terraform deploy vpc -s {{ .Flags.stack }}atmos terraform deploy eks/cluster -s {{ .Flags.stack }}atmos terraform deploy app -s {{ .Flags.stack }}{{ end }}
atmos deploy-stack -s plat-ue2-devatmos deploy-stack -s plat-ue2-prod --dry-runatmos deploy-stack -s plat-ue2-dev --verbose