# Environment Variables

The `env` section in `atmos.yaml` defines global environment variables that are automatically set for all Atmos operations. Use this to configure tools, inject credentials, or set defaults that apply across your entire project.

> **Key points**
>
> - Set environment variables once, use everywhere
> - Works seamlessly with [Atmos profiles](/cli/configuration/profiles) for environment-specific configuration
> - Supports [YAML functions](/functions/yaml) like `!env` and `!exec` for dynamic values
> - Variables are merged with system environment (global env can override system, component env overrides global)

## Configuration

Configure global environment variables in the `env` section of your `atmos.yaml`:

**File:** `atmos.yaml`

```yaml
env:
  # Get GitHub token dynamically from gh CLI
  GITHUB_TOKEN: !exec gh auth token

  # Static environment variable values
  AWS_SDK_LOAD_CONFIG: "true"
  TF_PLUGIN_CACHE_DIR: /tmp/terraform-plugin-cache
```

- **`env`**

  A map of environment variable names to values. Values can be literal strings or use [YAML functions](/functions/yaml) for dynamic values.

  **Type:** `map[string]string`

  **Default:** Not set

## Precedence

Environment variables are merged in the following order (lowest to highest priority):

| Priority | Source | Description |
|----------|--------|-------------|
| 1 (lowest) | System environment | Variables from your shell (`os.Environ()`) |
| 2 | Global `env` in `atmos.yaml` | Variables defined in CLI configuration |
| 3 (highest) | [Component/stack `env`](/stacks/env) | Variables defined in stack manifests |

This means:

- Global `env` in `atmos.yaml` can override system environment variables
- [Component-level `env`](/stacks/env) in stacks can override global `env`

### Special Handling for Terraform CLI Args

Variables starting with `TF_CLI_ARGS_` receive special handling. Instead of replacing, new values are **prepended** to existing values, allowing you to layer Terraform arguments:

```yaml
# atmos.yaml
env:
  TF_CLI_ARGS_plan: "-compact-warnings"

# If TF_CLI_ARGS_plan is already set to "-lock=false" in your shell,
# the final value becomes: "-compact-warnings -lock=false"
```

## YAML Functions

The `env` section supports [YAML functions](/functions/yaml) for dynamic values:

### Reading from Other Environment Variables

Use [`!env`](/functions/yaml/env) to read values from the current environment:

```yaml
env:
  # Copy GH_TOKEN to GITHUB_TOKEN if it exists
  GITHUB_TOKEN: !env GH_TOKEN

  # With a default value if not set
  AWS_PROFILE: !env MY_AWS_PROFILE default
```

### Executing Commands

Use [`!exec`](/functions/yaml/exec) to set values from command output:

```yaml
env:
  # Get GitHub token from gh CLI
  GITHUB_TOKEN: !exec gh auth token

  # Get AWS account ID
  AWS_ACCOUNT_ID: !exec aws sts get-caller-identity --query Account --output text
```

## Use Cases

### GitHub Token for Private Terraform Modules

When using private GitHub repositories as Terraform module sources, set `GITHUB_TOKEN`:

**File:** `atmos.yaml`

```yaml
env:
  # Use gh CLI to get token (requires gh auth login)
  GITHUB_TOKEN: !exec gh auth token
```

This enables Terraform to authenticate when downloading modules:

```hcl
module "vpc" {
  source = "git::https://github.com/myorg/terraform-aws-vpc.git?ref=v1.0.0"
}
```

### Terraform Plugin Cache

Speed up Terraform operations by caching providers:

**File:** `atmos.yaml`

```yaml
env:
  TF_PLUGIN_CACHE_DIR: /tmp/terraform-plugin-cache
```

### AWS SDK Configuration

Configure AWS SDK behavior globally:

**File:** `atmos.yaml`

```yaml
env:
  AWS_SDK_LOAD_CONFIG: "true"
  AWS_RETRY_MODE: "adaptive"
  AWS_MAX_ATTEMPTS: "10"
```

### OpenTofu Configuration

Set OpenTofu-specific environment variables:

**File:** `atmos.yaml`

