My Note

自己理解のためのブログ

Goアプリを Google App Engine ( GAE ) に GitHub Actionsでデプロイする(Workload Identity 連携)

はじめに

前回の記事でGitHub ActionsでGoogle App Engine (GAE) にデプロイする時の認証にサービスアカウントの秘密鍵を利用しました。 そこで今回はOpenID Connectを利用して実行します。秘密鍵を管理する必要もなく、githubのsecretsに登録しないのでより安全に利用できると思います。

yhidetoshi.hatenablog.com

Google Cloudの設定( IAM と Workload Identity )

Google Cloud側で必要となる設定を以下で作成する。(任意に設定する名前を環境変数にセットして上から順番に実行していく)

# 設定変数を任意に設定
export PROJECT_ID="project-id"
export SERVICE_ACCOUNT_NAME="sa-account-name"
export WORKLOAD_IDENTITY_POOLS="wi-pools"
export WORKLOAD_IDENTITY_POOLS_DISPLAY="wi-pools-display"
export WORKLOAD_IDENTITY_PROVIDER_DISPLAY="wi-provider-display"
export OIDC_NAME="oidc-name"
export GITHUB_REPO="account/repo-name"

# サービスアカウントを作成
gcloud iam service-accounts create "${SERVICE_ACCOUNT_NAME}" \
  --project "${PROJECT_ID}" \
  --display-name "${SERVICE_ACCOUNT_NAME}"

# サービスアカウントに権限を付与
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
  --role="roles/iam.serviceAccountUser" \
  --member="serviceAccount:${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"

# IAM Service Account Credentials APIを有効にする
gcloud services enable iamcredentials.googleapis.com \
  --project "${PROJECT_ID}"

# Workload Identity プールを作成
gcloud iam workload-identity-pools create "${WORKLOAD_IDENTITY_POOLS}" \
  --project="${PROJECT_ID}" \
  --location="global" \
  --display-name="${WORKLOAD_IDENTITY_POOLS_DISPLAY}"

# Workload IdentityプールのIDを取得
gcloud iam workload-identity-pools describe "${WORKLOAD_IDENTITY_POOLS}" \
  --project="${PROJECT_ID}" \
  --location="global" \
  --format="value(name)"

# Workload IdentityプールのIDを環境変数に設定
export WORKLOAD_IDENTITY_POOL_ID="上のレスポンス結果"

# Workload IdentityプールにWorkload Identityプロバイダを作成
gcloud iam workload-identity-pools providers create-oidc "${OIDC_NAME}" \
  --project="${PROJECT_ID}" \
  --location="global" \
  --workload-identity-pool="${WORKLOAD_IDENTITY_POOLS}" \
  --display-name="${WORKLOAD_IDENTITY_PROVIDER_DISPLAY}" \
  --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository" \
  --issuer-uri="https://token.actions.githubusercontent.com"

# 指定したGithubリポジトリで利用できるようにサービスアカウントに設定を追加
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}"

## Github Actionsで指定する値を確認 ##
# この結果を Github Actions (google-github-actions/auth)の 'workload_identity_provider' に設定する
gcloud iam workload-identity-pools providers describe "${OIDC_NAME}" \
  --project="${PROJECT_ID}" \
  --location="global" \
  --workload-identity-pool="${WORKLOAD_IDENTITY_POOLS}" \
  --format='value(name)'

# この結果を Github Actions (google-github-actions/auth)の 'service_account' に設定する
gcloud iam service-accounts describe "${SERVICE_ACCOUNT_NAME}"@"${PROJECT_ID}".iam.gserviceaccount.com --format="json" | jq .email -r
もしくは
gcloud iam service-accounts describe "${SERVICE_ACCOUNT_NAME}"@"${PROJECT_ID}".iam.gserviceaccount.com --format="yaml" | yq .email

作成したサービスアカウントに対して、GAEにデプロイするための権限を付与します。(google cloudへの認証だけであればこの権限追加は不要) f:id:yhidetoshi:20220214164245p:plain

GitHub Actionsについて

WORKLOAD_IDENTITY_PROVIDERGCP_SERVICE_ACCOUNTgithubのsecretsに登録する。 値については、上記の( "Google Cloudの設定( IAM と Workload Identity" の "Github Actionsで指定する値を確認") で確認 )

主な処理は以下の通り。

  1. Google Cloudに認証
  2. App Engineをデプロイ
  3. デプロイしたエンドポイントに curl で動作確認

■ 利用するGIthub-Actionsのライブラリ

name: Deploy Google App Engine
on:
  push:
    branches:
      - main
    paths:
      - ./**
      - .github/workflows/deploy.yaml

permissions:
  id-token: write
  contents: read


env:
  BASIC_AUTH_ID: ${{ secrets.BASIC_AUTH_ID }}
  BASIC_AUTH_PW: ${{ secrets.BASIC_AUTH_PW }}
  BASIC_AUTH_PATH: /metal
  WORKLOAD_IDENTITY_PROVIDER: ${{ secrets.WORKLOAD_IDENTITY_PROVIDER }}
  GCP_SERVICE_ACCOUNT: ${{ secrets.GCP_SERVICE_ACCOUNT }}


jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: 'actions/checkout@v2'
  
      - name: 'Authenticate to Google Cloud by OIDC'
         id: 'gcp-auth-oidc'
         uses: 'google-github-actions/auth@v0.6.0'
         with:
           workload_identity_provider: '${{ env.WORKLOAD_IDENTITY_PROVIDER }}'
           service_account: '${{ env.GCP_SERVICE_ACCOUNT }}'


      - name: 'Deploy to App Engine'
        id: 'deploy'
        uses: 'google-github-actions/deploy-appengine@v0.6.0'
        with:
          deliverables: 'app.yaml'
          promote: false
          version: 'v1'


      - name: 'validate'
        run: curl -sS -u ${{ env.BASIC_AUTH_ID }}:${{ env.BASIC_AUTH_PW }} ${{ steps.deploy.outputs.url }}${{ env.BASIC_AUTH_PATH }}

github actionsの実行結果 f:id:yhidetoshi:20220214164717p:plain

参考

Workload Identity 連携 について

cloud.google.com