Firebase周りのCI/CDと環境分けについて
はじめに
これは今さらな2021年振り返りカレンダーの5日目の記事です.
前回はBitrise上でExpo OTAを行うワークフローを構築するという内容でした.
今回は,最近の初期アプリにはほとんど使われてそうなFirebase周りのCI/CDと,環境分けについて書いていきます.
CI/CDの対象となるFirebaseのサービスはFirebase Functionです.
また,storageやfirestoreのセキュリティールールのデプロイは環境ごとに対象バケット名が少し変わったりするので,そこをどう分けて管理するかについてです.
仕様
今回は,service-dev,service-prd の2つのfirebase projectがあり,それぞれのために以下を作りたいとします.
- firestore のセキュリティルール及びインデックスのデプロイコマンド
- firebase storage のセキュリティルールのデプロイコマンド
- firebase functions のCI/CD
実装
まず,ディレクトリ構造は以下のようになります.
root/
├── firebase
│ ├── functions
│ ├── .firebaserc
│ ├── firebase_dev.json
│ ├── firebase_prd.json
│ ├── firestore.indexes.json
│ ├── firestore.rules
│ └── storage_assets.rules
├── release
├── dev
│ └── deploy_functions.yaml
└── prd
└── deploy_functions.yaml
セキュリティルールなどのデプロイコマンド
各環境で,どのセキュリティールールをデプロイするかなどを,firebase_{dev|prd}.jsonで管理します.
内容は以下の感じになります.
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"storage": [
{
"rules": "storage_assets.rules",
"bucket": "service-dev-public-assets"
}
]
}
また,デプロイは以下のようなコマンドを用意しておきます.
# ストレージのセキュリティルールのデプロイ
firebase deploy --only storage:rules --config firebase_{dev|prd}.json
# firestoreのセキュリティルール
firebase deploy --only firestore:rules --config firebase_{dev|prd}.json
configを用意したことで毎回それをオプションで指定する必要が出てきますが,常に環境を意識させられるのでまぁいいかぁという印象です.デフォルトはfirebase.jsonを参照するので,devはそれにしてもいいかもしれません.
firebase functions のCI/CD
functions のCI/CDの設定は,release下の各環境ごとのCloud Buildファイルを参照させて行います.
Cloud Buildの設定ファイルの流れは以下のようになっています.
- functionsのコードのビルド
- デプロイ先の環境を設定
- 環境変数,シークレット変数を設定
- デプロイ
シークレット変数は,secret managerに入れておき,Cloud Buildからそれを参照します.
実際のCloud Buildのファイルは以下のような感じです.トリガーのタイミング自体は適当に設定しましょう.
steps:
- id: build_functions
name: node:14.15.4
dir: firebase/functions
entrypoint: bash
args:
- -c
- |
npm i \
&& npm run build
- id: deploy_functions
name: gcr.io/$_PROJECT_ID/firebase
dir: firebase
entrypoint: bash
args:
- -c
- |
firebase use dev --config $_FIREBASE_CONFIG_JSON \
&& firebase functions:config:set slack.channel=$_SLACK_NOTIFICATION_CHANNEL --config $_FIREBASE_CONFIG_JSON \
&& firebase functions:config:set slack.oauth_token=$$SLACK_OAUTH_TOKEN --config $_FIREBASE_CONFIG_JSON \
&& firebase deploy --project=$_PROJECT_ID --only functions --config $_FIREBASE_CONFIG_JSON
secretEnv: ["SLACK_OAUTH_TOKEN"]
timeout: "600s"
substitutions:
_PROJECT_ID: service-dev
_FIREBASE_CONFIG_JSON: firebase_dev.json
_SLACK_NOTIFICATION_CHANNEL: service_dev_notice_test
availableSecrets:
secretManager:
- versionName: projects/service-dev/secrets/service-dev-slack-oauth-token/versions/latest
env: "SLACK_OAUTH_TOKEN"
その他細かい知見など
- firebase functions のCloud Build上でのビルドはコードにエラーが無くてもたまに落ちることがある(nodeのエラーが出てたがよくわからなかった).再実行しやすくしておくとよい.
- GCPのプロジェクト切り替えてもfirebaseは切り替わらないのでデプロイの際は注意.
最後に
内容薄いのですが備忘録として.firebaseも色々terraform化できるようになったら嬉しいな〜と少し思いました.
Discussion