このサイトの開発レポジトリではBazelでビルドを管理しています。
ビルド最適化の一環としてBazelのremote cacheを設定したので、ログを残しておきます。
キャッシュサーバの選択
https://docs.bazel.build/versions/master/remote-caching.html によれば、自前でキャッシュサーバを用意する方法と、GCPなどのマネージドサービスを利用する方法があるようです。
BazelはGoogleのプロジェクトだけに、デフォルトでGCPのcredentialsを用いて認証するオプションが付いていますので、これを用いるのが一番手っ取り早そうです。 (月数百円程度のコストは掛かってしまいますが)
自宅サーバが遊んでいればそっちを流用してみても良かったかも。
GCPの設定
キャッシュ用のストレージへのアクセス権限と鍵発行を担うアカウントを作成して、ストレージへ紐付けます。
Projectを作成
既存の関連Projectがなければ作成します。
Roleを作ってService Accountに紐付け
Remote cacheにはCloud Storageを使います。
その前にCloud StorageにアクセスするためのService Accountと、Accountに紐付けるRoleを用意します。
Remote cacheのためには、以下の3つの権限が付いていれば良いようです。
storage.objects.get
storage.objects.create
storage.objects.update
次にService Accountを作成して、先程作成したRoleを紐付けます。
Keyを作成
Service AccountからKeyを発行します。
Cloud StorageにBucketを作成
Bucketを作成します。objecgtにはBazelからしかアクセスしないので、Access ControlにはUniformedを設定します。
PERMISSIONSを追加
先程作成したService Accountを追加します。
LifyCycleを設定
キャッシュなのでいつまでも残しておく必要はありません。
Actionに Delete Object
を選択して、conditionsの Age
に適当な期間を入力します。 (私は30日で設定しています)
ローカルに設定
.bazelrcを設定
.bazelrc
に、設定したBucketをremote cacheとして紐付けます。
run --remote_cache=https://storage.googleapis.com/your-bucket-name
run --google_default_credentials
build --remote_cache=https://storage.googleapis.com/your-bucket-name
build --google_default_credentials
test --verbose_failures --remote_cache=https://storage.googleapis.com/your-bucket-name
test --google_default_credentials
これでremote cacheの設定は完了です。
google_default_credentials
はGoogle Cloudへアクセスする際の、 実行環境のデフォルトのService Accountをクレデンシャルとして用いる オプションです。 先程発行したKeyでgcloud
コマンドから認証しておくことで、BazelがBucketへアクセス出来るようになります。
ただしこのためだけにgcloud
コマンドをインストールするのも手間なので、以下のようにKeyを直接クレデンシャルとして設定することも可能です。
--- .bazelrc
+++ .bazelrc
@@ -1,5 +1,3 @@
+try-import %workspace%/dev.bazelrc
# user.bazelrc
run --nogoogle_default_credentials
build --nogoogle_default_credentials
test --nogoogle_default_credentials
run --google_credentials=secrets.json
build --google_credentials=secrets.json
test --google_credentials=secrets.json
ビルドしてみる
設定が正しいか確認してみましょう。
$ npx bazelisk build //...
設定に問題があれば、404系のエラーがログに表示されるはずです。 ビルドが完了したら、Bucketにobjectが出来ているかも確認できます。
GitHub Actionsに設定
最後にCI環境でremote cacheを設定します。 このサイトの 開発レポジトリではGitHub Actionsを使って いますのでそれに応じた作業ログになります。
Secretsに設定
gcloudの設定用actions が提供されているので、こちらを用います。
先程発行したKeyを適当なsecretsに設定して、actionからgcloudが認証出来るようにします。
# GitHub Actionsの設定
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@master
with:
project_id: "your-project-id"
service_account_key: ${{ secrets.GCP_BAZEL_CACHE_KEY }}
export_default_credentials: true
まとめ
以上で設定はすべて完了です。
月ごとの費用感 は数ドル~くらいのようです。
実はこのサイトの開発レポジトリくらいの規模感だと費用対効果はいまいちなのですが、別のレポジトリで各7~8分くらいのaction(がcommit毎に複数)が2~3分くらいにまで短縮されました。