Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion agent-skills/skills/atmos-migration/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
---
name: atmos-migration
description: "Migrating to Atmos from existing IaC: techniques, tactics, and design patterns for native Terraform and Terraform Workspaces — minimum-disruption paths, file-layout options, workspace mapping, and the remote-state bridge for progressive migration"
description: "Migrating to Atmos from existing IaC: techniques, tactics, and design patterns for native Terraform and Terraform Workspaces — minimum-disruption paths, file-layout options, workspace mapping, and the remote-state bridge for progressive migration. This skill also explains how to move from asdf, aqua, tfenv, tofuenv, tenv, or a Homebrew Brewfile to the Atmos toolchain."
metadata:
copyright: Copyright Cloud Posse, LLC 2026
version: "1.0.0"
references:
- references/from-native-terraform.md
- references/from-terraform-workspaces.md
- references/remote-state-bridge.md
- references/from-asdf.md
- references/from-aqua.md
- references/from-tfenv.md
- references/from-tofuenv.md
- references/from-tenv.md
- references/from-homebrew-brewfile.md
---

# Migrating to Atmos
Expand Down Expand Up @@ -78,6 +84,36 @@ The remote-state-bridge pattern is what makes **progressive, component-by-compon
possible. Without it, a team is forced into a big-bang cutover. Cover it any time the user has
existing Terraform state they need to read from new Atmos components.

## Replace a Tool-Version Manager

This section covers a topic separate from the IaC-layout question above. A user can migrate the
Terraform or OpenTofu layout, the tool-version manager, or both. Each choice is independent.

If the user currently pins CLI tool versions with asdf, aqua, tfenv, tofuenv, tenv, or a Homebrew
Brewfile, use the matching reference below. Do not write a new config translation by hand.

| Current tool | Reference |
|-----------------------------|---------------------------------------------------------------------|
| asdf | [from-asdf.md](references/from-asdf.md) |
| aqua CLI (`aqua.yaml`) | [from-aqua.md](references/from-aqua.md) |
| tfenv | [from-tfenv.md](references/from-tfenv.md) |
| tofuenv | [from-tofuenv.md](references/from-tofuenv.md) |
| tenv | [from-tenv.md](references/from-tenv.md) |
| Homebrew Brewfile | [from-homebrew-brewfile.md](references/from-homebrew-brewfile.md) |

Each reference includes a command-mapping table. This table shows the old tool's commands next to
the equivalent Atmos toolchain command. Use it to translate familiar commands directly.

Each reference also includes a Shell Integration section. Most tools that a user migrates from add
themselves to every shell automatically, through a shim on `PATH`. The Atmos toolchain does not do
this by default. The Atmos toolchain resolves tools only while an `atmos <subcommand>` runs.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

A user can still get the old shell experience back, where a plain `terraform` command works in any
shell. This is a supported feature, not a missing feature. To enable it, add `atmos toolchain env`
or `atmos toolchain path` to `~/.bashrc`, `~/.zshrc`, the fish config, or the PowerShell profile.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

Always tell the user about this option when they are used to a shim-based tool.

## The Minimum-Viable Migration

When a user says "I want to try Atmos on my existing repo," this is the checklist. Do not deviate
Expand Down Expand Up @@ -162,6 +198,7 @@ those questions to the right skill:
- **Validation policies (OPA, JSON Schema)** → [atmos-validation](../atmos-validation/SKILL.md)
- **CI/CD with affected-detection** → [atmos-ci](../atmos-ci/SKILL.md)
- **Cross-component data sharing via stores** → [atmos-stores](../atmos-stores/SKILL.md)
- **Toolchain configuration (`dependencies.tools`, registries, verification)** → [atmos-toolchain](../atmos-toolchain/SKILL.md)

## Anti-Patterns

Expand All @@ -177,6 +214,11 @@ Things to push back on if a user (or another agent) proposes them during migrati
`metadata.terraform_workspace` and the remote-state-bridge pattern.
- **"Add Gomplate datasources for everything."** No -- reach for YAML functions first.
- **"Adopt the full multi-account org hierarchy on day one."** No -- start with one stack file.
- **"Copy `aqua.yaml` packages into Atmos verbatim."** Do not do this. Atmos supports only part
of the Aqua registry schema. Check the Functional Gaps table in
[from-aqua.md](references/from-aqua.md) first.
- **"Replace the whole Brewfile with Atmos toolchain."** Do not do this. Casks, `mas` entries, and
source-built formulae are out of scope. See [from-homebrew-brewfile.md](references/from-homebrew-brewfile.md).

