# atmos terraform migrate

Use `atmos terraform migrate` to run user-authored `tfmigrate` migrations in an Atmos Terraform component context.

> ⚠️ Experimental

**Configure Tfmigrate Hooks**

Run migrations automatically from Terraform lifecycle hooks.

Hooks Reference[Read more](/stacks/hooks)

## Usage

```shell
atmos terraform migrate <subcommand> [component] [options]
```

Atmos prepares the component before `tfmigrate` runs. Source provisioning, workdir provisioning, generated backend files, generated varfiles, auth identity setup, and Terraform workspace selection all happen first.

## Arguments

- **`subcommand`**
  Migration action to run. Supported values are 
  `plan`
  , 
  `apply`
  , and 
  `list`
  .
- **`component`**
  Atmos Terraform component to migrate or inspect. Omit when selecting multiple components with flags such as 
  `--all`
  , 
  `--components`
  , 
  `--query`
  , or (for 
  `plan`
   and 
  `apply`
  ) 
  `--affected`
  .

## Flags

- **`--stack` / `-s`**
  Atmos stack where the component is defined.
- **`--identity` / `-i`**
  Identity to authenticate before resolving the component and running 
  `tfmigrate`
  . Environment variable: 
  `ATMOS_IDENTITY`
  .
- **`--migration`**
  A single 
  `tfmigrate`
   migration file for 
  `plan`
   or 
  `apply`
  . 
  `tfmigrate`
   resolves the value relative to the 
  `migration_dir`
   set in its config (default 
  `.`
  ). Pass just the filename when 
  `migration_dir`
   already points at your migrations directory. Omit this flag to let 
  `tfmigrate`
   run history mode.
- **`--tfmigrate-config`**
  Override the 
  `tfmigrate`
   config path. Atmos checks, in order: this flag or 
  `ATMOS_TFMIGRATE_CONFIG`
  , then 
  `TFMIGRATE_CONFIG`
  , then a 
  `.tfmigrate.hcl`
   file in the component. When none of these are set, Atmos generates a config that reuses the component's Terraform backend as history storage.
- **`--backend-config`**
  Backend config entry passed to 
  `tfmigrate --backend-config`
  . Repeat the flag for multiple entries.
- **`--all`, `--components`, `--query`, `--affected`**
  Select multiple Terraform component instances instead of passing one component argument. 
  `--affected`
   applies to 
  `plan`
   and 
  `apply`
   only. 
  `list`
   supports 
  `--all`
  , 
  `--components`
  , and 
  `--query`
  .
- **`--skip-init`**
  Skip the normal Terraform init path before 
  `tfmigrate`
   runs.

## Authentication

`atmos terraform migrate` uses the same identity flow as other Terraform commands. Pass an identity explicitly when the migration needs cloud credentials for backend access, YAML functions, source provisioning, or `tfmigrate` history storage:

```shell
atmos terraform migrate plan s3-bucket -s plat-ue2-dev --identity aws-prod --tfmigrate-config .tfmigrate.hcl
```

You can also use `ATMOS_IDENTITY`:

```shell
ATMOS_IDENTITY=aws-prod atmos terraform migrate apply s3-bucket -s plat-ue2-dev --tfmigrate-config .tfmigrate.hcl
```

When no identity is provided, Atmos can use the component or stack default identity. Use `--identity` without a value to select interactively, or `--identity=false` to disable authentication for the command.

## Subcommands

## Examples

Preview history-mode migrations:

```shell
atmos terraform migrate plan s3-bucket -s plat-ue2-dev
```

Apply history-mode migrations:

```shell
atmos terraform migrate apply s3-bucket -s plat-ue2-dev
```

List migration context and history settings:

```shell
atmos terraform migrate list -s plat-ue2-dev
```

## How Atmos Runs `tfmigrate`

For every selected component instance, Atmos:

