Google Cloud BuildでSPAのビルドとFirebase Hostingへのデプロイを自動化する
この記事はSpeee Advent Calendar 201819日目の記事です。
前日はyuta_kobayashiによる雑談の効用についてのお話でした。
今日はSPAの継続的デリバリーを手軽に実現できる、
Google Cloud Buildのお話です。
やること
最近、ちょっとしたSPAのデプロイ先としてFirebase Hostingを使うことが多くなってきたが、ローカルでFirebaseプロジェクトの設定をしたり、ビルドやデプロイを手動で実行するのが面倒なので最初にCloud Buildを設定してビルドとデプロイを自動化するようにしている。
以上を自動化する。
参考ドキュメント
ビルドトリガーを使用したビルドの自動化 | Cloud Build | Google Cloud
準備
- Firebaseで新規プロジェクトを作成
- アプリケーションはcreate-react-appで適当に作っておく
Firebaseのセットアップ
firebase-cli を使ってセットアップする
// Firebase CLIでログイン $ firebase login // SPAのプロジェクトディレクトリでfirebaseを初期化 $ firebase init // hostingを選択 ? **Which Firebase CLI features do you want to setup for this folder? Press Space** ❯◉ Hosting: Configure and deploy Firebase Hosting sites // buildディレクトリの内容をdeployする ? **What do you want to use as your public directory?** (public) build // SPAの設定 ? **Configure as a single-page app (rewrite all urls to /index.html)?** (y/N) y
デプロイの確認
念のため、Firebase Hostingにローカルからデプロイできることを確認しておく
$ yarn build $ firebase deploy
Cloud Buildの設定
APIの有効化
コンソールにアクセスしてCloud Build APIを有効にする
FirebaseはGCPと統合するとBlazeプラン(従量)に上がってしまうため、Firebaseのプロジェクトと別にプロジェクトを作ってからCloud Build APIの有効化を行うとよい。
設定
ビルドトリガーの作成
「トリガーの作成」からビルドトリガーを作成する。
cloudbuild.yamlの作成
cloudbuild.yamlを追加する。
ひとまずビルドの動作確認のため、yarn install
と yarn build
の設定のみ書いてcommitし、masterにpushする
steps: - name: 'gcr.io/cloud-builders/yarn' args: ['install'] - name: 'gcr.io/cloud-builders/yarn' args: ['build']
pushして確認
cloudbuild.yamlをcommit、pushしてトリガーの確認を行う。
Cloud Buildのビルド履歴から、ビルドの結果が閲覧できる。 各ビルドステップがグリーンになっていればトリガーが発動し、ビルドが成功している。
Firebaseデプロイのビルドステップを追加する
ここを参考にした
Firebaseのイメージを作成してgcr.ioにsubmitしておく
$ git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git $ cd cloud-builders-community/firebase/ $ gcloud builds submit --config cloudbuild.yaml .
Firebaseトークンの取得
$ firebase login:ci ... ✔ Success! Use this token to login on a CI server: [GENERATED_TOKEN] // 生成されたトークンが表示される // 後で使うのでexportしておく $ export FIREBASE_TOKEN=[GENERATED_TOKEN]
KMSでトークンを暗号化
KMSの有効化
https://console.cloud.google.com/security/kms の「セットアップ」でAPIを有効にする
Cloud BuildのサービスアカウントにKMS復号の権限を追加
トークンの暗号化
$ gcloud auth login $ gcloud config set project [PROJECT_ID] $ gcloud kms keyrings create cloudbuilder --location global $ gcloud kms keys create firebase-token --location global --keyring cloudbuilder --purpose encryption $ echo -n $FIREBASE_TOKEN | gcloud kms encrypt \ --plaintext-file=- \ --ciphertext-file=- \ --location=global \ --keyring=cloudbuilder \ --key=firebase-token | base64 [ENCRYPTED_TOKEN]
表示されたトークンをコピーしておく
cloudbuild.yamlにステップを追加
steps: - name: 'gcr.io/cloud-builders/yarn' args: ['install'] - name: 'gcr.io/cloud-builders/yarn' args: ['build'] - name: 'gcr.io/$PROJECT_ID/firebase' args: ['deploy', '--project=$PROJECT_ID'] secretEnv: ['FIREBASE_TOKEN'] secrets: # kmsKeyNameの中では$PROJECT_IDが使えないので直接書く必要あり - kmsKeyName: 'projects/[PROJECT_ID]/locations/global/keyRings/cloudbuilder/cryptoKeys/firebase-token' secretEnv: FIREBASE_TOKEN: '[ENCRYPTED_TOKEN]' # ここにさきほどコピーしたトークンをペースト
余談: create-react-appの環境変数
ビルドトリガーにはsubstitution(代入変数)という形で変数を定義できるが、そのまま環境変数としてロードされるわけではないので env
を使ってsubstitution -> 環境変数への変換を行う必要がある
ビルドトリガーで上記のようにsubstitutionを設定し、cloudbuild.yamlで下記のようにして利用する
steps: - name: 'gcr.io/cloud-builders/yarn' args: ['install'] - name: 'gcr.io/cloud-builders/yarn' args: ['build'] env: # substitutionをenvに渡す - 'REACT_APP_GOOGLE_MAPS_API_KEY=$_GOOGLE_MAPS_API_KEY' ... substitutions: _GOOGLE_MAPS_API_KEY: your-api-key
確認
以上の設定を行い、cloudbuild.yamlをcommitしてGitHubにpushすればビルドが開始される
まとめ
現在実運用しているプロジェクトでは、複数のビルドトリガーを用意し、
devブランチへのpushを開発環境に即反映、releaseブランチにpushしたら本番にデプロイといった運用をしている。
ビルドトリガーによって別の cloudbuild.yaml を設定することもできるため、環境に応じて異なるビルドステップを設定することも可能だ。
最近はGitHub Actionsが登場し、同じようなことが実現できるようになったので、そちらも近いうちに試してみたい。
明日はiida-hayatoによるハッカソンの話
お楽しみに!