Skip to main content
command-syntax.md14.2 KB
View on GitHub

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.yaml
commands:
- name: command-1
description: "First command"
steps:
- "echo hello"

- name: command-2
description: "Second command"
steps:
- "echo world"

Command Definition Fields

commands:
- name: string # Required: Command name
description: string # Optional: Help text description
verbose: boolean # Optional: Print commands before execution (default: true)
identity: string # Optional: Authentication identity name
working_directory: string # Optional: Working directory for steps
arguments: [] # Optional: Positional arguments
flags: [] # Optional: Named flags
env: [] # Optional: Environment variables
component_config: # Optional: Component configuration access
component: string
stack: string
dependencies: # Optional: Tool dependencies
tools: {}
commands: [] # Optional: Nested subcommands
steps: [] # 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: terraform
commands:
- 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: deploy
description: |
Deploy infrastructure components.

Example usage:
atmos deploy vpc -s plat-ue2-dev
atmos deploy eks/cluster -s plat-ue2-prod

verbose (Optional)

Controls whether step commands are printed before execution. Default: true.

- name: set-eks-cluster
verbose: 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-infra
identity: 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: build
working_directory: !repo-root . # Git repository root
# Or:
working_directory: /tmp # Absolute path
working_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-root or !repo-root . resolves to the git repository root

Arguments

Positional arguments are defined as a list under arguments:

arguments:
- name: string # Required: Argument name
description: string # Optional: Help text
required: 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: component
description: Component name
required: true
steps:
- "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: name
description: Name to greet
required: true
default: "John Doe" # Used when argument is omitted

Multiple Arguments

Arguments are positional and matched in order:

arguments:
- name: component
description: Component name
required: true
- name: environment
description: Target environment
default: dev
atmos mycommand vpc staging # component=vpc, environment=staging
atmos 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 text
required: 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: stack
shorthand: s
description: Stack name
required: true
- name: verbose
type: bool
default: false
steps:
- "echo Stack: {{ .Flags.stack }}"
- |
{{ if .Flags.verbose }}
echo "Verbose mode"
{{ end }}

String Flags

flags:
- name: environment
shorthand: e
description: Target environment
required: true
- name: region
shorthand: r
description: AWS region
default: us-east-1
atmos mycommand --environment prod --region us-west-2
atmos 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-run
shorthand: d
type: bool
description: Dry run mode
- name: force
type: bool
default: false
description: Force operation
- name: auto-approve
type: bool
default: true
description: Auto-approve changes
atmos mycommand --dry-run # dry-run=true
atmos mycommand -d # dry-run=true
atmos mycommand --auto-approve=false # auto-approve=false (explicit override)

Flag Defaults

Both string and boolean flags support defaults:

flags:
- name: environment
default: "development" # String default
- name: force
type: bool
default: false # Boolean default
- name: auto-approve
type: bool
default: true # Boolean default (true)

Trailing Arguments

Arguments after -- on the command line are accessible via {{ .TrailingArgs }}:

- name: ansible run
arguments:
- name: playbook
default: site.yml
required: true
steps:
- "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 VariableDescription
{{ .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

FormatMeaningExample
"1.10.3"Exact versionOnly 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 availableMost 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: list
description: List resources
commands:
- name: stacks
description: List all stacks
steps:
- atmos describe stacks --sections=none | grep -e "^\S" | sed s/://g
- name: components
description: List components
flags:
- name: stack
shorthand: s
description: Stack name
steps:
- >
{{ 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 stacks
atmos 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: atmos
command: terraform plan {{ .Arguments.component }} -s {{ .Flags.stack }}
- type: shell
command: |
if [ "{{ .Flags.verbose }}" = "true" ]; then
echo "Checking {{ .Arguments.component }} in {{ .Flags.stack }}"
fi
./scripts/check-plan.sh "{{ .Arguments.component }}" "{{ .Flags.stack }}"
- type: toast
level: success
content: 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

ExpressionDescription
{{ .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.yaml
commands:
- name: deploy-stack
description: |
Deploy all components in a stack in the correct order.

Example:
atmos deploy-stack -s plat-ue2-dev
atmos deploy-stack -s plat-ue2-prod --dry-run
identity: infrastructure-admin
flags:
- name: stack
shorthand: s
description: Target stack
required: true
- name: dry-run
shorthand: d
type: bool
description: Preview without applying
default: false
- name: verbose
shorthand: v
type: bool
description: Verbose output
default: false
dependencies:
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-dev
atmos deploy-stack -s plat-ue2-prod --dry-run
atmos deploy-stack -s plat-ue2-dev --verbose