複数の [[Google Cloud]] アカウントを案件ごとに使い分けていると、作業のたびに認証を切り替えるコマンドを打つことになり煩わしい。 direnv と `CLOUDSDK_CONFIG` を組み合わせると、ローカルリポジトリに `cd` するだけで CLI の認証・ADC・プロジェクトがまとめて切り替わるように設定できる。 > [!note] > ADC (Application Default Credentials) は、クライアントライブラリが規定の場所から自動で読み込む認証情報。 > > `gcloud auth application-default login` で保存され、Python の [[BigQuery]] クライアントや [[dbt]] が参照する。 ## 仕組み `CLOUDSDK_CONFIG` は、`gcloud` の設定ディレクトリを丸ごと差し替える公式の環境変数である。アカウント・プロジェクト設定・ADC がすべてこのディレクトリに収まる。 この環境変数は `gcloud` CLI だけでなく、Python のクライアントライブラリ (google-auth 系、dbt-bigquery を含む) も参照する。標準の `gcloud config configurations` と違い、ADC ごと分離できる。 direnv は、ディレクトリ移動をフックして `.envrc` に書いた環境変数を export / unexport するツールである。リポジトリ直下に `.envrc` を置けば、`cd` した瞬間にそのリポジトリのプロファイルへ切り替わり、外に出れば元に戻る。 ## セットアップ ### 1. direnv を導入する ```bash brew install direnv ``` `.zshrc` に hook を 1 行追加する (zsh 以外のシェルは [公式ドキュメント](https://direnv.net/docs/hook.html) を参照)。追記したら、新しいシェルを開くか `source ~/.zshrc` で反映する。 ```bash eval "$(direnv hook zsh)" ``` ### 2. プロファイルを作成する アカウントごとに 1 回だけ実行する。`{{ }}` の部分は自分の値に置き換え、`{{ PROFILE_NAME }}` は案件名ではなくアカウント単位の名前にする。 ```bash PROFILE_DIR="$HOME/.config/gcloud-profiles/{{ PROFILE_NAME }}" CLOUDSDK_CONFIG=$PROFILE_DIR gcloud auth login {{ ACCOUNT_EMAIL }} CLOUDSDK_CONFIG=$PROFILE_DIR gcloud config set project {{ PROJECT_ID }} CLOUDSDK_CONFIG=$PROFILE_DIR gcloud auth application-default login ``` 1 行目と 3 行目でブラウザ認証が開く。 ### 3. リポジトリに .envrc を置く リポジトリ直下に `.envrc` を作り、手順 2 と同じプロファイル名で次の 1 行を書く。 ```bash export CLOUDSDK_CONFIG="$HOME/.config/gcloud-profiles/{{ PROFILE_NAME }}" ``` 書いたら、リポジトリ直下で `direnv allow` を実行して `.envrc` を承認する (編集するたびに再承認が必要)。以降、このリポジトリ配下に `cd` するだけで切り替わり、`gcloud config list` のアカウントとプロジェクトで確認できる。 > [!tip] > `.envrc` は環境依存のファイルなのでコミットせず、グローバル gitignore (`~/.config/git/ignore`) に追加する。 ## git worktree で使う場合 `.envrc` は gitignore 対象なので、git worktree を作っても複製されない。そのままでは worktree 内がデフォルトの認証に落ちるため、作成直後に元リポジトリからコピーして再承認する。 ```bash cp {{ 元リポジトリ }}/.envrc {{ worktree }}/ && direnv allow {{ worktree }} ``` direnv の承認は `.envrc` のパス単位で管理されるため、コピーしただけでは有効にならず `direnv allow` が必ず必要になる。 ## 関連ノート - **[派生]** [[zshrc と zprofile の使い分け]]: direnv の hook を追記する `.zshrc` が読み込まれるタイミングを扱う