ginokent Blog
About RSS EN

versenv: 環境変数でツールのバージョンを管理するラッパースクリプト

開発の動機

チーム開発で kubectl や Terraform を使っていると、大抵はこんな問題に直面します。

  • プロジェクトごとに異なるバージョンの kubectl を使いたい
  • チームメンバーが異なるバージョンをインストールしている
  • 「正しいバージョンをインストールしてください」と毎回説明するのが面倒
  • 説明しても、正しいバージョンがインストールされているとは限らない

これらの問題を解決するために、環境変数でツールのバージョンを制御できるラッパースクリプト集を作りました。

versenv/versenv

概要

versenv は、kubectl, Terraform, Helm などの CLI ツールのラッパースクリプト集です。

各スクリプトは環境変数で指定されたバージョンの実行ファイルを自動的にダウンロードしてキャッシュし、元のコマンドと同じように動作します。

# 環境変数でバージョンを指定して実行
KUBECTL_VERSION=1.23.5 ./kubectl version --client

初回実行時は指定バージョンがダウンロードされ、2 回目以降はキャッシュされたバイナリが使われます。

対応ツール

主要なツール:

ツール環境変数
direnvDIRENV_VERSION
kubectlKUBECTL_VERSION
terraformTERRAFORM_VERSION
helmHELM_VERSION
packerPACKER_VERSION
aws (v2)AWSCLI_VERSION
protocPROTOC_VERSION
sopsSOPS_VERSION
gitleaksGITLEAKS_VERSION

その他、 buf, tflint, fzf など 20 以上のツールをサポートしています。

インストール

個別にダウンロード

curl --tlsv1.2 -#fLR https://raw.githubusercontent.com/versenv/versenv/HEAD/bin/kubectl -o ./kubectl && chmod +x ./kubectl

一括インストール

curl --tlsv1.2 -fLRSs https://raw.githubusercontent.com/versenv/versenv/HEAD/install.sh | VERSENV_PATH=./bin bash

特定のツールだけをインストールしたい場合は VERSENV_SCRIPTS を指定します。

curl --tlsv1.2 -fLRSs https://raw.githubusercontent.com/versenv/versenv/HEAD/install.sh | \
  VERSENV_SCRIPTS=kubectl,terraform VERSENV_PATH=./bin bash

使い方

基本的な使い方

# バージョンを指定して実行
KUBECTL_VERSION=1.23.5 ./kubectl version --client

# latest や stable を指定すると最新安定版を使用
KUBECTL_VERSION=latest ./kubectl version --client

# 環境変数を指定しないと、最新安定版が自動的に選択される
./kubectl version --client

direnv との組み合わせ (推奨)

direnv と組み合わせることで、プロジェクトごとにツールのバージョンを固定できます。

# プロジェクトルートに bin ディレクトリを作成してスクリプトを配置
cd "$(git rev-parse --show-toplevel)"
curl --tlsv1.2 -fLRSs https://raw.githubusercontent.com/versenv/versenv/HEAD/install.sh | \
  VERSENV_SCRIPTS=kubectl,terraform VERSENV_PATH=./bin bash

# .envrc でバージョンを固定
cat <<'EOF' > .envrc
export PATH="$(git rev-parse --show-toplevel)/bin:$PATH"
export KUBECTL_VERSION=1.23.5
export TERRAFORM_VERSION=1.1.8
EOF

direnv allow .

これで、このプロジェクトディレクトリに入ると自動的に指定バージョンが使われるようになります。.envrc を Git でコミットすれば、チーム全員が同じバージョンを使えます。

特殊機能

KUBECTL_CONTEXT による context 切り替え

kubectl, helm, stern では KUBECTL_CONTEXT 環境変数で context を自動的に切り替えられます。

KUBECTL_CONTEXT=gke_myproject_us-central1_alpha kubectl get pods
# => kubectl --context=gke_myproject_us-central1_alpha get pods として実行される

self-update

スクリプト自身を最新版に更新できます。

./kubectl versenv self-update

利用可能なバージョンの確認

# 全バージョンを表示
./kubectl versenv versions

# 安定版のみ表示
./kubectl versenv stables

仕組み

各ラッパースクリプトは以下の流れで動作します。

  1. 環境変数からバージョンを取得 (未設定なら最新安定版を自動解決)
  2. ~/.cache/versenv/{ツール名}/{バージョン}/bin/ にバイナリがあるか確認
  3. なければ公式サイトからダウンロードしてキャッシュ
  4. キャッシュされたバイナリを exec で実行

依存関係は curl (または wget) のみで、単一の Bash スクリプトとして動作します。

なぜ versenv を使うのか

versenv の最大の強みは、ただの薄いシェルスクリプトであるということです。

プロジェクトの bin/ ディレクトリにスクリプトをコミットし、.envrc で PATH を通すだけで、リポジトリをクローンした人は誰でも同じ環境を使えます。asdf や mise のような外部ツールを事前にインストールしてもらう必要はありません。

your-project/
├── bin/
│   ├── kubectl    # Git にコミット
│   └── terraform  # Git にコミット
└── .envrc         # PATH と VERSION を設定

新しいメンバーがプロジェクトに参加したとき、必要な作業は git clonedirenv allow だけです。「まず asdf をインストールして、プラグインを追加して…」という説明は不要になります。

既存のバージョン管理ツール (asdf, mise など) との違い:

  • 事前インストール不要: リポジトリに含まれているので clone するだけ
  • 依存関係が最小限: curl と bash だけで動作
  • 透過的な動作: 元のコマンドと同じように使える
  • CI/CD フレンドリー: 環境変数でバージョンを制御できるため、CI 環境でも簡単に使える

「チームメンバーに何かをインストールしてもらう」という手間を省きたいときに便利です。