Configure Variables
The vars section defines variables that are passed to your components. Variables can be set at the global level, component-type level, or component level, and are deep-merged across the inheritance chain.
Use Cases
- Component Configuration: Pass input variables to Terraform root modules, Helmfile releases, or Packer templates.
- Environment-Specific Values: Define different values for dev, staging, and production environments.
- Shared Defaults: Set common variables at higher levels and override them at lower levels as needed.
Configuration Scopes
The vars section can be defined at multiple levels. Atmos deep-merges variables from all levels, with more specific levels taking precedence.
Global Level
Variables defined at the root level apply to all components in the stack:
# stacks/orgs/acme/plat/prod/us-east-1.yaml
vars:
environment: prod
region: us-east-1
tags:
Environment: Production
ManagedBy: Atmos
Component-Type Level
Variables defined under terraform, helmfile, or packer apply to all components of that type:
# stacks/orgs/acme/plat/prod/_defaults.yaml
terraform:
vars:
terraform_version: "1.5"
helmfile:
vars:
helm_timeout: 300
Component Level
Variables defined within a component override all higher-level settings:
# stacks/orgs/acme/plat/prod/us-east-1.yaml
components:
terraform:
vpc:
vars:
vpc_cidr: "10.0.0.0/16"
enable_dns_hostnames: true
availability_zones:
- us-east-1a
- us-east-1b
- us-east-1c
Merge Behavior
Variables are deep-merged from the most general to the most specific level:
- Global
vars:(applies to all components) - Component-type
terraform.vars:/helmfile.vars:/packer.vars:(applies to all components of that type) - Component
components.terraform.<name>.vars(applies to a specific component)
Maps are recursively merged, and lists are replaced (not appended). More specific values override less specific ones.
Example
stacks/catalog/vpc/_defaults.yaml
stacks/orgs/acme/plat/prod/_defaults.yaml
stacks/orgs/acme/plat/prod/us-east-1.yaml
The resulting vars for the vpc component would be:
vars:
vpc_cidr: "10.0.0.0/16"
tags:
Team: Platform # From catalog/_defaults
Environment: Production # From prod/_defaults
Name: prod-vpc # From component
Context Variables
Atmos automatically provides context variables based on your stack naming convention. These are available in templates and can be used in your Terraform code:
namespace- Organization or company identifier.
tenant- Tenant identifier (for multi-tenant setups).
environment- Environment identifier (e.g.,
ue1for us-east-1). stage- Stage identifier (e.g.,
dev,staging,prod).
These context variables are typically configured in your atmos.yaml using the name_pattern setting.
Using Templates in Variables
Variables support Go templates for dynamic values:
vars:
cluster_name: "{{ .namespace }}-{{ .environment }}-{{ .stage }}-eks"
bucket_name: "{{ .namespace }}-{{ .tenant }}-{{ .stage }}-assets"
You can also reference other component outputs using YAML functions:
vars:
vpc_id: !terraform.output vpc/vpc_id
subnet_ids: !terraform.output vpc/private_subnet_ids
YAML Functions for Variables
Atmos provides YAML functions that can dynamically set variable values. These functions are evaluated at runtime when processing stack configurations.
!include - Load External Files
The !include function loads content from external files, making it ideal for reusing existing .tfvars files or large variable definitions:
vars:
# Include an entire tfvars file
!include path/to/variables.tfvars
# Or include specific variable files
network_config: !include config/network.yaml
tags: !include config/common-tags.yaml
This is particularly useful when:
- Migrating from native Terraform with existing
.tfvarsfiles - Sharing variable definitions across multiple components
- Keeping large configuration blocks in separate files
!terraform.output - Reference Component Outputs
Read outputs from other Terraform components:
vars:
vpc_id: !terraform.output vpc/vpc_id
subnet_ids: !terraform.output vpc/private_subnet_ids
!terraform.state - Access Remote State
Access values from Terraform state with more control:
vars:
# From same stack
vpc_id: !terraform.state vpc vpc_id
# From different stack
shared_vpc_id: !terraform.state shared-services/network vpc vpc_id
!store - Read from External Stores
Read values from external key-value stores:
vars:
api_key: !store ssm/prod app api_key
db_password: !store vault/secrets database password
!env - Read Environment Variables
Pass through environment variables:
vars:
aws_region: !env AWS_REGION
deploy_env: !env DEPLOY_ENV, development # With default
!exec - Execute Commands
Execute shell commands and use their output:
vars:
git_commit: !exec git rev-parse HEAD
current_user: !exec whoami
For the complete list of YAML functions, see YAML Functions.
Best Practices
-
Use Catalog Defaults: Define common variable patterns in
stacks/catalog/and import them. -
Keep Variables DRY: Set shared values at higher levels and only override what's different at lower levels.
-
Use Meaningful Names: Variable names should match your Terraform variable names for clarity.
-
Document Required Variables: Use abstract components to enforce required variables through inheritance.
-
Avoid Duplication: If you find yourself repeating the same variables, consider using imports or inheritance.