Cloud Build で Firebase のリソースをデプロイする
やりたいこと
Firebaseのプロダクトを管理する上で、1つ考慮しなければならないのが、rulesやindexといったインフラリソースの管理です。
リリース前は本番環境のrule更新もCLIで手動実行してもそれほど問題はありませんが、サービスインした後だと本番環境におかしな設定をデプロイしてしまったときの損害が大きくなるため、CI/CDで安全にデプロイするようにしたいです。
今回はCloud Buildを使って、GitHub上のmainブランチにpushがあったら、自動でそれらのインフラリソースがデプロイされるようにします。
Cloud Build Triggerの作成
開発・本番の2環境あるため、環境差異が出ないようにTerraformでCloud Build Triggerを作成します。今回は以下のドキュメントを参考にさせていただきました。
なお、Cloud Buildのアップデートに伴い、プロジェクトの作成時期によって挙動が異なるため、サービスアカウントも別途新規に作成しています。
今回はFirebaseのリソースを操作するため、roles/firebase.admin
の権限をtriggerで使用するアカウントに付与しています。
resource "google_project_iam_member" "firebase_admin" {
project = var.project_id
role = "roles/firebase.admin"
member = "serviceAccount:${google_service_account.cloudbuild_service_account.email}"
}
Firebase CLIをCloud Buildで実行する準備
Cloud BuildでFirebase CLIツールの操作を行うためには、Firebase CLIをDockerイメージとしてArtifact Registryにpushする必要があります。
基本的にはこのドキュメントの流れに沿う形ですが、いくつか落とし穴がありました。
まず、Windowsでgit cloneを実行すると、改行コードがLFからCRLFに変わってしまうため、shファイルが実行できなくなる可能性があります。
Windowsユーザーは改行コードを書き換えないようにautocrlfを無効化してください。この挙動については公式ドキュメントには記載はありませんが、GitHub側には注意書きがあります。
git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git --config core.autocrlf=false
次はcloud buildを実行してArtifact Registryにpushするプロセスですが、実行されるコマンドを見ると最終的にUSリージョンにpushされるようになっています。
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/firebase', '.']
images:
- 'gcr.io/$PROJECT_ID/firebase'
tags: ['cloud-builders-community']
普段からUSリージョンを使っているという場合は問題ありませんが、アジアやヨーロッパのリージョンをcloud buildなど他のリソースで使っている場合は、リージョン間通信で追加コストが発生する可能性があります。
このプロジェクトでもGDPR対応のためにUS以外のリージョンに各種リソースを置いているので、今回はcloudbuild.yaml
を使わずに手動でArtifact Registryにpushすることにしました。
まず、Artifact RegistryにRepositoryを作成します。
gcloud artifacts repositories create firebase \
--repository-format=docker \
--location=asia-northeast1 \
--description="Firebase CLI Docker image"
次に、firebaseのDockerイメージをローカルでビルドします。
cloneしたcloud buildのリポジトリに移動してから、
cd cloud-builders-community/firebase
docker buildコマンドを実行します。
docker build -t asia-northeast1-docker.pkg.dev/{you_project_id}/firebase/firebase .
ローカルにイメージは作成されましたが、手動でArtifact Registryにpushする場合は、Dockerレジストリに対するDockerの認証情報を設定するために以下のコマンドを実行する必要があります。
gcloud auth configure-docker asia-northeast1-docker.pkg.dev
このコマンドを実行すると、~/.docker/config.json
に以下のような設定が追加されます。
{
"credHelpers": {
"asia-northeast1-docker.pkg.dev": "gcloud"
}
}
これで認証は通ったので、Artifact registryにpushします。
docker push asia-northeast1-docker.pkg.dev/{your_project_id}/firebase/firebase:latest
問題なくpushすれば準備は完了です。最後に、cloud buildで使用するyamlもnameの部分をドキュメントのサンプルコードから修正します。
steps:
- name: asia-northeast1-docker.pkg.dev/$PROJECT_ID/firebase/firebase
args:
- 'deploy'
- '--project=$PROJECT_ID'
- '--only=firestore:rules'
timeout: 540s
options:
logging: CLOUD_LOGGING_ONLY
あとは、前述のCloud build triggerと組み合わせることで、mainブランチにマージすると自動でデプロイされるようになります。
もちろん、デプロイ前にローカルでcloud buildの動作確認を行うこともできます。トリガーと同じサービスアカウントで実行するための指定オプションがやや特殊な書き方になっている点に注意してください。
gcloud builds submit \
--region=asia-northeast1 \
--service-account projects/{your_project_id}/serviceAccounts/cloud-build-common-sa@{your_project_id}.iam.gserviceaccount.com \
--config cloudbuild__firebase.yaml \
.
GitHub Actionsでももちろん同じことは実現可能ですが、認証キーの払い出しなどを行わなくて済むので、Cloud Buildを使う方が管理がシンプルになりました。
Discussion