🚒

Cloud Build を使って Firebase Function を Deploy する際の環境変数の取り回し方法

2024/04/07に公開1

解決したい事

  • Firebase Function を Cloud Functions 1nd Gen から 2nd Gen に変更した際に、環境変数の読み込み方法が .runtimeconfig.json からではなく .env からに変わったことで Cloud Build の deploy 時に .env を用意しないといけなくなった
    • functions.config().hoge.fuga ではなく、 defineString('HOGE_FUGA') になった
  • ただし .env を git 管理していないと Cloud Build 内で動的に firebase functions:config:get して .runtimeconfig.json を作ってから、更に .runtimeconfig.json.env に変換して環境変数を認識させる必要があった
  • なので .runtimeconfig.json から .env に環境変数を変換する処理を cloudbuild.yaml 内に無理やり書いて対処することにした

準備すること

jq がインストールしてある firebase-cli のイメージを用意する

公式のドキュメントに記載されている Cloud Build を用いた firebase アプリケーションのデプロイ方法で、 firebase-cli の docker image の作成手順が記載されている。
https://cloud.google.com/build/docs/deploying-builds/deploy-firebase?hl=ja

この手順の中で build する Dockerfile に jq を追加でインストールするように Dockerfile を編集する

FROM node:lts-alpine3.18 AS app-env

# Install Python and Java and pre-cache emulator dependencies.
RUN apk add --no-cache python3 py3-pip openjdk11-jre bash jq && \
    npm install -g firebase-tools && \
    firebase setup:emulators:database && \
    firebase setup:emulators:firestore && \
    firebase setup:emulators:pubsub && \
    firebase setup:emulators:storage && \
    firebase setup:emulators:ui && \
    rm -rf /var/cache/apk/*

ADD firebase.bash /usr/bin
RUN chmod +x /usr/bin/firebase.bash

ENTRYPOINT [ "/usr/bin/firebase.bash" ]

codebuild.yaml に環境変数を変換する step を追加する

以下のように jq を使って .runtimeconfig.json.env ファイルに変換するステップを追加する

steps:
  - name: node:18.2.0
    entrypoint: yarn
    args: ["install"]
    dir: "./functions"
    id: "install"
  - name: gcr.io/$PROJECT_ID/firebase
    entrypoint: 'bash'
    args:
      - '-c'
      - |
        firebase functions:config:get --project=$PROJECT_ID > .runtimeconfig.json
        jq -r '(paths(scalars) as $p | ([$p[] | ascii_upcase | gsub("-"; "_")] | join("_")) + "=\"" + (getpath($p) | tostring) + "\"")' .runtimeconfig.json > .env    
    dir: "./functions"
    id: "config"
    waitFor: ["install"]
  - name: gcr.io/$PROJECT_ID/firebase
    args: ["deploy", "--project=$PROJECT_ID", "--only=functions"]
    dir: "./functions"
    id: "deploy"
    waitFor: ["config"]
timeout: 5500s

この方法で、例えば .runtimeconfig.json の中身が以下のようなファイルだと

{
  "hoge": {
    "fuga1": {
      "piyo": "ABCDE"
    },
    "fuga2": {
      "puyo": "FGHJKL"
    }
  }
}

以下のように .env に変換される

HOGE_FUGA1_PIYO="ABCDE"
HOGE_FUGA2_PUYO="FGHJKL"

これによって Firebase Function の deploy 時に環境変数が正しく認識されて deploy されるようになります。

もし他の正しいやり方がありましたら教えてください 🙏

Discussion