Go Template Reference for Atmos
Template Syntax Basics
Go templates in Atmos use {{ }} delimiters (configurable in atmos.yaml). Templates are
processed before YAML parsing, so output must produce valid YAML.
# Simple value interpolationname: "{{ .atmos_component }}"# Function callupper_name: "{{ .atmos_component | upper }}"# Conditional (use single quotes to avoid YAML double-quote conflicts)enabled: '{{ if eq .vars.stage "prod" }}true{{ else }}false{{ end }}'
Available Context Variables
When processing Go templates in stack manifests, Atmos provides the full component configuration
as the template context. All values from atmos describe component are available.
Core Variables
| Variable | Type | Description |
|---|---|---|
.atmos_component | string | The Atmos component name |
.atmos_stack | string | The full Atmos stack name |
.stack | string | Alias for .atmos_stack |
.atmos_stack_file | string | Path to the stack manifest file |
.workspace | string | Terraform workspace name |
.component | string | The Terraform component path |
Section Variables
| Variable | Type | Description |
|---|---|---|
.vars | map | Component variables |
.vars.namespace | string | Organization namespace |
.vars.tenant | string | Organizational unit |
.vars.environment | string | Region/environment |
.vars.stage | string | Account/stage |
.vars.name | string | Component instance name |
.vars.region | string | AWS/cloud region |
.vars.tags | map | Resource tags |
.settings | map | Component settings |
.env | map | Environment variables |
.metadata | map | Component metadata |
.metadata.component | string | Terraform component name |
.providers | map | Provider configuration |
.backend | map | Backend configuration |
.backend_type | string | Backend type (e.g., "s3") |
Atmos-Specific Template Functions
atmos.Component
Reads any section or attribute from another Atmos component in a stack.
{{ (atmos.Component "<component>" "<stack>").<section>.<attribute> }}
Reading outputs (remote state):
vpc_id: '{{ (atmos.Component "vpc" .stack).outputs.vpc_id }}'vpc_id: '{{ (atmos.Component "vpc" "plat-ue2-prod").outputs.vpc_id }}'
Reading variables:
vpc_name: '{{ (atmos.Component "vpc" .stack).vars.name }}'
Reading settings:
test_flag: '{{ (atmos.Component "test" .stack).settings.test }}'
Reading metadata:
tf_component: '{{ (atmos.Component "test" .stack).metadata.component }}'
Dynamic stack names:
# Using printf for cross-stack referencesvpc_id: '{{ (atmos.Component "vpc" (printf "net-%s-%s" .vars.environment .vars.stage)).outputs.vpc_id }}'
Complex types (lists/maps) require !template + toJson:
# YAML function wrapping template for proper type handlingsubnet_ids: !template '{{ toJson (atmos.Component "vpc" .stack).outputs.private_subnet_ids }}'config_map: !template '{{ toJson (atmos.Component "config" .stack).outputs.config_map }}'
Results are cached per execution -- repeated calls to the same component/stack return cached data.
atmos.GomplateDatasource
Fetches data from external sources with automatic caching. Requires datasource configuration in
atmos.yaml or stack manifest settings.templates.settings.gomplate.datasources.
{{ (atmos.GomplateDatasource "<alias>").<attribute> }}
Examples:
# API datapublic_ip: '{{ (atmos.GomplateDatasource "ip").ip }}'# AWS SSM Parameterdb_host: '{{ (atmos.GomplateDatasource "database").host }}'# Local fileconfig: '{{ (atmos.GomplateDatasource "config").api_url }}'
Supported datasource types: HTTP/HTTPS, file, AWS SSM/Secrets Manager/S3, Azure Key Vault, Google Cloud Storage, HashiCorp Vault, Consul, environment variables, Git.
atmos.Store
Reads values from configured stores. Same as !store YAML function but in template syntax.
{{ atmos.Store "<store_name>" "<stack>" "<component>" "<key>" }}
Examples:
# Simple valuecidr: '{{ atmos.Store "redis" "prod" "vpc" "cidr" }}'# Current stackcount: '{{ atmos.Store "redis" .stack "config" "instance_count" }}'# Nested accesssubnets: '{{ (atmos.Store "redis" .stack "config" "config_map").vpc_config.subnets_count }}'# In multi-line stringsjson_config: |{"cidr": {{ atmos.Store "redis" "prod" "vpc" "cidr" | quote }}}
Sprig Functions
When templates.settings.sprig.enabled: true, all Sprig functions are available.
String Functions
# uppercasename: '{{ upper .vars.name }}'# lowercasename: '{{ lower .vars.name }}'# title casetitle: '{{ title .vars.name }}'# trim whitespaceclean: '{{ trim .vars.name }}'# replaceslug: '{{ replace "/" "-" .atmos_component }}'# substringprefix: '{{ substr 0 3 .vars.name }}'# quotequoted: '{{ .vars.name | quote }}'# default valuename: '{{ .vars.name | default "unnamed" }}'
List Functions
# first/last elementfirst: '{{ first .vars.zones }}'last: '{{ last .vars.zones }}'# joinzones_str: '{{ join "," .vars.zones }}'# list creationitems: '{{ list "a" "b" "c" }}'# has (check if list contains)has_zone: '{{ has "us-east-1a" .vars.zones }}'
Map Functions
# get keyval: '{{ get .vars.tags "Environment" }}'# has keyhas_env: '{{ hasKey .vars.tags "Environment" }}'# keystag_keys: '{{ keys .vars.tags }}'
Type Conversion
# to JSONjson: '{{ toJson .vars.tags }}'json_raw: '{{ toRawJson .vars.tags }}'# to stringstr: '{{ toString .vars.count }}'# to intnum: '{{ atoi .vars.port_string }}'
OS Functions
# environment variableuser: '{{ env "USER" }}'home: '{{ env "HOME" }}'# with defaultprofile: '{{ env "AWS_PROFILE" | default "default" }}'
Atmos's Own Functions
Registered alongside Sprig and Gomplate in every FuncMap Atmos builds (stack configs, locals, secrets/store references, scaffold templates, toolchain assets).
collectKeys
Distinct from Sprig's own keys above (which takes multiple maps and returns their
unsorted, non-deduped union): collectKeys takes one map, returns its keys sorted, and
supports a nested mode.
# top-level keys, sortedenvironments: '{{ collectKeys .vars.environments }}'# nested: collect "regions" from every value in .vars.environments, flattened and deduplicatedregions: '{{ collectKeys .vars.environments "regions" }}'
Gomplate Functions
When templates.settings.gomplate.enabled: true, all Gomplate functions are available.
String Functions
# Title case (Gomplate)title: '{{ strings.Title .atmos_component }}'# Quotequoted: '{{ .vars.name | strings.Quote }}'# Containshas_prefix: '{{ strings.HasPrefix "vpc" .atmos_component }}'# Replaceclean: '{{ strings.ReplaceAll "/" "-" .atmos_component }}'
Environment (Gomplate)
# getenv (Gomplate's env function alias - use when both Sprig and Gomplate are enabled)user: '{{ getenv "USER" }}'profile: '{{ getenv "AWS_PROFILE" "default" }}'
Data Functions
# JSON encode/decodejson: '{{ data.ToJSON .vars.tags }}'parsed: '{{ data.JSON .vars.json_string }}'# YAML encodeyaml: '{{ data.ToYAML .vars.config }}'
Datasource Functions
# Access configured datasourcesip: '{{ (datasource "ip").ip }}'# With atmos cachingip: '{{ (atmos.GomplateDatasource "ip").ip }}'
Control Flow
Conditionals
# if/elsevalue: '{{ if eq .vars.stage "prod" }}production{{ else }}non-production{{ end }}'# if/else if/elsetier: '{{ if eq .vars.stage "prod" }}tier1{{ else if eq .vars.stage "staging" }}tier2{{ else }}tier3{{ end }}'# Boolean checkenabled: '{{ if .vars.enabled }}true{{ else }}false{{ end }}'# Negationdisabled: '{{ if not .vars.enabled }}true{{ else }}false{{ end }}'# And/Orcritical: '{{ if and (eq .vars.stage "prod") .vars.high_availability }}true{{ else }}false{{ end }}'
Loops (Range)
# Iterate over a listzones: |{{ range .vars.availability_zones }}- {{ . }}{{ end }}
Warning: Range in templates can easily break YAML indentation. Use with extreme caution.
Pipeline Operators
# Chain functions with |name: '{{ .vars.name | upper | quote }}'description: '{{ .atmos_component | strings.Title }} in {{ .atmos_stack | strings.Quote }}'
Template Delimiters
The default delimiters {{ }} can conflict with YAML syntax. To avoid issues with complex
outputs, configure custom delimiters:
# atmos.yamltemplates:settings:delimiters: ["'{{", "}}'"]
With custom delimiters, complex types can be safely embedded:
subnet_ids: '{{ toRawJson ((atmos.Component "vpc" .stack).outputs.private_subnet_ids) }}'
Escaping Templates
For External Systems
Prevent Atmos from processing templates intended for other tools:
# Backtick escapeannotation: "{{`{{ .Values.ingress.class }}`}}"# printf functionmessage: '{{ printf "Application {{ .app.metadata.name }} is running." }}'# !literal YAML function (preferred)annotation: !literal "{{ .Values.ingress.class }}"
In Import Files
When using Go templates in both imports and manifests, escape second-pass templates:
# In import template file (.tmpl)tags:atmos_component: "{{`{{ .atmos_component }}`}}"atmos_stack: "{{`{{ .atmos_stack }}`}}"
Performance Considerations
atmos.Componentrequires resolving the full component context and potentially runningterraform output, which initializes Terraform and downloads providersatmos.GomplateDatasourcecaches results per execution (use it instead ofdatasource)atmos.Storecaches results per store/stack/component/key combination- All Atmos template functions cache results within a single CLI command execution
- Functions like
atmos describe stacksevaluate all templates, so heavy use ofatmos.Componentcan significantly slow these commands
Safety Guidelines
- Always quote template expressions in YAML values:
'{{ .value }}'not{{ .value }} - Use
toJsonortoRawJsonwhen embedding complex types (lists, maps) - Use
!templateYAML function for complex type output fromatmos.Component - Prefer YAML functions (
!terraform.state,!store) over template functions when possible - Test templates with
atmos describe componentto verify output before plan/apply - Keep templates simple -- complex templates are hard to debug and maintain