💳

【OIDC認証】GitHub ActionsでCloud Run自動デプロイ

2024/09/15に公開

はじめに

かくひとと申します。ゲーム制作とWeb開発の勉強をしています。
この度、Cloud Runへの自動デプロイを試してみました。

https://github.com/Suke-H/wordle-in-gcp/

  • Github Actionsを使ったCloud RunへのCI/CD
  • OIDC認証を用いる方法

に関して情報が多くないと感じたので、備忘録として残します。

また記事作成にあたって、TeasegasugoiさんのZenn記事をとても参考にさせていただきました。
https://zenn.dev/teasegasugoi/articles/25ff7b339d528e

手順に関してはこちらの記事が完全にベースとなります。。こちらの記事の中で、自分がわからない箇所、一部つまづいた箇所を補足するようにして作成しました。

イメージ


CI/CD実行時のイメージ

本記事で紹介する方法は、Workload Identity 連携(Workload Identity Federation, 通称WIF)を用いて、Github Actions内でサービスアカウントを一時的に呼び出し、そのアカウントを使ってデプロイを実行していく流れとなります。このWorkload Identityを経由する方法によりサービスアカウントのキー管理が必要なくなり、かわりにGitHubとGoogle Cloudの間でOpenID Connect(OIDC)認証を使用した安全な認証を行えます。

Workload Identity 連携をするために、以降の手順で次のように準備していきます。

  • サービスアカウントの作成(ロール付与)
  • Workload Identityプールとサービスアカウントとの紐づけ
  • Workload IdentityプロバイダとGithubとのOIDC認証の設定


Workload Identity 連携の準備

事前準備

今回はCLIにてGoogle Cloudの環境構築を進めていきます(ダウンロード先)。
https://cloud.google.com/sdk/docs/install?hl=ja

ログインを実施。

$ gcloud auth login

問題なくログインできたことを確認。

$ gcloud auth list

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

まずはサービスアカウントを作成します。
このアカウントを後々Workload Identity 連携し、Actions上でのCloud Runデプロイ実行のために使います。
(*以下、<変数名>では各自で命名をお願いします。)

プロジェクトの作成

$ gcloud projects create <PROJECT_ID> --name="<PROJECT_NAME>"

プロジェクトを確認

$ gcloud projects list

今回使用するプロジェクトに切り替え

$ gcloud config set project <PROJECT_ID>

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

$ gcloud iam service-accounts create <SA_NAME>

サービスアカウントの確認

$ gcloud iam service-accounts list

2. サービスアカウントにロール付与

Cloud Runデプロイのために、以下の3つのロールを付与します。

  • roles/iam.serviceAccountUser
  • roles/artifactregistry.writer
  • roles/run.admin
$ gcloud projects add-iam-policy-binding <PROJECT_ID> \
    --member="serviceAccount:<SA_EMAIL>" \
    --role="roles/iam.serviceAccountUser"
$ gcloud projects add-iam-policy-binding <PROJECT_ID> \
    --member="serviceAccount:<SA_EMAIL>" \
    --role="roles/artifactregistry.writer"
$ gcloud projects add-iam-policy-binding <PROJECT_ID> \
    --member="serviceAccount:<SA_EMAIL>" \
    --role="roles/run.admin"

(Windowsのコマンドプロンプトの場合は\^に変えてください)

<SA-EMAIL>は以下です。

<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com

以下コマンドからも確認ができます。

$ gcloud iam service-accounts list

3. Workload Identity 連携

Workload Identityプール(WIFを行うための枠組み)を作成し、以下2つを行っていきます。

  • GithubとのOIDC認証の設定
  • サービスアカウントとの紐づけ

IAM Credentials API の有効化(WIFに必要)

$ gcloud services enable iamcredentials.googleapis.com \
 --project <PROJECT_ID>

Workload Identity プールを作成

$ gcloud iam workload-identity-pools create <POOL_NAME> \
    --project="<PROJECT_ID>" \
    --location="global"

Workload Identity プロバイダを作成し、GithubのOIDC認証を設定

$ gcloud iam workload-identity-pools providers create-oidc <PROVIDER_NAME> \
    --project="<PROJECT_ID>" \
    --location="global" \
    --workload-identity-pool="<POOL_NAME>" \
    --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository" \
    --issuer-uri="https://token.actions.githubusercontent.com"

Workload Identity プールと、先ほど作成したサービスアカウントの紐付け

