Google Workload identity federationでGitHub Actionsを設定してみた
現在開発中のプロジェクトでReactで構築したSPAのアプリケーションを開発しています。
提供方法はビルドしたReactのアプリケーションをGoogle Cloud Storage(GCS)に配置する方式でしたので、継続的なデプロイを円滑に進めるためにGitHub ActionsによるCI/CDを使うことにしました。
GitHub ActionsのworkflowでGCSにデプロイするためには、GCSにアクセス可能な権限(role)を持ったGoogle Cloud Platform(GCP)のIAMサービスアカウントとの紐づけが必要になります。
従来はサービスアカウントの credentials.json を使用して連携する形式が一般的なようですが、この場合クレデンシャル情報の管理が必要になってきます。
代替案はないかを検討したところ、社内のエンジニアから本題のWorkload identity federationを教えていただきました。
Workload identity federationを使用することで更にセキュアな連携が可能になり、クレデンシャル情報の管理も不要になるのでWorkload identity federationを採用することにしました。
今回はWorkload identity federationを使用した連携方法や作業中にハマった事についての共有です。
GCPの設定
環境変数の設定
export PROJECT_ID=<GCPのプロジェクトID>
export POOL_NAME=<Workload Identity プール名>
export POOL_DISPLAY_NAME=<Workload Identity プールの表示名>
export PROVIDER_NAME=<Workload Identity プロバイダ名>
export PROVIDER_DISPLAY_NAME=<Workload Identity プロバイダの表示名>
export SERVICE_ACCOUNT_NAME=<IAMのサービスアカウント名>
export SERVICE_ACCOUNT_DISPLAY_NAME=<IAMのサービスアカウントの表示名>
export GITHUB_REPO=<GitHubのリポジトリ名 e.g. organization/repo>
シェル変数を使用しているので同じセッション内で以下のコマンドを実行してください
IAM Service Accountを作成する
$ gcloud iam service-accounts create ${SERVICE_ACCOUNT_NAME} \
--project="${PROJECT_ID}" \
--display-name="${SERVICE_ACCOUNT_DISPLAY_NAME}"
IAM Service Account Credentials API を有効にする
IAM Service Account Credentials API は既に有効設定済
$ gcloud services list --enabled | grep iamcredentials.googleapis.com
iamcredentials.googleapis.com IAM Service Account Credentials API
今回のプロジェクトでは既に有効に設定済みなので不要でしたが、新規のプロジェクト等で有効にする場合は以下のコマンドを実行します。
$ gcloud services enable iamcredentials.googleapis.com \
--project "${PROJECT_ID}"
GCSのrole(権限)設定
$ gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--role="roles/storage.objectAdmin" \
--member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
Workload IdentityにPoolを作成する
$ gcloud iam workload-identity-pools create "${POOL_NAME}" \
--project="${PROJECT_ID}" \
--location="global" \
--display-name="${POOL_DISPLAY_NAME}"
export WORKLOAD_IDENTITY_POOL_ID=$( \
gcloud iam workload-identity-pools describe "${POOL_NAME}" \
--project="${PROJECT_ID}" \
--location="global" \
--format="value(name)" \
)
echo $WORKLOAD_IDENTITY_POOL_ID
作成したPoolにProvierを作成する
$ gcloud iam workload-identity-pools providers create-oidc "${PROVIDER_NAME}" \
--project="${PROJECT_ID}" \
--location="global" \
--workload-identity-pool="${POOL_NAME}" \
--display-name="${PROVIDER_DISPLAY_NAME}" \
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.actor=assertion.actor,attribute.aud=assertion.aud" \
--issuer-uri="https://token.actions.githubusercontent.com"
Workload Identityでサービス アカウントの権限借用の設定
$ gcloud iam service-accounts add-iam-policy-binding "${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \
--project="${PROJECT_ID}" \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${GITHUB_REPO}"
Workload Indentity Providerのリソース名の確認用
$ gcloud iam workload-identity-pools providers describe "${PROVIDER_NAME}" \
--project="${PROJECT_ID}" \
--location="global" \
--workload-identity-pool="${POOL_NAME}" \
--format='value(name)'
上記コマンドを実行後下記のような結果が返ってきたら成功です。
projects/<PROJECT_ID>/locations/global/workloadIdentityPools/<POOL_NAME>/providers/<PROVIDER_NAME>
GCPの設定は以上です。
GitHub Actionsの設定
環境変数の設定
GitHubリポジトリのSecretsに環境変数を追加します。
Name | Value |
---|---|
GCP_IDENTITY_PROVIDER | Workload Indentity Providerのリソース名の確認用の結果 |
GCP_SERVICE_ACCOUNT | サービスアカウント名 |
GCP_BUCKET | GCSのバケット名 |
GitHub Actionsのworkflowファイルを作成
GitHub Actionsにはgoogle謹製の setup-gcloud を使用します。
/.github/workflows/xxx.yaml に追加name: Deploy
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
strategy:
matrix:
node-version: [16.13.1]
os: [ubuntu-20.04]
runs-on: ${{ matrix.os }}
timeout-minutes: 10
# For google could SDK needs permissions.
# Add "id-token" with the intended permissions.
# ref. https://github.com/google-github-actions/setup-gcloud
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v2
with:
persist-credentials: false
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm ci
- name: Build
run: |
npm run build
- name: Setup google cloud SDK
uses: google-github-actions/setup-gcloud@v0.3.0
- id: auth
name: Authenticate to google cloud platform
uses: google-github-actions/auth@v0
with:
workload_identity_provider: ${{ secrets.GCP_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
create_credentials_file: 'true'
access_token_lifetime: 1200s
- name: Deploy
run: |
gcloud --quiet alpha storage cp -r ./dist/* "gs://${GCP_BUCKET}"
env:
GCP_BUCKET: ${{ secrets.GCP_BUCKET }}
この設定でmainブランチにpush(merge)されると都度デプロイされるようになります。
ハマり箇所
gsutil Workload Identity Federation対応してないってよ
元々は gsutil rsync を使用する予定だったんですが、対応していないようで gcloud alha storage cp に変更。
gcloudコマンドのalphaなので、正式に使用する場合には upload-cloud-storage に変更した方がよさそうです。
最後に
Google Workload identity federationの設定とGitHub Actionsの設定方法をお送りしました。
gsutil がWorkload identity federationに対応していないことに気づくのにえらい時間が掛かりましたが、それ以外の設定は比較的スムーズで、結果クレデンシャル情報を管理しなくてよくなったのは気持ちとしてすごく楽です。今回のプロジェクトでは結果としてデプロイ先がGCSから別のプラットフォームに変更になったので、このGitHub Actionsの設定もあと少しだけの期間ですが、これからGCSにGitHub ActionsでCI/CDを検討される方のお役に立つと嬉しく思います。
この記事を書いた人
- 2013年にアーティスに入社。システムエンジニアとしてアーティスCMSを使用したWebサイトや受託システムの構築・保守に携わる。環境構築が好き。
関連記事
最新記事
FOLLOW US
最新の情報をお届けします
- facebookでフォロー
- Twitterでフォロー
- Feedlyでフォロー