# Workdir Provisioning

`provision.workdir` creates an isolated working directory for each component instance under `.workdir/<componentType>/<stack>-<componentName>-<hash>/`. The component source is staged into this directory and all toolchain commands execute there, enabling concurrent execution and just-in-time source provisioning without `.terraform/`, lockfile, or generated-varfile collisions.

> ⚠️ Experimental

## Schema

- **`provision.workdir.enabled`**

  Create an isolated working directory for each component instance.
  - **Type:** `boolean`
  - **Default:** `false`
  - **Applies to:** Terraform, Helmfile, Packer, and Ansible components

## Configuration

Enable workdir provisioning for any supported toolchain:

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

```yaml
components:
  terraform:
    vpc:
      provision:
        workdir:
          enabled: true
      vars:
        cidr_block: "10.0.0.0/16"

  helmfile:
    nginx:
      provision:
        workdir:
          enabled: true
      vars:
        replicas: 3
```

## Directory Layout

When workdir provisioning is enabled, Atmos creates a per-component-instance directory under `.workdir/` and runs all toolchain commands there. Each instance gets its own `.terraform/`, varfiles, and state cache. The directory name ends with a short hash suffix (derived from the stack and component name) that keeps two component instances from colliding even when their `<stack>-<componentName>` prefixes happen to look the same.

```
.workdir/
├── terraform/
│   └── prod-ue1-vpc-b52c4d0a/        # <stack>-<componentName>-<hash>
│       ├── .terraform/
│       ├── .atmos/metadata.json
│       └── ... (component source)
└── helmfile/
    └── prod-ue1-nginx-27ff63ad/
        └── ...
```

> **Note**
>
> The `.workdir/` directory is created at runtime and should be added to `.gitignore`. It is not used by `atmos describe affected` for change detection — that command tracks the source files in `components/<type>/<name>/`, not the runtime workdir.

## Toolchain-Level Defaults

Apply workdir provisioning to every component of a toolchain:

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

```yaml
terraform:
  provision:
    workdir:
      enabled: true   # Every Terraform component in this stack gets an isolated workdir

helmfile:
  provision:
    workdir:
      enabled: true   # Every Helmfile component runs in its own workdir
```

## Component-Level Overrides

Opt a single component out of a toolchain or global default by setting `enabled: false`:

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

```yaml
components:
  terraform:
    legacy-vpc:
      provision:
        workdir:
          enabled: false   # Run in the original component directory
      vars:
        # ...
```

## Global Defaults

To apply a workdir default across every stack, declare `terraform.provision` (and
`helmfile.provision`, etc.) in a base stack manifest that all your stacks import - for example a
`_defaults.yaml` or a catalog mixin. This is the same place you set global `vars`, `metadata`, and
`secrets`, and it cascades to every component through normal stack inheritance. Component-level
`provision.workdir` still overrides it.

**File:** `stacks/mixins/provision-workdir.yaml`

```yaml
terraform:
  provision:
    workdir:
      enabled: true       # Default for every Terraform component that imports this mixin
      ttl: "7d"           # Documents the intended cleanup window for unused workdirs

helmfile:
  provision:
    workdir:
      enabled: true
```

- **`provision.workdir.enabled`**
  Whether components run inside an isolated workdir. Set it at the toolchain section of a shared stack manifest for a global default; component-level 
  `provision.workdir.enabled`
   still overrides it.
- **`provision.workdir.ttl`**
  Time-to-live for workdirs (e.g., 
  `"7d"`
  , 
  `"24h"`
  , 
  `"weekly"`
  ). Workdirs not accessed within this duration become candidates for cleanup by 
  [`atmos terraform workdir clean --expired`](/cli/commands/terraform/workdir)
  .

Workdir provisioning is component configuration, so its global default belongs in the stack
configuration alongside `vars`, `metadata`, and `secrets` - there is no `settings.provision.workdir`
block in `atmos.yaml`.

## Managing Workdirs

Use the [`atmos terraform workdir`](/cli/commands/terraform/workdir) commands to inspect and clean up workdirs:

| Command | Purpose |
|---|---|
| `atmos terraform workdir list` | List all workdirs |
| `atmos terraform workdir show <component> -s <stack>` | Show details for a specific workdir |
| `atmos terraform workdir clean --expired --ttl=7d` | Remove workdirs not accessed within the TTL |
| `atmos terraform workdir clean --all` | Remove every workdir (forces re-provisioning on next run) |

## Related

- [Backend Provisioning](/stacks/components/provision/backend) — The other half of the `provision:` block
- [`atmos terraform workdir`](/cli/commands/terraform/workdir) — CLI commands for managing workdirs
- [Terraform CLI Configuration](/cli/configuration/components/terraform) — `auto_provision_workdir_for_outputs` and other global Terraform settings
