業界・業務から探す
導入目的・課題から探す
データ・AIについて学ぶ
News
Hakkyについて
ウェビナーコラム
◆トップ【Hakkyの社内Wiki】Strapi
クラウドとオンプレの違いAIシステム導入時におすすめのクラウドシステムスクレイピングのためのプロキシサーバのAPI
TerraformでGCPからAWSのリソースにアクセスするGoogle Cloudとは?
AI

執筆者:Handbook編集部

Workload Identityを使ったGitHub ActionsとGoogle Cloudの連携方法

概要

本記事では Workload Identity を Github Actions で利用する方法について解説します。また、本記事では Docker イメージの GCR への Push と Cloud Run へのデプロイを行う例も紹介します。

Workload Identity とは

Workload Identity とはサービスアカウントキーを必要としないアプリケーション認証方法であり、Google Cloud と外部のワークロード連携のために用いられます。キーを利用しないためよりセキュアに連携を行うことがメリットです。

Workload Identity の設定

ここからは実際に Workload Identity を利用するための設定について解説を行います。

Workload Identity を利用するには Google Cloud 側での設定と外部での呼び出しのための設定の両方を行う必要があります。本セクションではまず Google Cloud 側の設定について解説いたします。

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

まず、外部サービスで利用するサービスアカウントを作成します。本記事の例ではgithub-actions-deployerという名前のサービスアカウントを利用することとします。サービスアカウントには適切な権限を割り当てる必要があり、今回は GCR への書き込み権限と Cloud Run のサービスのデプロイ権限を付与する必要があります。

また、IAM Service Account Credentials API が有効になっていない場合は有効にする必要がある点も注意が必要です。有効になっていない場合は以下のコマンドで有効化できます。

gcloud services enable iamcredentials.googleapis.com \
  --project "${PROJECT_ID}"

2. Workload Identity を設定する

最初に今回利用する環境変数を設定します。今回は以下のような設定を利用することにします。

export PROJECT_ID=<YOUR_PROJECT>
export POOL_NAME=github-actions-pool
export POOL_DISPLAY_NAME=github-actions-pool
export PROVIDER_NAME=github-actions-provider
export PROVIDER_DISPLAY_NAME=github-actions-provider
export SERVICE_ACCOUNT_NAME=github-actions-deployer
export SERVICE_ACCOUNT_DISPLAY_NAME=github-actions-deployer
export GITHUB_REPO=<Organization>/<Repository>

続いて Workload Identity に Pool を作成します。

gcloud iam workload-identity-pools create "${POOL_NAME}" \
  --project="${PROJECT_ID}" \
  --location="global" \
  --display-name="${POOL_DISPLAY_NAME}"

# 後で利用する変数をExport
export WORKLOAD_IDENTITY_POOL_ID=$( \
     gcloud iam workload-identity-pools describe "${POOL_NAME}" \
    --project="${PROJECT_ID}" \
    --location="global" \
    --format="value(name)" \
)

次に以下のコマンドで Provider を設定します。今回の例では GitHub Actions を用いるため issuer には GitHub を設定しています。利用する外部サービスが異なる場合はこちらを変更する必要があります。

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}"

以上で Google Cloud 側の設定は終了です。

正しく設定できているかは以下のコマンドで確認できます。

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>

3. Terraform を利用した Workload Identity の設定

手動で gcloud コマンドを実行する代わりに、Terraform を使って Workload Identity に必要なリソースを作成することも可能です。下記のコード例は、GitHub Actions 用の Workload Identity Pool と Provider、そして Service Account の IAM バインディングを Terraform で定義しています。 なお、ここでは Terraform の変数ブロックは割愛しています。ご利用の環境に合わせて var.project、var.repository_name、var.github_actions_roles 等を定義してください。 Terraform 設定例

# Workload Identity Pool の作成
resource "google_iam_workload_identity_pool" "github_actions" {
  provider                  = google-beta
  workload_identity_pool_id = "github-actions-deploy-pool"
  project                   = var.project
}

# Workload Identity Pool Provider の作成
resource "google_iam_workload_identity_pool_provider" "github_actions" {
  provider                           = google-beta
  workload_identity_pool_id          = google_iam_workload_identity_pool.github_actions.workload_identity_pool_id
  workload_identity_pool_provider_id = "github-actions-provider"
  display_name                       = "github-actions-provider"
  description                        = "GitHub ActionsでCI/CDするときに利用するもの"
  project                            = var.project

  # GitHub からのOIDCトークンを検証する条件
  attribute_condition = <<-EOT
    attribute.repository == "${var.repository_organization_name}/${var.repository_name}"
  EOT

  # GitHub Actions のOIDCトークンからGCP側の属性にマッピング
  attribute_mapping = {
    "google.subject"       = "assertion.sub"
    "attribute.actor"      = "assertion.actor"
    "attribute.repository" = "assertion.repository"
    "attribute.aud"        = "assertion.aud"
  }

  oidc {
    issuer_uri = "https://token.actions.githubusercontent.com"
  }
}

