⛅️

【GCP】Cloud Buildを触ってみた

2021/04/04に公開

Cloud Buildとは

Cloud BuildとはCI/CDを簡単にできるGCPのサービスです。
似たようなサービスとしてはGitHub Actions, CircleCI, AWS CodeBuild等があります。

Cloud BuildがGCPのサービスのため、GCPで構成しているサービスの場合、サービスアカウントで権限管理をすることができます。
もし、GitHub ActionsやCircleCIなどでデプロイを行いたい場合、IAMを作成してクレデンシャルファイルを取得して、各サービスに配置する必要がでてくると思います。しかしデプロイで必要な権限は強いものが多いので、クレデンシャルの管理コストやリスクを考えるとCloud Buildを使用したほうが安全になることがあります。

今回、firebaseのアプリをデプロイして、Cloud Buildの動きを確認しました。
確認したことは下記になります。

  • ローカルからCloud Buildを使ってデプロイ
  • GitHubのpushトリガーでデプロイ
  • 環境変数を与えて、手動デプロイ
  • ローカルのCloud Buildを使用してデプロイ

事前準備

プロジェクト作成

今回はfirebase initで作成されたプロジェクトを使って確認していきます。

選択項目は下記のようにしました。

$ firebase init
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. Firestore: Deploy rules and create indexes for Firestore, Functions: Configure and deploy Cloud Functions, Hosting: Configure 
and deploy Firebase Hosting sites, Storage: Deploy Cloud Storage security rules
? Please select an option: Use an existing project
? Select a default Firebase project for this directory: ${PROJECT_ID} (cloudbuild-tutorial)
? What file should be used for Firestore Rules? firestore.rules
? What file should be used for Firestore indexes? firestore.indexes.json
? What language would you like to use to write Cloud Functions? TypeScript
? Do you want to use ESLint to catch probable bugs and enforce style? Yes
? Do you want to install dependencies with npm now? Yes
? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No
? Set up automatic builds and deploys with GitHub? No
? What file should be used for Storage Rules? storage.rules

✔  Firebase initialization complete!

この時点でFirebaseのデプロイができるかを確認します。

index.tsの関数をコメントアウトを外して、firebase deployをします。
Deploy complete!がでれば成功しています。

必要なIAM権限を設定

こちらの内容を設定します。

事前にCloud Build, Firebase, and Resource Manager API を有効にします。

また、末尾が@cloudbuild.gserviceaccount.comのサービスアカウントにFirebaseのデプロイで必要な権限を付与します。
今回は編集者権限を付けました。

firebaseのコミュニティビルダーイメージをpush

firebaseをデプロイするには、firebaseコマンドが必要です。
Cloud BuildはDockerコンテナで実行されますが、Firebase コミュニティビルダーイメージが用意されているのでそれを使用します。

https://cloud.google.com/build/docs/deploying-builds/deploy-firebase?hl=ja#using_the_firebase_community_builder

# コミュニティビルダーのリポジトリをクローン
$ git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
$ cd cloud-builders-community/firebase
# イメージをContainer Registryに登録
$ gcloud builds submit .

コンテナイメージはContainer Registryから確認できます。名前がfirebaseのものがアップロードしたものです

ローカルからCloud Buildを実行

CloudBuildではビルド構成ファイルをyamlもしくはjsonで記述します。

firebaseのプロジェクト直下にcloudbuild.yamlを作成します。

steps:
  # ビルドに必要になるpackagesをinstall
  - id: 'Install npm packages'
    name: 'node:12.9-buster'
    args: ['npm', 'install']
    dir: 'functions/'
  # firebaseのデプロイ
  - name: gcr.io/$PROJECT_ID/firebase
    args: ['deploy', '--project=$PROJECT_ID']

細かい設定はこちらのドキュメントから確認できます。
https://cloud.google.com/build/docs/build-config?hl=ja

gcloudから実行することができます。
gcloud builds submit --config cloudbuild.yaml .

これを実行するとディレクトリがCloud Storageにアップロードされて、Cloud Buildが実行されます。

実行ログはCloudBuildの履歴から確認できます。

pushトリガーで実行

次はGitHubのpushトリガーで実行させます。
Cloud Buildのトリガー設定から作成します。

作成できたらFirebaseのプロジェクトをmainブランチにpushします。

履歴を確認するとビルドが開始されることが分かると思います。

また、トリガーから手動実行もできます。

環境変数を使ってdeployする

Firebaseではデプロイするコンポーネントをオプションで指定することが可能です。
次は、実行する際に環境変数を渡して、デプロイコンポーネント指定できるようにします。

環境変数は_から始める必要があります。
https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values?hl=ja#using_user-defined_substitutions

steps:
  - id: 'Install npm packages'
    name: 'node:12.9-buster'
    args: ['npm', 'install']
    dir: 'functions/'
  # _COMPONENTの環境変数によって、実行内容が変わる
  - name: gcr.io/$PROJECT_ID/firebase
    args: ['deploy', '--project=$PROJECT_ID', '--only=$_COMPONENT']

--substitutions のオプションで環境変数を設定できます。
gcloud builds submit --substitutions _COMPONENT=hosting --config cloudbuild.yaml .

これを実行するとhostingだけがビルドされると思います。

Cloud Buildからの実行方法

トリガーの編集から、詳細設定の代入変数を設定します。

実行時に変数を設定できるので、値を設定します。

シェルスクリプトを使用する

より柔軟にシェルスクリプトを使用する方法も確認します。
ビルド構成ファイルは下記になります。

steps:
  - id: 'Install npm packages'
    name: 'node:12.9-buster'
    args: ['npm', 'install']
    dir: 'functions/'
  - name: gcr.io/$PROJECT_ID/firebase
    # bashを実行するよう変更
    entrypoint: 'bash'
    args: ['./deploy.sh']
    # 環境変数をセット
    env:
      - COMPONENT=$_COMPONENT

デプロイスクリプトは下記のようになります。

deploy.sh
#!/bin/sh

echo "deployするよ"
firebase deploy --project=$PROJECT_ID --only=$COMPONENT

ローカルマシンで Cloud Build を使用する方法

Cloud Buildを実行するにはpushしたり、gcloudを使う必要があります。
ローカルマシンで Cloud Buildも使うことが可能であり、迅速にビルドを繰り返し試行錯誤ができるようになります。

https://cloud.google.com/build/docs/build-debug-locally?hl=ja

$ gcloud components install docker-credential-gcr
$ gcloud auth configure-docker
$ gcloud components install cloud-build-local

実行
cloud-build-local --config=cloudbuild.yaml --dryrun=false --substitutions _COMPONENT=hosting --push .

おわりに

本番環境のデプロイをローカルから実施するとソースコードが古いままになっていたり、クレデンシャルが古かったり、実行コマンドのversionがズレてしまうことがあります。CloudBuildを使えば、いつでも同じ環境でデプロイできるので良さそうです。

Discussion