Skip to main content

Unified Task Runner for Custom Commands

· 2 min read
Erik Osterman
Founder @ Cloud Posse

Custom commands now support structured task syntax with per-step configuration including timeouts, retry logic, working directories, and authentication identities.

What Changed​

We've introduced a new pkg/runner package that provides a unified task execution layer for custom commands. This enables structured syntax alongside the existing simple string syntax:

Simple syntax (still works):

commands:
- name: hello
steps:
- "echo Hello world!"
- "echo Goodbye!"

New structured syntax:

commands:
- name: deploy
steps:
- name: validate
command: terraform validate
timeout: 30s
- name: apply
command: terraform apply -auto-approve
timeout: 10m
working_directory: /app/infra

Mixed syntax:

commands:
- name: build
steps:
- "echo Starting build..."
- name: compile
command: make build
timeout: 5m
- "echo Build complete!"

With retry for flaky operations:

commands:
- name: sync
steps:
- name: upload
command: aws s3 sync ./dist s3://mybucket
retry:
max_attempts: 3
initial_delay: 1s
max_delay: 30s

Using atmos commands with identity:

commands:
- name: deploy-all
steps:
- name: deploy-vpc
command: terraform apply vpc
type: atmos
stack: prod-us-east-1
identity: production-deployer
timeout: 15m

Why This Matters​

This change lays the groundwork for unifying custom commands and workflows under a shared execution model. The new Task type supports:

  • Timeouts - Prevent runaway commands with per-step time limits
  • Working directories - Execute steps in specific directories
  • Task types - shell (default) for shell commands, atmos for atmos CLI commands with stack support
  • Retry configuration - Built-in retry support with configurable attempts and backoff delays
  • Identity - Per-step authentication identity for multi-account deployments
  • Stack - Specify which stack to use for atmos type commands

For Contributors​

The new pkg/runner package provides:

  • Task and Tasks types with flexible YAML unmarshaling
  • CommandRunner interface for testable command execution
  • Run() and RunAll() functions with context-based timeout enforcement
  • Full mapstructure decode hook support for Viper integration

This is an internal architectural improvement with full backward compatibility for existing custom command configurations.

Try it out​

Copy the example into a new directory and make it your own:

atmos init examples/custom-commands
cd custom-commands

Run a local custom command; no cloud account is needed.

atmos hello

For more details, see the Custom Commands documentation.

For usage and configuration, see steps.