## Additional Resources

Expand All @@ -186,3 +228,18 @@ Things to push back on if a user (or another agent) proposes them during migrati
workspaces to stacks without losing state
- [References/remote-state-bridge.md](references/remote-state-bridge.md) -- the dummy-component
and abstract-component patterns for reading state from un-migrated or external Terraform
- [References/from-asdf.md](references/from-asdf.md): steps to move `.tool-versions` and asdf
plugins to the Atmos toolchain. Includes a command mapping and shell integration steps.
- [References/from-aqua.md](references/from-aqua.md): steps to move `aqua.yaml` packages to the
Atmos toolchain. Includes the schema-gap table, a command mapping, and shell integration steps.
- [References/from-tfenv.md](references/from-tfenv.md): steps to move `.terraform-version` and
`tfenv use` pins to the Atmos toolchain. Includes a command mapping and shell integration steps.
- [References/from-tofuenv.md](references/from-tofuenv.md): steps to move `.opentofu-version` and
`tofuenv use` pins to the Atmos toolchain. Includes a command mapping and shell integration
steps.
- [References/from-tenv.md](references/from-tenv.md): steps to move tenv's version files for
Terraform, OpenTofu, Terragrunt, and TFLint to the Atmos toolchain. Includes a command mapping
and shell integration steps.
- [References/from-homebrew-brewfile.md](references/from-homebrew-brewfile.md): steps to move the
CLI-tool part of a Brewfile to the Atmos toolchain. Includes the partial-scope rules, a command
mapping, and shell integration steps.
209 changes: 209 additions & 0 deletions agent-skills/skills/atmos-migration/references/from-aqua.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# Replace Aqua with the Atmos Toolchain

