【Firebase Hosting + GitHub Actions】Workload Identity連携を使用した自動デプロイのやり方 (備忘録)

2022/12/13 23:17公開
2023/02/24 08:59最終更新

ここ最近、CIにおいてfirebase login:ciで取得できるトークンを利用することが非推奨になり、Workload Identity 連携を使用することが推奨されるようになりました。今回は、それを用いてFirebase Hostingに自動デプロイするワークフローを作る方法を解説します。

Table of Contents
  1. Firebaseの準備
  2. GitHubレポジトリの作成
  3. Workload Identity 連携の設定
  4. サービスアカウントの作成
  5. サービスアカウントとWI連携の紐付け
  6. ワークフローファイルの作成
  7. Pushする

Firebaseの準備

まず、Firebase ConsoleからFirebaseプロジェクトを作成します。Google アナリティクスについては必要に応じて有効化します。今回は有効にしませんでした。

image

image

次に、自分のPCでディレクトリを作成し、firebase initします。選択内容は下を参照してください。

? Which Firebase features do you want to set up for this directory?
  --> Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys

? Please select an option:
  --> Use an existing project
    
? Select a default Firebase project for this directory:
  --> workload-test-xxxxx (workload-test)

? 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

GitHubレポジトリの作成

GitHubでレポジトリを作成しておきます。方法については割愛します。

Workload Identity 連携の設定

Google Cloud Platform ConsoleからWorkload Identity 連携の設定をします。こちら にアクセスしてください。

image

「使ってみる」をクリックします。


image

「名前」を「GitHub Actions」にし*1、「続行」をクリックします。


*1 名前は任意ですが、今後この名称を使用して説明するため同じにすることを推奨します。

image

以下のように入力して「続行」をクリックします。

名称
プロバイダの選択 OpenID Connect (OIDC)
プロバイダ名 GitHub
発行元(URL) https://token.actions.githubusercontent.com
オーディエンス 許可するオーディエンス
対象1 自身のGitHubプロフィールURL(https://github.com/<ユーザー名>の形式)

image

属性マッピングで以下のように設定します。(「マッピングを追加」をクリックすると2個目が表示されます)

Google OIDC
google.subject assertion.sub
attribute.repository assertion.repository

次に、「属性条件」で「条件を追加」をクリックし、「条件CEL」に'<GitHubユーザー名>/<レポジトリID>' == attribute.repositoryの形式で入力します。

サービスアカウントの作成

次に、デプロイ用のサービスアカウントを作成します。コンソール上ではこのアカウントでデプロイしたことになります。左のメニューから「サービスアカウント」を選択し、上部の「サービスアカウントの作成」をクリックします。

まず、サービスアカウント名に「github-actions」など適当な名前を設定し、「作成して続行」をクリックします。次に、「このサービス アカウントにプロジェクトへのアクセスを許可する」で「ロールを選択」から以下の2つを追加します。

  • サービス アカウント ユーザー
  • Firebase Hosting 管理者

Firebase Cloud Functionsも利用している場合、以下の3つも必要になる場合があります。

  • Cloud Functions 管理者
  • Cloud Scheduler 管理者
  • Secret Manager 管理者

最後に「続行」「完了」をクリックします。

(※ロール設定は「IAMと管理」画面の左メニュー下「リソースの管理」→プロジェクトを選択→右側の情報パネルから編集できます。ロールを追加する場合は「プリンシパルの追加」から「新しいプリンシパル」にサービスアカウントIDを入力します。)

サービスアカウントとWI連携の紐付け

次に、この2つを紐付けます。左メニューから「Workload Identity 連携」をクリックし、先程作成したWIプール(GitHub Actions)をクリックし、上部の「アクセスを許可」をクリックします。「サービスアカウント」から先程作成したサービスアカウントを選択し、「保存」をクリックします。

image

ワークフローファイルの作成

ここでやっとワークフローを作成します。.github/workflows/deploy.ymlファイルを作成してください。以下が雛形になります。

name: Deploy
on:
  push:
    branches:
      - main

  workflow_dispatch:
  repository_dispatch:

env:
  workload_identity_provider: <Workload Identity プロバイダー>
  service_account: <サービスアカウントID>
    
jobs:
    deploy-to-hosting:
      name: "Deploy to Hosting"
      runs-on: ubuntu-latest
      permissions:
        contents: read
        id-token: write

      steps:
        - uses: actions/checkout@v3

        - uses: actions/setup-node@v3
          with:
            node-version: 16
            cache: yarn

        - name: Install Firebase CLI
          run: yarn global add firebase-tools

        - name: 'Authenticate to Google Cloud'
          id: auth
          uses: 'google-github-actions/auth@v0'
          with:
            workload_identity_provider: ${{ env.workload_identity_provider }}
            service_account: ${{ env.service_account }}
            audience: https://github.com/<GitHubユーザー名>

      - name: Deploy to Firebase Hosting
        run: firebase deploy --only hosting

「Workload Identity プロバイダー」は以下の形式に従ってください。

projects/<プロジェクトID>/locations/global/workloadIdentityPools/<WIプールのID(github-actions)>/providers/<プロバイダーID(github)>

「サービスアカウントID」は左メニュー「サービスアカウント」より先程作成したサービスアカウントをクリックすると表示されるメールアドレスです。

肝は

permissions:
    contents: read
    id-token: write

の部分です。これがないと認証に失敗します。

お気づきかもしれませんが、そう。トークンなどの機密情報を人の手で管理する必要が一切ありません設定を適切にすれば Workload Identity プロバイダーやサービスアカウントIDだけ知っていても誰も悪用できないため、ハードコードしても全く問題ありません。設定はめちゃくちゃ面倒臭いですが、セキュリティは最強です。

Pushする

最後に、このディレクトリをGitHubにPushすれば、public以下がデプロイされるはずです。めでたしめでたし。