- Resolves the stack/component with the standard Terraform command flags.
- Authenticates the configured Atmos identity before migration.
- Runs the normal Terraform init path unless `--skip-init` is set.
- Selects the configured Terraform workspace.
- Resolves `tfmigrate` and Terraform/OpenTofu through the Atmos toolchain or PATH.
- Sets `TFMIGRATE_EXEC_PATH` to the resolved Terraform/OpenTofu binary unless already set.
- Routes the generated varfile into `tfmigrate`'s internal Terraform plans via `TF_CLI_ARGS_plan`. This lets components with required variables plan cleanly.
- Generates a default `tfmigrate` config when you have not provided one. The default reuses the component's Terraform backend as history storage.
- Pre-creates the parent directory of a `storage "local"` history path from the `tfmigrate` config. This prevents the first history save from failing on a missing directory.
- Exports per-instance history helper variables for the `tfmigrate` config.

## History Mode

Enable `tfmigrate` history mode by omitting `--migration`:

```shell
atmos terraform migrate apply s3-bucket -s plat-ue2-dev
```

History storage works with zero configuration. When the component has no `.tfmigrate.hcl`, and no `--tfmigrate-config` or `TFMIGRATE_CONFIG`, Atmos generates a `tfmigrate` config that reuses the component's Terraform backend:

- **S3 backend** — Atmos stores history in the same bucket, under `tfmigrate/<stack>/<component>/<workspace>/history.json`. It inherits the region, profile, assume-role ARN, KMS key, and custom endpoint.
- **GCS backend** — Atmos stores history in the same bucket, under the same namespaced object name.
- **Local or other backends** — Atmos stores history as a local file next to the local-backend state file, or under the component working directory. Atmos creates the directory automatically.

The generated config points `migration_dir` at the component's `migrations/` directory when one exists, the component root otherwise.

To take control, add a `.tfmigrate.hcl` file to the component, or point at one explicitly. Atmos discovers a component-local file automatically, and skips the generated default entirely:

```shell
atmos terraform migrate apply s3-bucket -s plat-ue2-dev --tfmigrate-config migrations/.tfmigrate.hcl
```

## History Variables

Atmos sets these variables for use from the `tfmigrate` config via `env`:

- **`ATMOS_STACK`**
  The selected Atmos stack.
- **`ATMOS_COMPONENT`**
  The selected Terraform component instance.
- **`ATMOS_TERRAFORM_WORKSPACE`**
  The selected Terraform workspace, or 
  `default`
   when none is configured.
- **`ATMOS_TFMIGRATE_HISTORY_NAMESPACE`**
  `tfmigrate/&lt;stack&gt;/&lt;component&gt;/&lt;workspace&gt;`
  .
- **`ATMOS_TFMIGRATE_HISTORY_KEY`**
  `tfmigrate/&lt;stack&gt;/&lt;component&gt;/&lt;workspace&gt;/history.json`
  .
- **`ATMOS_TFMIGRATE_HISTORY_BUCKET`**
  Copied from the component Terraform backend when the backend is S3 or GCS.
- **`ATMOS_TFMIGRATE_HISTORY_REGION`, `ATMOS_TFMIGRATE_HISTORY_PROFILE`, `ATMOS_TFMIGRATE_HISTORY_ROLE_ARN`**
  Copied from supported S3 backend settings.

Atmos namespaces the history key by stack, component, and workspace. This avoids collisions when multiple Atmos component instances share the same Terraform backend bucket.

## Rerun Safety

Single-file `tfmigrate apply path.hcl` is not inherently idempotent. A rerun can fail if a `state mv` source or `state rm` address already changed.

For CI, use `tfmigrate` history mode with durable storage such as S3, GCS, or a local file persisted by the workflow runner.

## Related

- [`atmos terraform migrate plan`](/cli/commands/terraform/migrate-plan)
- [`atmos terraform migrate apply`](/cli/commands/terraform/migrate-apply)
- [`atmos terraform migrate list`](/cli/commands/terraform/migrate-list)
- [Hooks](/stacks/hooks)
- [Terraform Component Configuration](/cli/configuration/components/terraform)
