Migrating from Aqua CLI
Aqua CLI is a tool-version manager. It reads a config file named
aqua.yaml.
Read this distinction before you start: Aqua CLI is not the same thing as the Aqua registry.
Atmos does not run the Aqua CLI tool. Atmos does reuse the Aqua registry data format --
the same package listings that Aqua CLI reads. Atmos reimplemented the registry parser itself,
because the Aqua project states that its own Go modules are for internal use, not for external
tools to depend on. This means the registry ecosystem carries over. The aqua.yaml file, the
checksum lockfile, and the policy file do not carry over as-is. See "Common Gotchas" below.
This reference is a scenario-keyed decision guide. It covers only tool-version management: the
migration of aqua.yaml to the Atmos toolchain. It does not cover the migration of Terraform code
itself. For that task, use the other references in this skill.
Identifying the User's Shape
Read the aqua.yaml file, or ask the user to show it to you.
| Shape | Recipe |
|---|---|
aqua.yaml uses the standard registry only | Shape A |
aqua.yaml uses a custom registry, a checksum block, or a policy file | Shape B |
Shape A: Standard Registry Only
Before:
project/├── aqua.yaml└── main.tf
# aqua.yamlregistries:- type: standardref: v4.0.0packages:- name: hashicorp/terraform@v1.10.3- name: jqlang/jq@jq-1.7.1- name: kubernetes/kubectl@v1.28.0
Recipe:
- Add the
toolchain:block toatmos.yaml. Aregistries:entry withtype: standardmaps to atoolchain.registries[]entry withtype: aqua. Carry over theref:pin fromaqua.yaml-- an unpinned registry can change under you the same way an unpinnedref: mainwould. Do not put atree/<ref>segment insource; Atmos treats everything aftergithub.com/<owner>/<repo>as a literal file path, sosourcemust end at the repository (plus an optional subpath likepkgs) and the ref belongs in the separateref:field.toolchain:versions_file: .tool-versionsregistries:- name: aquatype: aquasource: https://github.com/aquaproj/aqua-registry/pkgsref: v4.0.0priority: 10 - Convert each
packages:entry to a.tool-versionsline. The commonname: owner/repo@versionform splits into a short tool name and a version:
If the short name in# .tool-versionsterraform 1.10.3jq 1.7.1kubectl 1.28.0.tool-versionsdoes not match the Aquaowner/reponame, add an alias:toolchain:aliases:terraform: hashicorp/terraformjq: jqlang/jqkubectl: kubernetes/kubectl - Check the migration. Run
atmos toolchain install, thenatmos toolchain list, thenatmos toolchain which <tool>for each tool. Confirm each version matches what Aqua CLI reported.
Shape B: Custom Registry, Checksums, or Policy
This shape builds on Shape A. Do the Shape A recipe first, then add the steps below.
Before:
# aqua.yamlregistries:- type: standardref: v4.0.0- type: github_contentrepo_owner: myorgrepo_name: my-registryref: mainpath: registry.yamlpackages:- name: hashicorp/terraform@v1.10.3- name: myorg/internal-tool@v2.0.0checksum:enabled: truerequire_checksum: true
# aqua-policy.yamlregistries:- type: standardpolicies:- myorg/my-registry/registry.yaml
Recipe:
- Add the custom registry as a second
toolchain.registries[]entry. Usesourcefor the registry location, andrefto pin a version. Atmos acceptsrefonly whensourceis agithub.comURL. Pinrefto a tag or commit SHA, not a branch -- a branch likemainis mutable and can change what gets installed without any change toatmos.yaml. Do not encode the ref as atree/<ref>path segment insource; that breaks tool lookups against this registry (see "Common Gotchas" below). Keepsourceat the repository, plus an optional subpath, and put the ref inref:.toolchain:registries:- name: internaltype: aquasource: https://github.com/myorg/my-registryref: v1.2.0priority: 100- name: aquatype: aquasource: https://github.com/aquaproj/aqua-registry/pkgsref: v4.0.0priority: 10 - Replace the
checksum:block withtoolchain.verification:toolchain:verification:checksums: requiredsignatures: when_availableverifier_install: auto - Drop
aqua-policy.yaml. Atmos has no trust or policy step. See "Common Gotchas" below. - Do not migrate
aqua-checksums.json. Atmos manages its own lockfile,toolchain.lock.yaml. Whether it writes that lockfile automatically depends on the project's edition: unpinned or newer projects get it by default, with no configuration needed. A project whoseatmos.yamlpins an edition dated before2026-08-05keeps the old opt-in behavior and must settoolchain.use_lock_file: trueexplicitly to get the same automatic lockfile. - Check the migration the same way as Shape A.
CLI Command Mapping
| Aqua CLI command | Atmos equivalent | Notes |
|---|---|---|
aqua init | Create the toolchain: block in atmos.yaml by hand | There is no init command. |
aqua install | atmos toolchain install | Installs all tools from .tool-versions |
aqua g / aqua generate | atmos toolchain search <name>, then add a .tool-versions line | Atmos has no interactive picker. |
aqua cp | No direct equivalent | toolchain.install_path gives a predictable local directory, for caching, not for vendoring binaries into another image. |
aqua exec -- <command> | atmos toolchain exec <tool>@<version> -- <command> | Runs one command with a pinned tool version |
aqua which <tool> | atmos toolchain which <tool> | Shows the path to the tool binary |
aqua list | atmos toolchain list | Lists installed tools |
aqua update-checksum | No action needed | Atmos manages toolchain.lock.yaml on its own. |
aqua policy allow [file] | No equivalent | Atmos has no trust or policy step. |
aqua info | atmos toolchain info <tool> | Shows registry metadata for one tool, not full environment diagnostics |
Common Gotchas
The registry format is shared. The CLI tool is not.
Atmos reads Aqua registry package listings. Atmos does not read aqua.yaml directly, and Atmos
does not run the Aqua CLI. Translate aqua.yaml by hand, using the recipes above. Do not expect
Atmos to parse aqua.yaml as config.
No policy or trust-gating step
Aqua CLI uses aqua-policy.yaml and the AQUA_POLICY_CONFIG variable to control which configs
and registries a user trusts, because some Aqua package types run arbitrary build steps or
scripts. Atmos supports only the two safest package types, github_release and http. Atmos
never runs an install script. This removes the need for a trust step. Do not look for a policy
equivalent.
No layered global config
Aqua CLI supports AQUA_GLOBAL_CONFIG, a list of config file paths that apply everywhere, not
just in one project. Atmos has no matching variable. Use the project .tool-versions file for
tools every developer needs, or toolchain.aliases/toolchain.registries in atmos.yaml or in
.atmos.d/.
A broken custom registry fails silently for public tools
If a custom toolchain.registries[] entry can't resolve a tool (wrong source, unreachable
host, tool not present at that path), Atmos does not error. It falls back to searching the
built-in public Aqua registry for that same tool. For a tool that also exists publicly, this
means a misconfigured custom registry produces no visible symptom at all -- the install succeeds,
just from the wrong source. The failure only becomes visible for a tool that exists only in the
custom registry, like the myorg/internal-tool example above, where it fails outright with "tool
not in registry." After adding a custom registry, verify it is actually being used: run
atmos toolchain install with --reinstall and logs.level: Debug in atmos.yaml, and confirm
the log shows Tool found in configured registry, not a Searching builtin registry fallback.
Shims are opt-in, not automatic
Aqua CLI installs a shim for every declared tool automatically, then downloads the real binary
the first time the shim runs. Atmos has an equivalent, toolchain.proxies, but it is opt-in per
command, not automatic for every package in .tool-versions: add a proxies: entry (command
name -> tool) under the toolchain: block, then run atmos toolchain env to activate it in an
interactive shell -- the pinned tool installs on first use, the same lazy-install behavior as an
Aqua shim. See Toolchain Proxies.
Without an explicit proxy entry, Atmos installs a tool when a component, workflow, or command
that declares it runs, or when the user runs atmos toolchain install directly.
Unsupported package types
Atmos does not support these Aqua package types: github_content, github_archive, go_build,
cargo, go_install. If a package in aqua.yaml uses one of these types, find another source
for it, or define an inline type: atmos registry entry with a github_release or http
package type instead. See the atmos-toolchain skill for the
full list of supported and unsupported registry features.
What to NOT Do
- Do not point Atmos at
aqua.yamldirectly. Atmos does not read this file. Translate it by hand, using the recipes above. - Do not look for an Atmos equivalent of
aqua-policy.yamlorAQUA_POLICY_CONFIG. Atmos has no trust step, by design. - Do not try to migrate
aqua-checksums.json. Atmos writes its own lockfile automatically. - Do not use a naive
greponname:lines to convertpackages:entries. This breaks on the common single-linename: owner/repo@versionform. Use the recipe above instead. - Do not introduce Gomplate datasources for things YAML functions can express. See the Core Principles in the SKILL.md.