Skip to main content

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_LOG for debugging or TF_CLI_CONFIG_FILE for 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:

  1. Global env: (applies to all components)
  2. Component-type terraform.env: / helmfile.env: / packer.env: (applies to all components of that type)
  3. 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

# Global defaults
env:
AWS_SDK_LOAD_CONFIG: "true"

stacks/orgs/acme/plat/prod/_defaults.yaml

# Production defaults
env:
AWS_PROFILE: acme-prod
TF_IN_AUTOMATION: "true"

stacks/orgs/acme/plat/prod/us-east-1.yaml

import:
- catalog/defaults
- orgs/acme/plat/prod/_defaults

env:
AWS_REGION: us-east-1

components:
terraform:
vpc:
env:
TF_LOG: TRACE

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 false to 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​

  1. Use Profiles Over Credentials: Set AWS_PROFILE rather than embedding AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

  2. Enable Automation Mode: Set TF_IN_AUTOMATION=true in CI/CD environments to suppress interactive prompts.

  3. Centralize Common Settings: Define shared environment variables in catalog defaults and import them.

  4. Use Component-Level Sparingly: Only override environment variables at the component level when that component has unique requirements.

  5. Consider Auth for Credentials: For complex credential management, use the auth section instead of environment variables.