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, packer, or ansible 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
ansible:
env:
ANSIBLE_HOST_KEY_CHECKING: "false"
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
Including Dotenv Files
Use !include to load a dotenv file directly into a stack env section:
Use YAML merge keys when you want to include dotenv values and also define inline overrides. The << key is YAML's merge-key syntax, the same YAML mechanism commonly used with anchors and aliases:
Atmos parses .env, .env.*, and *.env files as dotenv key/value files when they are included with !include. The included values become a map, so standard YAML merge behavior applies: keys written directly under env override keys loaded from the dotenv file.
Dotenv includes can be used at any stack env scope:
terraform:
env:
<<: !include ./terraform.env
TF_IN_AUTOMATION: "true"
components:
terraform:
vpc:
env:
<<: !include ./vpc.env
TF_LOG: DEBUG
You can layer multiple dotenv files with a YAML merge sequence:
env:
<<:
- !include .env.local
- !include .env
AWS_REGION: us-east-2
YAML merge sequence precedence is earlier item wins. In the example above, .env.local has higher precedence than .env, so .env.local overrides .env. Keys written directly under env, such as AWS_REGION, override all merged dotenv values.
Local dotenv paths follow the existing !include resolution rules. Use ./ or ../ for paths relative to the YAML file containing the include; bare local paths such as .env follow Atmos' normal current/base-path lookup for includes. Absolute paths are honored.
Use !include.raw when you need the raw file contents instead of parsed dotenv values. Atmos does not automatically load dotenv files, and it does not load or execute .envrc files.
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:/ansible.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
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.
Ansible
ANSIBLE_HOST_KEY_CHECKING- Disable SSH host key checking (set to
false). ANSIBLE_FORCE_COLOR- Force colored output (set to
true). ANSIBLE_CONFIG- Path to Ansible configuration file.
ANSIBLE_VAULT_PASSWORD_FILE- Path to Ansible Vault password file.
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