この記事は Retty Advent Calendar 2022 Part1 の14日目の記事です。昨日は今井さんの『ストーリーポイント定規を作ってみた』でした。
今年も Part2 があるのでこちらもよろしくお願いします。自分は Part2 の16日にも記事を書きます。
はじめに
Retty インフラチームの幸田です。締め切りの仕事が増えて年末を感じています。
日々の業務で様々な CLI ツールを利用していると思いますが、それらのツールはどのようにインストールし、管理していますか?管理方法は色々ありますが、brew や apt などのパッケージマネージャーを利用している方が多いのではないでしょうか。
自分も様々なツールを brew で入れることが多かったのですが、最近は aqua という CLI Version Manager に寄せていて、対応していないツールのみを brew で管理することにしています。
今回の記事では aqua を布教するべく、主要機能や推しポイントを紹介しようと思います。
aqua について
aqua は YAML ファイルを用いてツールとバージョンを宣言的に記述できる CLI Version Manager です。CLI Version Manager というと聞き慣れないかもしれないですが、有名なツールとして asdf-vm/asdf が挙げられます。また特定の言語やツールでよくある XXenv (tfenv, rbenv, pyenv..) 系のツールも広義ではその仲間だと思っています。
aqua はどちらかというと asdf に近いツールで、公式ドキュメントでもその違いや Pros / Cons が言及されています。
チュートリアル
説明するよりも実際に見たほうが早いと思うのでどのように動作するのかを紹介したいと思います。概ね Quick Start の通りです。
1. aqua のインストール
まずは aqua 自体のインストールが必要です。Mac ユーザであれば brew
で入れてしまうのが早いかと思います。
brew install aquaproj/aqua/aqua
続いて PATH の設定です。
この $XDG_DATA_HOME/.local/share/aquaproj-aqua/bin
配下に様々なコマンドが足されていくイメージです。*1
export PATH="${AQUA_ROOT_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/aquaproj-aqua}/bin:$PATH"
インストールはこれで完了します。
$ aqua -v aqua version 1.25.0 (9a544d686c6b7898596dd4a44cd04bd3a2782473)
docker を使ったチュートリアル も紹介されているので、手元の環境を汚したくないという方はこちらがオススメです。
2. ツールの追加
aqua
コマンドの準備が完了したので、実際にツールのインストールをしてみたいと思います。
2.1 Registry とは
aqua で利用可能なツールは Registry によって管理されます。Registry は自分で作ることもできますが、公式から Standard Registry と呼ばれるものが公開されています。
公開されていない社内ツールを利用したいなどの特殊なケースを除いて、基本的にはこの Standard Registry を利用する形で問題ないと思います。
記事執筆時点での最新バージョンである Standard Registry v1.102.0 では 967 種類の CLI ツールが利用可能です。
2.2 aqua.yaml
の生成
aqua で利用するツールは aqua.yaml
で管理します。aqua init
を実行することでファイルを自動生成することができます。
$ aqua init $ cat aqua.yaml --- # aqua - Declarative CLI Version Manager # https://aquaproj.github.io/ # checksum: # # https://aquaproj.github.io/docs/reference/checksum/ # enabled: true # require_checksum: true registries: - type: standard ref: v3.102.0 # renovate: depName=aquaproj/aqua-registry packages:
registries:
にはデフォルトで Standard Registry が使用され、その時点での最新バージョンが設定されます。
このファイルの packages:
にツールを追加していきます。
2.3 aqua generate
によるツールの追加
aqua.yaml
へのツールの追加は、手動で書くこともできますが aqua generate -i
コマンドを利用すると便利です。short command の場合は aqua g -i
です。
このコマンドを利用すると下記のように fzf like *2な検索画面でツールを検索することができて、選択すると aqua.yaml
の packages に自動で追記してくれます。(-i
オプションは aqua.yaml
に追記するためのオプション)
GoogleContainerTools/skaffold ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ GoogleContainerTools/kpt │ 1xyz/pryrite GoogleContainerTools/container-structure-test │ GoogleContainerTools/container-diff │ https://github.com/1xyz/pryrite GoogleCloudPlatform/terraformer/aws [terraformer] │ Pryrite, interactively execute shell code blocks GoogleCloudPlatform/terraformer │ in a markdown file GoogleCloudPlatform/cloud-sql-proxy │ GoogleCloudPlatform/berglas │ GoodwayGroup/gwvault │ GoTestTools/gotestfmt │ FiloSottile/mkcert │ FiloSottile/age [age, age-keygen] │ FairwindsOps/rbac-lookup │ FairwindsOps/polaris │ FairwindsOps/pluto │ FairwindsOps/nova │ EdenEast/repo │ Dreamacro/clash │ DelineaXPM/dsv-cli (thycotic/dsv-cli) [dsv]: secrets .. │ ClementTsang/bottom [btm] │ CircleCI-Public/circleci-cli [circleci] │ Cian911/switchboard │ BurntSushi/ripgrep [rg] │ BishopFox/cloudfox │ BeryJu/korb │ Azure/draft │ Azure/aztfy │ Azure/aks-engine │ Arriven/db1000n │ Aloxaf/silicon │ 99designs/aws-vault │ > 1xyz/pryrite │ 967/967 │ > └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
例として GitHub の CLI ツール (gh
) である cli/cli を選択すると、aqua.yaml
は次のようになります。
$ cat aqua.yaml --- # aqua - Declarative CLI Version Manager # https://aquaproj.github.io/ # checksum: # # https://aquaproj.github.io/docs/reference/checksum/ # enabled: true # require_checksum: true registries: - type: standard ref: v3.102.0 # renovate: depName=aquaproj/aqua-registry packages: - name: cli/cli@v2.20.2
packages:
に - name: cli/cli@v2.20.2
が足されました。
3. ツールのインストールと実行
aqua.yaml
にファイルを追加したら aqua i
コマンドを利用してツールをインストールします。
aqua i
これで gh
コマンドを利用する準備が整ったので実行してみます。
$ gh --version gh version 2.20.2 (2022-11-15) https://github.com/cli/cli/releases/tag/v2.20.2
gh
コマンドが正常に実行され、さらにバージョンは指定した 2.20.2
が実行されていることが確認できました。
aqua のここが便利!
ざっくりとした使い方が紹介できたので、ここからは便利ポイントを紹介します。
バージョンの指定、切り替えが簡単にできる
aqua の場合には、ツールのバージョンも合わせて YAML ファイルに記載することになっているので、このバージョンを変更するだけで簡単にツールのバージョンを切り替えることができます。
$ cat aqua.yaml | grep cli/cli - name: cli/cli@v2.20.2 $ gh --version gh version 2.20.2 (2022-11-15) https://github.com/cli/cli/releases/tag/v2.20.2 # aqua.yaml に記載されている cli/cli のバージョン v2.19.0 に切り替え $ cat aqua.yaml | grep cli/cli - name: cli/cli@v2.19.0 $ gh --version gh version 2.19.0 (2022-11-03) https://github.com/cli/cli/releases/tag/v2.19.0
言語のランタイム以外でバージョンを切り替えたい、もしくは指定されたバージョンで動かしたいケースはあまりないかと思いますが、下記のようなケースで有用だと思っています。
- CI 環境で各種ツールを利用するケース(CI 環境での利用は後述します)
- チーム開発でメンバーとツールのバージョンを揃えたいケース
バージョン切り替え時の挙動について
既にそのツールが aqua i
によってインストールされており、バージョンのみ切り替わった場合には再度 aqua i
をする必要はありません。これは aqua の Lazy Install の機能によるものです。
下記のように、指定されたバージョンが実行環境に存在しない場合には、実行時に自動的にインストールされます。
# cli/cli v2.20.2 がインストールされていない状態で実行 $ gh --version INFO[0000] download and unarchive the package aqua_version=1.25.0 env=darwin/amd64 exe_name=gh exe_path=/Users/username/.local/share/aquaproj-aqua/pkgs/github_release/github.com/cli/cli/v2.20.2/gh_2.20.2_macOS_amd64.tar.gz/gh_2.20.2_macOS_amd64/bin/gh package=cli/cli package_name=cli/cli package_version=v2.20.2 program=aqua registry=standard gh version 2.20.2 (2022-11-15) https://github.com/cli/cli/releases/tag/v2.20.2
バージョンの指定について
aqua.yaml
には必ずバージョンを指定する必要があり、@latest
のような指定はできません。これは aqua の思想によるものだと思われます。
On the other hand, aqua doesn't support specifying latest because aqua is CLI Version Manager. You must specify the version strictly.
https://aquaproj.github.io/blog/2022/05/30/support-building-go-tools/#can-we-specify-latest-like-go-install
場合によっては不便に感じるかもしれませんが「知らない間にバージョンが上がって挙動が変わった」といったトラブルを防ぐことができるため、個人的には便利に感じています。
aqua generate -s
の利用
ツール追加時の aqua g
でもバージョンを選択することができて aqua g -i -s
のように -s
をつけると、ツールを選択した後にバージョンのリストが表示されて、バージョンも fzf like に検索、指定できます。
v2.6.0 │ v2.20.2 (GitHub CLI 2.20.2) v2.7.0 │ v2.8.0 │ https://github.com/cli/cli/releases/tag/v2. . v2.9.0 │ ## What's Changed v2.10.0 │ * Fix up Linux packaging regression by v2.10.1 │ @samcoe in https://github.com/cli/cli/p v2.11.0 │ ull/6621 v2.11.1 │ v2.11.2 │ v2.11.3 │ **Full Changelog**: https://github.com/ v2.12.0 │ cli/cli/compare/v2.20.1...v2.20.2 v2.12.1 │ v2.13.0 │ v2.14.0 │ v2.14.1 │ v2.14.2 │ v2.14.3 │ v2.14.4 │ v2.14.5 │ v2.14.6 │ v2.14.7 │ v2.15.0 │ v2.16.0 │ v2.16.1 │ v2.17.0 │ v2.18.0 │ v2.18.1 │ v2.19.0 │ v2.20.0 │ v2.20.1 │ > v2.20.2 │ 88/88 │ > └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
aqua.yaml
による設定の共有ができる
チュートリアルで説明したように aqua.yaml
で利用するツールやバージョンを指定します。そのため aqua.yaml
を共有することで、環境が異なるマシンでも同様のツール、同様のバージョンを用意することができます。
複雑なインストール作業は不要で、aqua さえあれば aqua i
を実行するだけで使えるようになります。
このファイルを Git 管理すれば、他のメンバーとツールやバージョンを共有できますし、CI でも aqua を利用することで CI 環境とローカルでツールのバージョンを揃えるといったこともできるようになります。
設定ファイルの読み込みについて
Configuration file path に記載されていますが、aqua はカレントディレクトリからルートディレクトリまでのファイルを探索するため、カレントディレクトリの aqua.yaml
が優先して利用されます。
例えばモノレポ構成の場合、ディレクトリ毎に aqua.yaml
を配置することでプロジェクトによってバージョンを固定したり切り替えたりすることができます。
手元の CLI ツールを管理したい場合には AQUA_GLOBAL_CONFIG
を設定することで、カレントディレクトリに aqua.yaml
がなくとも利用できるため、dotfiles 的に利用したい場合にはこちらを設定すると良いでしょう。(Global Configuration)
Renovate によるバージョンアップに対応
aqua は Renovate によるバージョンのアップデートに対応しています。個人的に一番の推しポイントです。
https://aquaproj.github.io/docs/tutorial-extras/renovateaquaproj.github.io
使い方は簡単で renovate.json
に下記を追記するだけです。
{ "extends": [ "github>aquaproj/aqua-renovate-config#1.2.6" ] }
Renovate には RegexManager と呼ばれる機能があり、カスタムの設定ファイルを記述することで、正規表現をベースに任意のファイルに記載されたバージョンを Renovate でアップデートさせることができます。
aqua ではこの RegexManager の設定が公式で提供されており、上記のようにこの設定を読み込むことで aqua.yaml
などのファイルを自動で更新させることができます。(renovate.json
のバージョンも自動で更新されます)
https://aquaproj.github.io/docs/tutorial-extras/renovateaquaproj.github.io
今まで自前で RegexManager の設定を書いていた箇所も aqua + 公式の Preset Config に置き換える事によって、消すことができました。もちろん新しいツールを追加した場合にも自前の設定は不要です。
社の Terraform CI で aqua を使うようにしてみた。regex manager の設定が消せて便利
— Yuya Koda (@ponkio_o) 2022年8月24日
新規ツールの追加が簡単
Standard Registry には毎日のように新しいツールが足されています。(Pull Request 一覧)
主要なツールはカバーされている印象ですが aqua g
で検索しても出てこない場合には、aqua-registry に PR を出すことでツールの追加が可能です。
registry-tool の使用
まだ対応していないツールを Standard Registry で利用したい場合には、aqua-registry
と呼ばれるコマンドを利用することで簡単に追加することができます。
CONTRIBUTION.md にある通りですが、(追加するツール次第では)下記コマンドを実行するだけで Standard Registry へのツールの追加から PR の作成までを行うことができます。
$ aqua-registry scaffold cli/cli $ aqua-registry create-pr-new-pkg cli/cli
ツールによっては生成されたファイルの細かい手直しが必要になるので、公式ドキュメントに従って修正を行います。
PR マージ後に新しい Registry のバージョンがリリースされ、手元の aqua.yaml
にバージョンを反映するとインストール可能になります。もちろん Renovate によるアップデートにも対応されます。
ユースケース
特に凝った使い方はしていないですが、会社や個人でどう使っているかを紹介します。
CI での利用
先月公開した記事でも書きましたが、Terraform の CI/CD に aqua を導入しています。
インストール作業の簡易化
CI で利用する linter や各種デプロイツールのインストールは curl
などを利用して GitHub Release からバイナリを落として来るようなパターンが多いかと思いますが、ここでも aqua を利用することができます。必要なツールを記載した aqua.yaml
をリポジトリに入れて、CI 上で aqua i
を実行するだけです。
当然 aqua 自体のインストールは必要ですが、CircleCI Orb と GitHub Actions の Action が提供されているため、これを利用すると便利です。
GitHub Actions の場合には次のようなステップを用意するだけで aqua
コマンドが利用可能になります。
- uses: aquaproj/aqua-installer@v1.1.2 with: aqua_version: v1.25.0
余談ですが、aqua 本体のバージョンを指定するための aqua_version
には latest などのデフォルト値が用意されておらず、必ずバージョンを指定する必要があるのは aqua の思想が感じられて面白いですね。
そして地味に嬉しいのが、GitHub Actions の input として指定する aqua_version
についても提供されている Renovate Config Preset でカバーされており、ここも自前で設定を用意しなくても良いです。便利。
そういえば actions のバージョンは拾われるだろうけど、aqua-installer で指定する aqua_version に関しては自前で regex manager 書かないと。。と思って aqua-renovate-config を見るとちゃんと regex manager が用意されており更に便利!という気持ちになった
— Yuya Koda (@ponkio_o) 2022年8月24日
厳密なバージョン指定
例えば GitHub Actions で各ツール向けに提供されている Action は、バージョンを指定することもできますが、特に指定しない場合にはデフォルトで latest が降ってくるケースが多いかと思います。そしてこのデフォルト値を利用している方も多いのではないでしょうか?
特にバージョンアップ作業などを行う必要もなく、常に最新に追従できるのは大きなメリットだと思いますが、その裏には「実行タイミングによってバージョンが変わってしまう」というデメリットがあると思っています。そう頻繁には起きないですが、新しいバージョンがリリースされて1時間前と今では latest で降ってくるバージョンが違うパターンなどです。
特に CI 環境においては冪等性が担保されるべきだと考えているので、個人的にはあまり望ましくありません。
aqua の場合だと厳密にバージョンを指定できる上に、面倒なバージョンのアップデート作業は Renovate で自動化できるため CI での利用にはよりマッチしていると思います。
dotfiles での利用
冒頭でも書いたように dotfiles に入れてローカルツールの管理にも利用しています。
Renovate の設定で automerge を設定しておくと、アップデートが降ってきた時に勝手に main に反映してくれます。定期的に dotfiles を pull してくる必要はありますが、手元のツールのバージョンを最新の状態に保つことができます。
実際の PR を見てもらえるとイメージが湧くと思います。
各ツールの機能追加時に自分をアサインする
dotfiles に作られる PR は、patch バージョン(≒ 主に bugfix)のアップデートは自動でマージして、minor 以上のアップデートにはレビュアーとして自分をアサインするようにしています。
Renovate が作る PR には Release Notes なども書かれるので、(必ずしも含まれている訳ではないですが)手元で利用している各ツールの機能追加にも気付けるようになりました。
アサインのルールなどは細かく設定可能なので、ドキュメントとにらめっこしながら設定してみてください。
まとめ
今回は CLI Version Manager の aqua について紹介しました。
色々な機能がありますが、Renovate による自動アップデートができる点に一番便利さを感じています。今までツール毎に書いていた RegexManager の設定を消すことができ、ツールを足した際にも追加設定が不要なのはかなり体験がいいです。
簡単に導入できるので皆さんもぜひ使ってみてください。