Skip to main content

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 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

warning

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:

  1. Test thoroughly - Template errors often only appear with specific input values
  2. Keep templates simple - Complex templates are hard to debug
  3. Validate output - Ensure generated YAML is always valid
  4. Use proper escaping - Handle special characters in template outputs
  5. Document extensively - Explain why templates are needed and what they do
  6. Consider alternatives - Can you restructure to use YAML functions instead?

Function Categories

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)