Workload Identity 連携を利用して GitHub Actions から Cloud Run にデプロイ
概要
Workload Identity 連携を利用した GitHub Actions からのGCP認証を行ったので、参考にしたサイトと手順を備忘録として残します。
Workload Identity 連携について
Workload Identity 連携は、キーなしの新しいアプリケーション認証メカニズムであり、オンプレミス、AWS、Azure で実行するワークロードは、外部 ID プロバイダ(IdP)と連携し、サービス アカウント キーを使用せずに Google Cloud リソースを呼び出すことができます。ワークロードはセキュリティ トークン サービス(STS)エンドポイントを呼び出して、IdP から取得した認証トークンを有効期間が短い GCP アクセス トークンと交換します。そして、このアクセス トークンを使用してサービス アカウントになりすまして、GCP リソースにアクセスするサービス アカウントの権限を継承します。
従来のサービスアカウントキーによる認証は以下の欠点があり、現在は最終手段になっているようです。
- キーを保持しているアプリケーションにそのキーを使用する権限があるかどうかを確認する方法がない
- 有効期限が長い
Workload Identity 連携を使うことで、外部の ID に対して サービスアカウントになりすます機能を含むIAMロールを付与できるので、アカウントキーを発行する必要がなくなり、キーのメンテナンスとセキュリティの負担がなくなります。
動画での説明が分かりやすかったのでオススメです。
GCP設定
1. サービスアカウントの作成
プロジェクトの確認
$ gcloud projects list
プロジェクトの切り替え
$ gcloud config set project $PROJECT_ID
サービスアカウントの作成
$ gcloud iam service-accounts create $SA_NAME
サービスアカウントの確認
$ gcloud iam service-accounts list
2. サービスアカウントに権限付与
Artifact Registry と Cloud Run を利用することを踏まえ、以下の権限を付与
- roles/iam.serviceAccountUser
- roles/artifactregistry.writer
- roles/run.admin
roles/iam.serviceAccountUser を付与する例
$ gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SA_EMAIL" \
--role="roles/iam.serviceAccountUser"
3. Workload Identity 連携
IAM Credentials API の有効化
$ 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 プロバイダの作成
$ 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"
プールとサービスアカウントの紐付け
$ export WORKLOAD_IDENTITY_POOL_ID=$(gcloud iam workload-identity-pools describe $POOL_NAME --project="$PROJECT_ID" --location="global" --format="value(name)")
# GitHub Actions を利用したいリポジトリ名
$ export REPO="username/name" # e.g. "Teasegasugoi/sample-app"
$ 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}"
GitHub Actions から Cloud Run にデプロイ
認証
GitHub Actions の permissionsとstepsに以下を追加します。
permissions:
contents: 'read'
id-token: 'write'
steps:
- name: 'Checkout'
uses: 'actions/checkout@v4'
- name: 'Authenticate to Google Cloud'
id: 'auth'
uses: 'google-github-actions/auth@v1'
with:
token_format: 'access_token'
workload_identity_provider: '${{ secrets.WIF_PROVIDER }}'
service_account: '${{ secrets.WIF_SERVICE_ACCOUNT }}'
- name: 'Docker Auth'
id: docker-auth
uses: 'docker/login-action@v1'
with:
username: 'oauth2accesstoken'
password: '${{ steps.auth.outputs.access_token }}'
registry: '${{ vars.LOCATION }}-docker.pkg.dev'
これ以降のstepではサービスアカウントが認証されている状態となり、docker
コマンドやgcloud
コマンドを実行できます。
コンテナの Build と Push
- name: Build, tag and push container
id: build-image
uses: docker/build-push-action@v3
with:
context: ${{ vars.code_directory }}
push: true
tags: |
${{ vars.REGION }}-docker.pkg.dev/${{ vars.GCP_PROJECT_ID }}/${{ vars.ARTIFACT_REPO }}/${{ vars.SERVICE_NAME }}:${{ inputs.ref }}
Cloud Run にデプロイ
- name: 'Deploy to Cloud Run'
id: deploy
uses: google-github-actions/deploy-cloudrun@v0
with:
service: ${{ vars.service_name }}
region: ${{ vars.region }}
metadata: container-${{ inputs.environment }}.yaml
その他参考
Discussion