Atmos Functions
Atmos provides two types of functions for dynamic configuration: YAML Functions (recommended) and Template Functions. Understanding the difference is crucial for writing reliable, maintainable configurations.
Critical Differences
YAML Functions (Recommended) ✅
YAML functions are native YAML features that work with the YAML parser. They are processed after the YAML is parsed into a structured document.
Advantages:
- Type-safe: Work with actual YAML data types (strings, numbers, booleans, objects, arrays)
- Error-resistant: Cannot break YAML syntax since they operate on parsed data
- Predictable: Results are always valid YAML structures
- Debuggable: Errors point to specific YAML nodes
- Native: Part of the YAML specification via custom tags
Example:
# Safe and predictable - the function receives and returns proper YAML types
vpc_id: !terraform.output vpc.vpc_id
environment: !env AWS_ENVIRONMENT
config: !include common-config.yaml
Template Functions (Use with Caution) ⚠️
Template functions use Go's text templating to manipulate the raw text before YAML parsing. They operate on the document as a string, not as structured data.
Disadvantages:
- Error-prone: Can easily generate invalid YAML syntax
- Type-unsafe: Work with text, not data types
- Fragile: Whitespace and indentation issues are common
- Hard to debug: Errors appear as YAML parsing failures
- Side effects: Can accidentally modify unintended parts of the document
Example of potential issues:
# DANGEROUS - template functions can break YAML structure
# If the template returns multi-line text or special characters, YAML parsing fails
value: {{ atmos.Component "vpc" .stack }} # May break if output contains colons or newlines
Best Practices
Always prefer YAML functions over template functions when possible. Template functions should only be used when absolutely necessary for complex logic that cannot be achieved with YAML functions.
When to Use YAML Functions
- Reading Terraform outputs: Use
!terraform.output
or!terraform.state
- Including external files: Use
!include
- Environment variables: Use
!env
- External data stores: Use
!store
- Command execution: Use
!exec
When Template Functions Might Be Necessary
- Complex conditional logic that requires if/else statements
- Loops and iteration over data structures
- String manipulation that requires Go template functions
- Dynamic key generation in YAML structures
Safety Guidelines for Template Functions
If you must use template functions:
- Test thoroughly - Template errors often only appear with specific input values
- Keep templates simple - Complex templates are hard to debug
- Validate output - Ensure generated YAML is always valid
- Use proper escaping - Handle special characters in template outputs
- Document extensively - Explain why templates are needed and what they do
- Consider alternatives - Can you restructure to use YAML functions instead?
Function Categories
🗃️ YAML Functions
11 items
🗃️ Template Functions
4 items
Migration Path
If you have existing template functions, consider migrating to YAML functions:
Instead of (Template) | Use (YAML) |
---|---|
{{ exec "command" }} | !exec command |
{{ env "VAR" }} | !env VAR |
{{ toJson .values }} | Native YAML structures |
Reading outputs via templates | !terraform.output or !terraform.state |
Performance Considerations
- YAML functions are generally faster as they work with parsed data structures
- Template functions require an additional pre-processing step before YAML parsing
!terraform.state
is the fastest way to read Terraform outputs (10-100x faster than!terraform.output
)