# 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](/stacks/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:

```yaml
# 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:

```yaml
# 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:

```yaml
# 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:` / `ansible.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

**File:** `stacks/catalog/defaults.yaml`

```yaml
# Global defaults
env:
  AWS_SDK_LOAD_CONFIG: "true"
```

**File:** `stacks/orgs/acme/plat/prod/_defaults.yaml`

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

**File:** `stacks/orgs/acme/plat/prod/us-east-1.yaml`

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

```yaml
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.

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

```yaml
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:

```yaml
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:

```yaml
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:

```yaml
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`)

```yaml
env:
  GITHUB_TOKEN: !exec gh auth token
  GH_REPO: !exec gh repo view --json nameWithOwner -q .nameWithOwner
```

#### 1Password CLI (`op`)

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

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

```yaml
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](/stacks/auth) section instead of environment variables.

## Related

- [Variables (vars)](/stacks/vars)
- [Locals](/stacks/locals)
- [Settings](/stacks/settings)
- [Authentication](/stacks/auth)
- [Imports](/stacks/imports)
- [Inheritance](/howto/inheritance)
- [YAML Functions](/functions/yaml) - Full reference for `!env`, `!exec`, and other YAML functions
