Configure Environment Variables
The env section defines environment variables that are set when executing your components. Environment variables can be configured at the global level, component-type level, or component level, and are deep-merged across the inheritance chain.
Use Casesβ
- Cloud Provider Configuration: Set
AWS_PROFILE,AWS_REGION, or other provider-specific environment variables. - Terraform Debugging: Enable
TF_LOGfor debugging orTF_CLI_CONFIG_FILEfor custom CLI configuration. - Tool Configuration: Configure paths and settings for external tools used by your components.
- Secrets Injection: Pass secrets from environment to components (though consider using auth for credentials).
Configuration Scopesβ
The env section can be defined at multiple levels. Atmos deep-merges environment variables from all levels, with more specific levels taking precedence.
Global Levelβ
Environment variables defined at the root level apply to all components in the stack:
# stacks/orgs/acme/plat/prod/us-east-1.yaml
env:
AWS_PROFILE: acme-prod
AWS_REGION: us-east-1
Component-Type Levelβ
Environment variables defined under terraform, helmfile, or packer apply to all components of that type:
# stacks/orgs/acme/plat/prod/_defaults.yaml
terraform:
env:
TF_CLI_CONFIG_FILE: /path/to/terraformrc
TF_PLUGIN_CACHE_DIR: /path/to/plugin-cache
helmfile:
env:
HELM_CACHE_HOME: /path/to/helm-cache
Component Levelβ
Environment variables defined within a component override all higher-level settings:
# stacks/orgs/acme/plat/prod/us-east-1.yaml
components:
terraform:
vpc:
env:
TF_LOG: DEBUG
TF_LOG_PATH: /tmp/vpc-terraform.log
Merge Behaviorβ
Environment variables are deep-merged from the most general to the most specific level:
- Global
env:(applies to all components) - Component-type
terraform.env:/helmfile.env:/packer.env:(applies to all components of that type) - Component
components.terraform.<name>.env(applies to a specific component)
Unlike vars, environment variables are simple key-value pairs and are merged shallowlyβmore specific values replace less specific ones for the same key.
Exampleβ
stacks/catalog/defaults.yaml
stacks/orgs/acme/plat/prod/_defaults.yaml
stacks/orgs/acme/plat/prod/us-east-1.yaml
The resulting env for the vpc component would be:
env:
AWS_SDK_LOAD_CONFIG: "true" # From catalog/defaults
AWS_PROFILE: acme-prod # From prod/_defaults
TF_IN_AUTOMATION: "true" # From prod/_defaults
AWS_REGION: us-east-1 # From stack file
TF_LOG: TRACE # From component
Common Environment Variablesβ
Terraformβ
TF_LOG- Set log level (
TRACE,DEBUG,INFO,WARN,ERROR). TF_LOG_PATH- Path to write Terraform logs.
TF_CLI_CONFIG_FILE- Path to Terraform CLI configuration file.
TF_PLUGIN_CACHE_DIR- Directory to cache provider plugins.
TF_IN_AUTOMATION- Suppress prompts when running in automation.
TF_INPUT- Set to
falseto disable interactive prompts.
AWSβ
AWS_PROFILE- AWS CLI profile to use.
AWS_REGION- Default AWS region.
AWS_DEFAULT_REGION- Fallback AWS region.
AWS_SDK_LOAD_CONFIG- Load settings from
~/.aws/config.
Helmfileβ
HELM_CACHE_HOME- Directory for Helm cache.
HELM_CONFIG_HOME- Directory for Helm configuration.
HELM_DATA_HOME- Directory for Helm data.
Using Templates in Environment Variablesβ
Environment variables support Go templates for dynamic values:
env:
TF_LOG_PATH: "/tmp/{{ .namespace }}-{{ .environment }}-{{ .stage }}.log"
KUBECONFIG: "{{ env \"HOME\" }}/.kube/{{ .stage }}-config"
YAML Functions for Dynamic Valuesβ
Atmos provides YAML functions that can dynamically set environment variable values at runtime.
!env - Read from Environmentβ
The !env function reads values from the current environment:
env:
# Pass through an existing environment variable
AWS_PROFILE: !env AWS_PROFILE
# Use a default if the variable is not set
TF_LOG: !env TF_LOG, INFO
This is useful for:
- Passing through environment variables from CI/CD systems
- Inheriting local developer settings
- Providing sensible defaults
!exec - Execute Commandsβ
The !exec function executes shell commands and uses their output as values. This is powerful for integrating with secret managers and credential tools:
env:
# GitHub CLI - get authentication token
GITHUB_TOKEN: !exec gh auth token
# 1Password CLI - retrieve secrets
DATABASE_PASSWORD: !exec op read "op://vault/database/password"
API_KEY: !exec op read "op://vault/api/key"
# AWS Secrets Manager via CLI
DB_CONNECTION_STRING: !exec aws secretsmanager get-secret-value --secret-id prod/db --query SecretString --output text
# HashiCorp Vault
VAULT_SECRET: !exec vault kv get -field=value secret/myapp/config
Combining Functions with Templatesβ
You can combine YAML functions with Go templates for powerful dynamic configuration:
env:
# Dynamic secret path based on environment
DB_PASSWORD: !exec op read "op://{{ .stage }}/database/password"
# GitHub token for the current environment
GITHUB_TOKEN: !exec gh auth token
# AWS profile from environment with fallback
AWS_PROFILE: !env AWS_PROFILE, {{ .namespace }}-{{ .stage }}
Common CLI Integrationsβ
GitHub CLI (gh)β
env:
GITHUB_TOKEN: !exec gh auth token
GH_REPO: !exec gh repo view --json nameWithOwner -q .nameWithOwner
1Password CLI (op)β
env:
# Read individual fields
API_KEY: !exec op read "op://Private/API Credentials/api_key"
API_SECRET: !exec op read "op://Private/API Credentials/api_secret"
# Read from specific vault
DB_PASSWORD: !exec op read "op://Production/Database/password"
AWS CLIβ
env:
# Get secret from Secrets Manager
SECRET_VALUE: !exec aws secretsmanager get-secret-value --secret-id my-secret --query SecretString --output text
# Get parameter from SSM
CONFIG_VALUE: !exec aws ssm get-parameter --name /app/config --with-decryption --query Parameter.Value --output text
HashiCorp Vaultβ
env:
VAULT_TOKEN: !exec vault token lookup -format=json | jq -r .data.id
APP_SECRET: !exec vault kv get -field=secret secret/data/myapp
Best Practicesβ
-
Use Profiles Over Credentials: Set
AWS_PROFILErather than embeddingAWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEY. -
Enable Automation Mode: Set
TF_IN_AUTOMATION=truein CI/CD environments to suppress interactive prompts. -
Centralize Common Settings: Define shared environment variables in catalog defaults and import them.
-
Use Component-Level Sparingly: Only override environment variables at the component level when that component has unique requirements.
-
Consider Auth for Credentials: For complex credential management, use the auth section instead of environment variables.
Relatedβ
- Variables (vars)
- Locals
- Settings
- Authentication
- Imports
- Inheritance
- YAML Functions - Full reference for
!env,!exec, and other YAML functions