Atmos Automation Language
Write your build, test, and deployment process in the Atmos Automation Language, a Python-like language based on Starlark. Compose Atmos capabilities with your own functions and run the same automation locally and in CI, for applications and infrastructure.
Atmos executes your code as a standalone .star program or as a script step
in a custom command, workflow, or lifecycle hook. Run a file with
atmos ./my-tool.star. For an inline YAML script step, set
type: script and interpreter: starlark. The interpreter and built-in functions
ship with Atmos.
This page introduces the language and how Atmos runs it. For complete syntax and data types, see the language reference.
Why Starlark?
Starlark provides functions, loops, conditions, and structured data with Python-like syntax. You can pass a component's configuration between functions, inspect a command result, and test a calculation without converting everything to shell text. Shared functions let your release process grow without copying logic between Bash scripts and CI jobs.
Its smaller feature set gives teams fewer language features to learn when writing and reviewing automation. It is a separate language: Atmos scripts do not run arbitrary Python code or import Python packages.
Atmos supplies functions for reading files, running commands, and working with component configuration. These built-ins use the same interfaces in standalone scripts, workflow steps, custom commands, and hooks. Scripts that use only the built-ins need no separate Python or Node.js installation; commands they launch still need their own tools and credentials.
Calculations using only their supplied inputs produce repeatable results. Values shared with parallel tasks are frozen so those tasks cannot change shared state. File reads and subprocess results still depend on the environment, so an entire automation script is not necessarily deterministic. The interpreter is not a security boundary for untrusted scripts.
See Starlark's design principles for the language's design rationale.
Syntax and values
Write functions, conditions, loops, lists, and dictionaries using familiar Python-like syntax:
def capacity(replicas, workers_per_replica):
if replicas < 1:
fail("replicas must be positive")
return replicas * workers_per_replica
print("Total workers: {}".format(capacity(3, 4)))
This prints Total workers: 12. Use fail(message) to stop a script with an
error. Atmos reports the source location and traceback. Use
sum() to total numbers and
round() to round a result.
The runtime supports top-level conditionals and loops, while, set(), and
recursive functions. It does not run arbitrary Python programs or import Python
packages. Use the built-in modules below and load() for shared Starlark code.
Module-level names cannot be reassigned. Compute a changing value inside a function or mutate a list or dictionary before dispatching parallel work. Values reachable by parallel tasks become immutable when dispatched. See the detailed language behavior.
Inputs depend on the entry point
| Where the program runs | How it receives inputs |
|---|---|
| Custom CLI app | cli.command parses declarations and calls main(args, flags); ctx.args provides raw script arguments. |
| Custom Atmos command | ctx.flags and ctx.arguments contain parsed inputs from the command's YAML declarations. |
| Workflow step | env contains explicitly declared step inputs; the workflow supplies its execution environment. |
| Lifecycle hook | ctx.component, ctx.hook, and ctx.operation describe the component and operation. |
ctx.flags and ctx.arguments are read-only dictionaries. Use parsed inputs
directly instead of interpolating them into script source or mapping each flag
to an environment variable.
Built-in helpers
| Helper | Purpose |
|---|---|
cli.command, cli.arg, cli.flag | Declare a standalone program's interface, validate inputs, and invoke its callback. |
atmos.run, atmos.terraform, atmos.helm, atmos.toolchain, and one wrapper per command, such as atmos.vendor | Invoke registered Atmos commands, including Terraform, Helm, and project commands through atmos.run. |
components.get | Resolve component configuration for a named component and stack. |
exec.run | Run an external program with an argument list and capture its result. |
steps.task, steps.parallel | Describe function calls, execute concurrent work, and apply retries and timeouts. |
fs.read_file | Read a local file as text. |
json.encode, json.decode | Convert between structured values and JSON text. |
regex.search, regex.findall, regex.replace | Match and transform text using regular expressions. |
dependencies.tools | Request tools through Atmos's toolchain integration. |
ui.info, ui.success, ui.warning | Write status messages for the person running the program. |
errors.build | Raise actionable errors with Atmos's explanations, hints, examples, context, and exit codes. |
log.trace, log.debug, log.info, log.warn, log.error | Emit diagnostics at the configured Atmos log level. |
The automation functions reference documents every helper and built-in value with its signature, arguments, return value, and examples. The script API reference also details call signatures, return values, and failure behavior. The Atmos command reference explains command arguments and flags.
Data, status, and diagnostics
Use print() for data on stdout, ui.info(), ui.success(), and ui.warning()
for status on stderr, and log.debug() or other log levels for diagnostics.
Assign the top-level output variable to return a step value. Strings are used
as written; other values must be JSON-encodable. Without output, a script
step uses captured stdout as its value. Status and diagnostic output do not
become the step value.
Output streams while the program runs. When masking is enabled, Atmos masks registered secrets and matches for configured masking patterns in displayed output. Log messages respect the configured log level and can include structured fields. See output and logging.
Use errors.build to give failures the same
presentation as Atmos's own errors. Add an explanation, recovery hints, and an
example before calling .fail(). These errors follow Atmos's normal reporting
path, including Sentry when configured.
Call the step library directly from scripts:
steps.input(prompt = "Service?", default = "api").value returns an input value.
The same module exposes choice and confirmation prompts, HTTP requests, container
operations, archives, and the other registered step handlers. Calls return values,
metadata, and named outputs that you can pass to the next operation.
You can also combine YAML prompts and script steps in a workflow or custom command. See prompts and step outputs.
Files and shared code
Use load("helpers.star", "function_name") to load reusable functions. For a
program read from a file, module paths resolve relative to that file. For an
inline YAML script, they resolve relative to the step's working directory.
fs.read_file and exec.run use the step's working directory. A component's
exec method defaults to the component directory. See
file resolution for YAML includes,
symlinks, and source paths.
Execution controls
Use steps.task to attach arguments, retries, and a timeout to a function call.
Use steps.parallel to run a collection of tasks with a concurrency limit.
Results retain input order. A retry runs the entire function again, so use it
for operations that are safe to repeat.
Workflow dry runs parse embedded script steps without executing their code,
starting child processes, or installing tools. The embedded interpreter runs
inside Atmos; script steps using interpreter: starlark cannot run inside an
enabled container. See workflow integration and
execution restrictions.
Test program behavior
Use conditions and fail() to express assertions in the same language as your
automation. With exec.run(..., check=False, output="capture"), inspect a
command's exit code, stdout, and stderr before deciding whether it met the
expectation. A process that cannot start still raises an error.
Put these checks in a test step to collect results and display failures. See
testing automation for a runnable suite.
Build with the language
- Custom CLI apps: declare your own executable's interface.
- Custom commands: add project-specific subcommands to Atmos.
- Workflows: combine programs and other step types into a runbook.
- Lifecycle hooks: attach checks and actions to component operations.
Compute stack configuration
Use !starlark in stack manifests to compute typed
values from the merged component context. These blocks use return and a
read-only ctx object; see the YAML function reference for the available
builtins and evaluation order.