# サービスアカウントの作成
resource "google_service_account" "github_actions" {
  project      = var.project
  account_id   = "github-actions-deployer"
  display_name = "github-actions-deployer"
}

# Workload Identityによる認証を許可するIAMバインディング設定
resource "google_service_account_iam_member" "workload_identity_account_iam" {
  service_account_id = google_service_account.github_actions.name
  role               = "roles/iam.workloadIdentityUser"
  # principalSet://iam.googleapis.com/${POOL_NAME}/attribute.repository/organization/repo
  member             = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github_actions.name}/attribute.repository/${var.repository_organization_name}/${var.repository_name}"
}

# サービスアカウントにロールを付与する
resource "google_project_iam_member" "github_actions" {
  for_each = toset(var.github_actions_roles)

  project = var.project
  role    = each.value
  member  = "serviceAccount:${google_service_account.github_actions.email}"
}

GitHub Actions の設定

本セクションでは GitHub 側で Workload Identity を利用するための設定について解説します。以下のような GitHub Actions の Workflow を設定します。流れとしては、image-urlで利用する GCR の URL を取得し、authで Workload Identity の認証を行なっています。その後 Docker イメージをビルド、Push し、Cloud Run に Deploy するという流れです。

GitHub Actions の設定で注意する点としては、以下の通りです。

  1. Pool や Provider の名前が Workload Identity 作成時に設定したものと同じか
  2. サービスアカウントに正しく権限が振られているか
name: Build and Deploy

on:
  push:
    branches:
      - "main"

env:
  GITHUB_SHA: ${{ github.sha }}
  REGISTRY_HOSTNAME: asia.gcr.io
  GCP_PROJECT_ID: <YOUR_PROJECT_ID>
  GCP_PROJECT_NUMBER: <YOUR_PROJECT_NUMBER>
  DOCKER_BUILDKIT: 1

jobs:
  build:
    name: Build and Push Docker Image
    runs-on: ubuntu-20.04

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

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - id: image-url
        name: Create docker image url
        run: |
          echo "::set-output name=value::${{ env.REGISTRY_HOSTNAME }}/${{ env.GCP_PROJECT_ID }}/my-service:latest"

      - name: loud SDK
        uses: google-github-actions/setup-gcloud@v0
        with:
          project_id: ${{ env.GCP_PROJECT_ID }}

      - id: auth
        name: "Authenticate to Google Cloud"
        uses: google-github-actions/auth@v0.8.0
        with:
          create_credentials_file: "true"
          workload_identity_provider: "projects/${{ env.GCP_PROJECT_NUMBER }}/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider"
          service_account: "github-actions-deployer@${{ env.GCP_PROJECT_ID }}.iam.gserviceaccount.com"
          access_token_lifetime: 1200s

      - name: gcloud auth login by workload identity
        run: |-
          gcloud auth login --brief --cred-file="${{ steps.auth.outputs.credentials_file_path }}"

      - name: Configure docker to use the gcloud cli
        run: gcloud auth configure-docker --quiet

      - name: Build a docker image
        run: |
          docker build -t ${{ steps.image-url.outputs.value }} .
      - name: Push the docker image to Container Registry
        run: docker push ${{ steps.image-url.outputs.value }}

      - name: Deploy revision
        if: ${{ github.event_name == 'push'}}
        run: |
          # Install Beta components
          gcloud components install -q beta
          gcloud beta run deploy $my-service \
          --memory 1Gi \
          --platform managed \
          --region asia-northeast1 \
          --image ${{ steps.image-url.outputs.value }} \
          --ingress internal-and-cloud-load-balancing \
          --service-account "github-actions-deployer@${{ env.GCP_PROJECT_ID }}.iam.gserviceaccount.com" \

本記事で紹介した設定は Google Cloud のほかのサービスと連携する際でもgcloud auth login by workload identityまでは共通して使うことができます。以上で GitHub Actions 側の設定は終わりです。mainブランチに Push して Actions が最後まで正しく動作しているか確認しましょう。

参考

info
備考

Hakky ではエンジニアを募集中です!まずは話してみたいなどでも構いませんので、ぜひお気軽に採用ページからお問い合わせくださいませ。

2025年06月15日に最終更新
読み込み中...