This reference explains how to replace the [Aqua](https://aquaproj.github.io/) CLI with the Atmos
toolchain. For the skill's decision guide, see [../SKILL.md](../SKILL.md). For the full toolchain
feature reference, see [atmos-toolchain](../../atmos-toolchain/SKILL.md).

## Overview

The Atmos toolchain reimplements the Aqua registry YAML schema with its own parser. It does not
use the Aqua Go SDK. The toolchain understands the same `pkgs/` registry format as Aqua. However,
the toolchain supports only a **subset** of the schema. It is **not** a full reimplementation.

Migration is mechanical for plain GitHub-release packages. Migration is not purely mechanical for
packages that use the schema features listed in Functional Gaps below. Check each package against
that table before you assume a 1:1 port.

## Before / After

**Before** (`aqua.yaml`):
```yaml
registries:
- type: standard
ref: v4.245.0 # renovate: depName=aquaproj/aqua-registry

packages:
- name: hashicorp/terraform
version: v1.9.8
- name: kubernetes-sigs/kubectl
version: v1.28.0
- name: jqlang/jq
version: v1.7.1
```
Aqua also generates `aqua-checksums.json`. This file records checksums for supply-chain
verification.

**After** (`atmos.yaml` + `.tool-versions`):
```yaml
# atmos.yaml
toolchain:
use_lock_file: true
registries:
- name: aqua
type: aqua
source: https://github.com/aquaproj/aqua-registry/tree/main/pkgs
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
priority: 10
verification:
checksums: when_available
signatures: when_available
```
```text
# .tool-versions
hashicorp/terraform 1.9.8
kubernetes-sigs/kubectl 1.28.0
jqlang/jq 1.7.1
```
```bash
atmos toolchain install
```
Atmos also generates a lock file when you set `use_lock_file: true`. By default, Atmos writes it
as `toolchain.lock.yaml` under the toolchain install path. Set `toolchain.lock_file` to choose a
different path, for example a repo-relative path you can commit. This file records the resolved
version and checksum for each tool. It serves the same purpose as `aqua-checksums.json`.

## Steps

1. **Mirror the registry.** Map Aqua's `type: standard` registry with a `ref:` pin to a
`toolchain.registries` entry of `type: aqua`. Point it at
`https://github.com/aquaproj/aqua-registry/tree/main/pkgs`. If `aqua.yaml` used a private or
custom registry, add it as a second `type: aqua` registry entry. Use a `file://` or GitHub
`source` for this entry. Set its `priority` higher than the public registry.
2. **Convert each plain package.** For a `packages:` entry with no unusual fields, run
`atmos toolchain add owner/repo@version`. You can also hand-write the `.tool-versions` line.
Both methods produce the same result.
3. **Flag nonstandard packages.** For any entry that uses a field or package type from the
Functional Gaps table below, do not assume it ports automatically. Follow that row's
workaround. Or leave the tool on Aqua temporarily until the team decides how to handle it.
4. **Replace `aqua-checksums.json` with `toolchain.verification` and `use_lock_file`.** Atmos
verifies packages against checksum and signature metadata published by the registry itself.
Set `checksums` and `signatures` to `when_available`, `required`, or `disabled`. Set
`use_lock_file: true` to also record resolved versions and checksums in `toolchain.lock.yaml`,
for the same reproducibility `aqua-checksums.json` provides.
5. **Verify the migration.** Run `atmos toolchain install`, then run `atmos toolchain list`.
Confirm the resolved versions match what `aqua list` reported before.

## Command Mapping

| aqua command | Atmos toolchain equivalent |
|---|---|
| `aqua install` | `atmos toolchain install` |
| `aqua install github.com/hashicorp/terraform@v1.9.8` (ad hoc) | `atmos toolchain install hashicorp/terraform@1.9.8` |
| `aqua g -i` (generate + insert into `aqua.yaml`) | `atmos toolchain add owner/repo@version` (writes to `.tool-versions`) |
| `aqua list` | `atmos toolchain list` |
| `aqua which terraform` | `atmos toolchain which terraform` |
| `aqua exec -- terraform plan` | `atmos toolchain exec terraform@<version> -- plan` (direct third-party use only). `atmos terraform plan` already resolves the toolchain automatically. Do not wrap it in `atmos toolchain exec`. |
| `aqua update-checksum` | No separate command. `toolchain.verification` handles this automatically at install time. |

## Shell Integration

Aqua uses the same shim-based method as asdf. Add `export PATH="$(aqua root-dir)/bin:$PATH"` to
`~/.bashrc` or `~/.zshrc`. This puts Aqua's proxy directory on `PATH`. `aqua-proxy` resolves the
nearest `aqua.yaml` again on every invocation. As a result, plain `terraform` always resolves
correctly in any shell. This method needs no per-project setup.

**The Atmos toolchain does not do this by default.** Atmos resolves tools declared in
`dependencies.tools` and injects them into `PATH` only for the duration of one
`atmos <subcommand>` invocation. If you run plain `terraform` in your shell, it will not use the
Atmos-managed version unless you opt in to shell integration. This is a **supported mode**, not a
limitation. Use `atmos toolchain env` to export the resolved `PATH` into your interactive shell:

**Bash** (add to `~/.bashrc`):
```bash
eval "$(atmos toolchain env --format=bash)"
```

**Zsh** (add to `~/.zshrc`):
```zsh
eval "$(atmos toolchain env --format=bash)"
```
Atmos has no separate `--format=zsh` option. The `bash` format emits plain POSIX
`export PATH=...`. Zsh evaluates this output the same way.

**Fish** (add to `~/.config/fish/config.fish`):
```fish
atmos toolchain env --format=fish | source
```

**PowerShell** (add to `$PROFILE`):
```powershell
Invoke-Expression (atmos toolchain env --format powershell | Out-String)
```

Verify with `which terraform` (use `Get-Command terraform` on PowerShell). It must resolve under
the Atmos toolchain install directory, not Aqua's proxy directory.

**Important: this method takes a static snapshot, not Aqua's dynamic per-directory resolution.**
`aqua-proxy` resolves the nearest `aqua.yaml` again on every command. As a result, when you `cd`
into a different project, Aqua automatically switches versions. `atmos toolchain env` bakes the
resolved paths of the current directory into `PATH` one time, at eval time. It does not update
automatically when you `cd`. Re-run the `eval` line after you switch projects. Or use
`atmos terraform ...` instead of bare `terraform` when you work across multiple projects.
`atmos terraform ...` always resolves per invocation, regardless of shell state.

**Atmos also has a direct equivalent to `aqua-proxy`: `toolchain.proxies`.** Configure a proxy to
expose a toolchain tool under a command name that differs from the tool's own binary name. Atmos
creates a link in `${toolchain.install_path}/bin/proxy`. That link re-invokes Atmos under the
configured command name. Atmos then resolves the tool, installs it if needed, and forwards the
arguments. `atmos toolchain env` puts this proxy directory on `PATH` when you configure at least
one proxy. Use this when a package name differs from the command name, for example a multicall
binary such as `coreutils` that must run under the name `ls`. You do not need a proxy for the
common case, where the tool's binary already has the name you want to type. In that case, the
direct `PATH` export above already provides it. The
[atmos-toolchain](../../atmos-toolchain/SKILL.md) skill does not yet cover `toolchain.proxies` in
depth; see [Toolchain Proxies](https://atmos.tools/cli/configuration/toolchain/proxies) for the
full reference.

## Functional Gaps

### Planned

| Aqua package type | Status | Workaround until it lands |
|---|---|---|
| `github_archive` | In progress. [PR #2416](https://github.com/cloudposse/atmos/pull/2416) adds this feature. It resolves to `https://github.com/{owner}/{repo}/archive/refs/tags/{version}.tar.gz`, matching upstream Aqua semantics. | Hand-port to a `type: atmos` inline registry entry (`http` type pointed at the archive URL). Or leave the tool on Aqua until the PR merges. |
| `github_content` | In progress. [PR #2416](https://github.com/cloudposse/atmos/pull/2416) also adds this feature. | Hand-port to a `type: atmos` inline registry entry (`http` type pointed at the raw file URL). Or leave the tool on Aqua until the PR merges. |

Check whether PR #2416 has merged before you tell a user these types are unsupported. If it has
merged, treat both types as supported and remove this section. The Not Supported table below
still applies.

### Not Supported

Atmos intentionally does not support the following Aqua schema features. These come from the
"Unsupported Aqua Features" list in [atmos-toolchain](../../atmos-toolchain/SKILL.md).

| Aqua feature | Why it does not port directly | Workaround |
|---|---|---|
| `go_build` package type | Not implemented. Atmos does not build tools from source. | Use a pre-built release if the project publishes one. Add it via a `type: atmos` inline registry. |
| `cargo` package type | Not implemented. Atmos has no Cargo or crates.io installer. | No direct equivalent exists. Source the binary another way. |
| `version_filter` / `version_prefix` | Atmos does not support version-string manipulation. | Pin an exact version. Or normalize the version with `toolchain.aliases`. |
| `version_expr` / `version_expr_prefix` | Same as above. | Same as above. |
| `go_version_file` | Atmos does not support reading a version from a Go source file. | Pin the version explicitly in `.tool-versions`. |
| `import` | Atmos does not support Aqua's registry-composition mechanism. | Add multiple `toolchain.registries` entries instead of one registry that imports others. |
| `command_aliases` | Atmos does not support this Aqua field. | Use `toolchain.aliases` in `atmos.yaml` instead. |
Comment thread
osterman marked this conversation as resolved.
Outdated
| `tags` | Not supported. | No equivalent exists. Atmos does not filter installs by tag. |
| `vars` | Atmos does not support Aqua's per-package template variables. | Hard-code the value into the `url` template of a `type: atmos` inline registry entry. |

## Worked Example

This mixed `aqua.yaml` file shows both cases:
```yaml
packages:
- name: hashicorp/terraform # plain GitHub release -- migrates cleanly
version: v1.9.8
- name: some-org/custom-tool # uses go_build -- needs manual porting
version: v2.1.0
```

`hashicorp/terraform` becomes `atmos toolchain add hashicorp/terraform@1.9.8`. For
`some-org/custom-tool`, add a `type: atmos` inline registry entry that points at a pre-built
release asset, if one exists. Otherwise, leave it out of scope for this migration pass.

## Cross-Links

- [atmos-toolchain SKILL.md](../../atmos-toolchain/SKILL.md): the Registries section and the
"Unsupported Aqua Features" list. The Not Supported table above comes from this list.
- [PR #2416](https://github.com/cloudposse/atmos/pull/2416): adds `github_archive` and
`github_content` package-type support. Check its merge status before you cite the Planned table
above as still accurate.
- [atmos-toolchain commands-reference.md](../../atmos-toolchain/references/commands-reference.md):
covers `atmos toolchain add`, `registry list`, `registry search`.
Loading