!starlark
Compute configuration values with the Atmos Automation Language. Use functions, conditions, and loops to derive tags, names, lists, and maps from the component's merged configuration.
Usage
Write a function body inside a !starlark YAML scalar. Use return to supply the
value that replaces it:
vars:
stage: dev
region: us-east-2
resource_tags: !starlark |
return {
"Environment": ctx.vars["stage"],
"Region": ctx.vars["region"],
"Owner": ctx.metadata.get("owner", "platform"),
}
Atmos evaluates the code after imports, inheritance, and overrides have been
merged. An inherited expression reads the consuming component's values. For
example, overriding stage to prod produces an Environment tag of prod.
An expression is a scalar during inheritance. A higher-precedence expression or concrete value replaces that field; returned dictionaries are not deep-merged with lower-precedence values.
The returned dictionary becomes a YAML mapping. Strings, booleans, numbers,
lists, and None also retain their types; None becomes YAML null.
Try it
In an Atmos project with a Terraform component named service, add this
component to a stack manifest:
vars:
stage: dev
region: us-east-2
components:
terraform:
service:
metadata:
owner: platform
vars:
resource_tags: !starlark |
return {
"Environment": ctx.vars["stage"],
"Region": ctx.vars["region"],
"Owner": ctx.metadata.get("owner", "platform"),
}
Inspect it with your project's stack name:
atmos describe component service -s <stack> --format json
The vars.resource_tags field contains:
{
"Environment": "dev",
"Region": "us-east-2",
"Owner": "platform"
}
Context
The read-only ctx object exposes the effective component configuration.
Access sections as attributes, then use dictionary indexing or .get() for
values. Mappings also support iteration, .keys(), .values(), and .items().
ctx.vars- Merged component variables, including inherited values and overrides.
ctx.metadata- Component metadata. Use
.get()for optional fields. ctx.settings- Merged component settings.
ctx.env- The component's configured environment mapping. This is not the process environment.
ctx.locals- Local values available in the component configuration.
ctx.stack- The stack being evaluated.
ctx.component- The component instance name when evaluation has a component context.
ctx.component_type- The component type, such as
terraformorhelmfile, when available.
Missing configuration sections are empty mappings. Reading a missing key with
ctx.vars["name"] fails; ctx.vars.get("name", "default") supplies a fallback.
The context and its nested values cannot be modified. Build and return a new
value instead.
Computed dependencies
Values are resolved when accessed, so a computed field can depend on another computed field regardless of their order in YAML:
vars:
replicas: !starlark |
return ctx.vars["minimum_replicas"] * 2
minimum_replicas: !starlark |
return 3 if ctx.vars["stage"] == "prod" else 1
stage: prod
Here, replicas is 6. Each field is resolved once per component evaluation.
A circular dependency fails with the configuration paths involved, rather than
depending on YAML key order.
Go templates run before YAML functions. Starlark can read rendered values from
ctx; a Go template cannot read the result of a !starlark expression in that
same pass. Source inside !starlark is literal: {{ ... }} inside a Starlark
string stays unchanged.
Functions and results
A block is an implicit function body. It supports local variables, helper functions, loops, conditions, and early returns:
vars:
stage: dev
enabled_regions: [us-east-1, us-east-2]
deployment_names: !starlark |
def name(region):
return "%s-%s" % (ctx.vars["stage"], region)
return [name(region) for region in ctx.vars["enabled_regions"]]
The evaluator includes Starlark builtins, sum, round, and the json module.
See the language overview for the language's syntax and
Starlark background.
Return None, a boolean, string, finite number, list, or dictionary with string
keys. Integers must fit a signed or unsigned 64-bit value. An empty list or
dictionary remains empty. Falling through without a return produces null.
Functions, sets, tuples, non-string dictionary keys, and cyclic collections are
rejected as return values.
Evaluation scope
Use !starlark in component configuration values within stack manifests. It
computes values after structural merging; it does not generate imports,
component names, inheritance rules, or stack identities. It is not supported in
atmos.yaml or scaffold configuration.
The selector fields metadata.tags and metadata.labels reject !starlark.
They determine component selection before full evaluation, while context reads
can resolve dependencies that require authentication or execute commands.
This configuration evaluator provides ctx, language builtins, and json.
Automation modules such as exec, fs, and steps, and module loading with
load(), are unavailable here. Use automation scripts for
commands, prompts, and other operations. Existing YAML functions referenced
through ctx retain their own behavior, including any external reads they
perform.
Each block has a budget of 100,000 interpreter steps. This catches runaway loops; it is not a hard memory or CPU limit. Evaluation errors include the configuration field and, for source errors, the originating filename and line.
Commands that support --skip !starlark preserve the expression without
evaluating it.