$ export WORKLOAD_IDENTITY_POOL_ID=$(gcloud iam workload-identity-pools describe $POOL_NAME --project="<PROJECT_ID>" --location="global" --format="value(name)")

# GitHub Actions を利用したいリポジトリ名
# e.g. "Suke-H/wordle-in-gcp"
$ export REPO="username/name" 

$ gcloud iam service-accounts add-iam-policy-binding <SA_EMAIL> \
   --project="<PROJECT_ID>" \
   --role="roles/iam.workloadIdentityUser" \
   --member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${REPO}"
Windows(コマンドプロンプト)の場合
REM WORKLOAD_IDENTITY_POOL_IDを取得
set WORKLOAD_IDENTITY_POOL_ID=gcloud iam workload-identity-pools describe %POOL_NAME% --project="<PROJECT_ID>" --location="global" --format="value(name)"

REM GitHub Actions を利用したいリポジトリ名
REM 例: "Suke-H/wordle-in-gcp"
set REPO=username/name

REM サービスアカウントにIAMポリシーバインディングを追加
gcloud iam service-accounts add-iam-policy-binding <SA_EMAIL> ^
   --project="<PROJECT_ID>" ^
   --role="roles/iam.workloadIdentityUser" ^
   --member="principalSet://iam.googleapis.com/%WORKLOAD_IDENTITY_POOL_ID%/attribute.repository/%REPO%"

これでようやくWorkload Identity 連携は完了です!

4. GitHub ActionsからCloud Runにデプロイ

最後に、自動デプロイのためのGithub Actionsワークフローを記載します。
.github/workflows/配下に、以下のyamlを置きます(名前は何でも大丈夫です)。

name: Deploy to Cloud Run

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    permissions:
      contents: 'read'
      id-token: 'write'

    env:
      SERVICE_NAME: 'gcp-wordle'
      REGION: 'asia-northeast1' 

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Authenticate to Google Cloud
        id: auth
        uses: google-github-actions/auth@v1
        with:
          workload_identity_provider: ${{ secrets.WIF_PROVIDER }}
          service_account: ${{ secrets.SA_EMAIL }}

      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v1
        with:
          project_id: ${{ secrets.PROJECT_ID }}
          install_components: 'beta'

      - name: Build Docker image
        run: |
          docker build --no-cache -t gcr.io/${{ secrets.PROJECT_ID }}/${{ env.SERVICE_NAME }}:$GITHUB_SHA .

      - name: Push Docker image
        run: |
          gcloud auth configure-docker
          docker push gcr.io/${{ secrets.PROJECT_ID }}/${{ env.SERVICE_NAME }}:$GITHUB_SHA

      - name: Deploy to Cloud Run
        run: |
          gcloud run deploy ${{ env.SERVICE_NAME }} \
            --image gcr.io/${{ secrets.PROJECT_ID }}/${{ env.SERVICE_NAME }}:$GITHUB_SHA \
            --platform managed \
            --region  ${{ env.REGION }}\
            --allow-unauthenticated

Authenticate to Google Cloudにて、Workload Identity プロバイダ を通してOIDC認証が実施されます。これによってWorkload Identity連携させたサービスアカウントが使えるようになります。

その後、

  • Dockerイメージのビルド
  • Artifact Registryへのプッシュ
  • Cloud Runへのデプロイ

と続きます。

mainにプッシュすることで、自動デプロイが問題なく実行されたら成功です!

補足

  • envは自分に合った内容を記載してください。

  • secretsはGithub側で書き込みます。

    • PROJECT-ID
    • SA_EMAILS
    • WIF_PROVIDER:以下のコマンドから取得
$ gcloud iam workload-identity-pools providers list --workload-identity-pool=<POOL_NAME> --location="global"

以下の形式からなる情報です:

projects/<YOUR_PROJECT_NUMBER>/locations/global/workloadIdentityPools/<YOUR_POOL_NAME>/providers/<YOUR_PROVIDER_NAME>

まとめ

以上となります!これで、OIDC認証がされたCloud Runへの自動デプロイが可能になります。
この作業を通した感想として、Workload Identity 連携の仕組みはもちろんですが、そもそもGoogle Cloudのサービス自体詳しくなかったので、CLIでの操作、Cloud RunやArtifact Registryについて学ぶよい機会となりました。

......が、結構大変です。。これこそTerraformで自動化するべき作業なのかなと思っております。ぜひ勉強して、再び共有できたらと思いました。

Discussion