```yaml
env:
  TOFU_CLI_CONFIG_FILE: /etc/opentofu/tofurc
```

## Using with Atmos Profiles

The `env` section becomes powerful when combined with [Atmos profiles](/cli/configuration/profiles). Define environment-specific variables in profile configurations:

### Local Development Profile

**File:** `profiles/developer/atmos.yaml`

```yaml
metadata:
  name: developer
  description: Local development with GitHub token from gh CLI

env:
  # Get token from gh CLI for local development
  GITHUB_TOKEN: !exec gh auth token

  # Enable debug logging
  TF_LOG: DEBUG
```

### CI/CD Profile

**File:** `profiles/ci/atmos.yaml`

```yaml
metadata:
  name: ci
  description: CI/CD pipeline settings

env:
  # In CI, GITHUB_TOKEN is typically already set by the CI system
  # This passes through the existing token from the CI environment
  GITHUB_TOKEN: !env GITHUB_TOKEN

  # CI-specific settings
  TF_IN_AUTOMATION: "true"
  TF_INPUT: "false"
```

### Usage

```bash
# Local development - uses gh CLI for GitHub token
atmos --profile developer terraform plan vpc -s prod

# CI/CD - uses existing GITHUB_TOKEN from CI environment
ATMOS_PROFILE=ci atmos terraform apply vpc -s prod --auto-approve
```

This pattern allows you to:

- Use `gh auth token` locally (no token management)
- Use CI-provided `GITHUB_TOKEN` in pipelines (secure, no secrets in config)
- Keep your base `atmos.yaml` clean of environment-specific settings

## Comparison with Stack-Level `env`

| Feature          | CLI `env` (atmos.yaml) | [Stack `env`](/stacks/env) (stack manifests) |
|------------------|------------------------|----------------------------------------------|
| Scope            | All Atmos operations   | Specific components/stacks                   |
| Inheritance      | From profiles          | From stack imports                           |
| Use case         | Global tooling config  | Component-specific config                    |
| Template support | Yes                    | Yes                                          |

### When to Use Which

**Use CLI `env` for:**

- Tool configuration (`GITHUB_TOKEN`, `TF_PLUGIN_CACHE_DIR`)
- SDK settings (`AWS_SDK_LOAD_CONFIG`)
- CI/CD automation flags (`TF_IN_AUTOMATION`)

**Use [Stack `env`](/stacks/env) for:**

- Cloud provider profiles (`AWS_PROFILE`)
- Region-specific settings (`AWS_REGION`)
- Component-specific debugging (`TF_LOG`)

## Examples

### Complete Development Setup

**File:** `atmos.yaml`

```yaml
env:
  # GitHub authentication for private modules
  GITHUB_TOKEN: !exec gh auth token

  # Terraform caching
  TF_PLUGIN_CACHE_DIR: /tmp/terraform-plugin-cache

  # AWS configuration
  AWS_SDK_LOAD_CONFIG: "true"
```

### CI/CD Pipeline Setup

**File:** `profiles/ci/atmos.yaml`

```yaml
env:
  # Automation mode
  TF_IN_AUTOMATION: "true"
  TF_INPUT: "false"

  # Use existing CI tokens
  GITHUB_TOKEN: !env GITHUB_TOKEN

  # Disable color for log parsing
  NO_COLOR: "1"
```

### Multi-Cloud Setup

**File:** `atmos.yaml`

```yaml
env:
  # AWS
  AWS_SDK_LOAD_CONFIG: "true"

  # Azure
  ARM_USE_CLI: "true"

  # GCP
  GOOGLE_CLOUD_PROJECT: my-project-id
```

## See Also

- [Environment Variables](/cli/environment-variables) - Complete reference for all Atmos CLI environment variables
- [Global Flags](/cli/global-flags) - Flag reference with environment variable equivalents
- [Profiles](/cli/configuration/profiles) - Environment-specific configuration overrides
- [Stack Environment Variables](/stacks/env) - Component-level environment variables
- [Commands](/cli/configuration/commands) - Custom commands with environment variables
- [YAML Functions](/functions/yaml) - Dynamic value functions (`!env`, `!exec`, `!store`, etc.)
