【OIDC認証】GitHub ActionsでCloud Run自動デプロイ
はじめに
かくひとと申します。ゲーム制作とWeb開発の勉強をしています。
この度、Cloud Runへの自動デプロイを試してみました。
- Github Actionsを使ったCloud RunへのCI/CD
- OIDC認証を用いる方法
に関して情報が多くないと感じたので、備忘録として残します。
また記事作成にあたって、TeasegasugoiさんのZenn記事をとても参考にさせていただきました。
手順に関してはこちらの記事が完全にベースとなります。。こちらの記事の中で、自分がわからない箇所、一部つまづいた箇所を補足するようにして作成しました。
イメージ
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の環境構築を進めていきます(ダウンロード先)。
ログインを実施。
$ 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