LoginSignup
21
6

GitHub Actionsでfirebaseのdeploy時の認証をトークンからGCPのサービスアカウントに切り替える

Last updated at Posted at 2022-08-16

firebase deploy --token="$FIREBASE_TOKEN"でデプロイすると、

Authenticating with `--token` is deprecated and will be removed in a future major version of `firebase-tools`. Instead, use a service account key with `GOOGLE_APPLICATION_CREDENTIALS`: https://cloud.google.com/docs/authentication/getting-started

と指摘されてしまいます。

CircleCIの値上がりによって、CircleCIからfirebaseにデプロイしていたサイトのCI/CDをGitHub Actionsに乗り換えていたのですが、せっかくなのでこちらの警告にも対応したいと思います。

材料

  • GitHab Actionsのworkflowの設定ファイル(yamlファイル)
  • GCPのサービス アカウントの認証キー(JSONファイル)

workflowの設定ファイルはFIREBASE_TOKENですでにデプロイ可能になっていることを前提としています。

レシピ

1. GCPのサービス アカウントを作成する

firebaseと紐付いているgoogleアカウントで[サービス アカウントの作成] ページを開きます。すでに、Firebaseでプロジェクト作成済みの方は、「Firebaseコンソール」から[プロジェクトの設定] > [サービス アカウント] > [新しい秘密鍵の生成]からでも次のキーを取得まで実施可能です。

image.png

アカウント名もサービスアカウント説明も全部適当でOKです。

アカウントの権限は「Firebase Develop 管理者」にしました。

2. 作成したアカウントからキーを取得

アカウント一覧から作成したアカウントの[キーの管理]を開きます。

スクリーンショット-2022-08-16-16.53.05.png

キーの管理を開いたら中断にある[鍵を追加]を選択

image.png

新しい鍵を作成を選択して、作成形式をJSONにしてください。

作成したらダウンロードが始まるのでローカルの適当なところに保存。

3. キー(JSON)をbase64でエンコード

JSONファイルの扱いですが、認証情報なのでGitHub repositoryのsecretsに登録したいのでbase64で文字列にエンコードします。

cat 〇〇〇〇.json | base64

結果はクリップボードにコピーしておきます。

4. GitHub repositoryのsecretsにエンコード後の認証情報とJSONファイルの生成先を登録

ここからややこしくなっていきます。

対象のレポジトリの[settings]→[secrets]→[actions]から、[New repository secret]を選択して新しいsecretを2つ登録します。

secret 内容
GCLOUD_SERVICE_KEY 先程コピーしたエンコード後の認証情報の文字列
GOOGLE_APPLICATION_CREDENTIALS エンコード後の認証情報をデコードして生成する認証用JSONファイルの保存先・任意で設定できますが今回は先人に習って/tmp/credentials.jsonと指定しました

GCLOUD_SERVICE_KEYは任意の名前で利用可能です。GOOGLE_APPLICATION_CREDENTIALSはこの名前で認証時にローカル変数として読まれるため、この時点からこの名前を使うことをおすすめします。

5. workflowの設定ファイルで4で設定したsecretを環境変数として読み込み

環境変数を設定するためにYAMLファイルの上段で以下のコードを記述して下さい。

        GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
        GCLOUD_SERVICE_KEY: ${{ secrets.GCLOUD_SERVICE_KEY }}

するとこんな感じなります。

jobs:
  deploy:
    env:
      GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
      GCLOUD_SERVICE_KEY: ${{ secrets.GCLOUD_SERVICE_KEY }}
    runs-on: ubuntu-latest

6. CI/CD実行時にエンコード後の認証情報をデコードしてJSONに変換

一番面倒なところです。ローカルでエンコードしたJSONファイルをデコードして復活します。

以下の記述をデプロイ直前に追加してください。

        # 認証情報を保持するjsonファイルをGOOGLE_APPLICATION_CREDENTIALSで指定したpassに生成
      - name: make GOOGLE_APPLICATION_CREDENTIALS
        run: echo $GCLOUD_SERVICE_KEY | base64 -d > $GOOGLE_APPLICATION_CREDENTIALS

7. 普通にデプロイ

ここまでやれば認証情報は勝手に読み込まれてくれるみたいなので普通にデプロイしてみましょう

      - name: change environments
        run: firebase use environment
      - name: deploy to hosting
        run: firebase deploy

image.png

最後に一応認証情報を環境から削除しておきます。

      - name: delete GOOGLE_APPLICATION_CREDENTIALS
        run: rm $GOOGLE_APPLICATION_CREDENTIALS
        if: ${{ always() }}

お疲れさまでした。

まとめるとこんな感じになると思います。

jobs:
  deploy:
    env:
      GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
      GCLOUD_SERVICE_KEY: ${{ secrets.PROD_GCP_KEY }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

(省略)

      - name: install firebase
        run: npm install --save-dev firebase-tools
        # 認証情報を保持するjsonファイルをGOOGLE_APPLICATION_CREDENTIALSで指定したpassに生成
      - name: make GOOGLE_APPLICATION_CREDENTIALS
        run: echo $GCLOUD_SERVICE_KEY | base64 -d > $GOOGLE_APPLICATION_CREDENTIALS
      - name: change environments
        run: |
          ./node_modules/.bin/firebase use aitcweb-prod
      - name: deploy to hosting
        run: |
          ./node_modules/.bin/firebase deploy
        # 認証用jsonファイルを削除
      - name: delete GOOGLE_APPLICATION_CREDENTIALS
        run: rm $GOOGLE_APPLICATION_CREDENTIALS
        if: ${{ always() }}

軽くまとめていますが、自分が設定した際はかなり手こずりました。CircleCIからの移行は対したことなかったのですが、思ってなかったところでコケましたね。

それでは。

21
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
6