🤖

OpenID Connectを利用して、Github ActionsからGCPにキーなしで認証する構成をTerraformを使って実装する

2023/12/16に公開

記事の内容

OpenID Connectを利用して、サービスアカウントキーを発行することなく、Github ActionsからGCPに認証します。

また、リソースの作成はTerraformで行います。

対象読者

  • Github ActionsからGCPに対して認証し、操作がしたい人
  • TerraformでOIDC構成を実装したい人

記事の長さ

1分で読めます

Github Actions用のユーザーを用意する

まずは、Github Actionsで利用するServiceAccountを作成します。

resource "google_service_account" "github_actions" {
  project      = var.project_id
  account_id   = "github-actions"
  display_name = "Github Actions"
}
resource "google_project_iam_member" "github_actions" {
  project = var.project_id
  role    = "roles/owner"
  member  = "serviceAccount:${google_service_account.github_actions.email}"
}

上記ファイルを作成後、terraform applyを実行します。

$ terraform apply
...

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

正常にApplyが完了すると、roles/owner権限を持ったGithub Actionsという名前のService Accountが作成されます。
roels/owner権限は強い権限ですので、実際にプロジェクトで利用する際は、最小限の権限に絞って利用してください。

Workload Identity poolを用意する

次に、Workload Identity Poolを作成します。

以下のリソースを追加して、Terraform Applyを実行してください。

resource "google_iam_workload_identity_pool" "github_actions" {
  project                   = var.project_id
  workload_identity_pool_id = "github-actions-oidc"
}
$ terraform apply
...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

これで、Workload Identity Poolが作成できました。

API Errorが出た場合

Error: Error creating WorkloadIdentityPool: googleapi: Error 403: Identity and Access Management (IAM) API has not been used in project <GCP Project ID> before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/iam.googleapis.com/overview?project=<GCP Project ID> then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

このようなエラーが出た場合、Error文の中に含まれるURLをクリックして、APIを有効化してください。
有効化が完了したら、再度、Terraform Applyを実行すると、うまくいきます。

Workload Identity Pool Providerを用意する

次に、今作成したWorkload Identity Poolに紐づくProviderを作成します。

resource "google_iam_workload_identity_pool_provider" "github_actions" {
  project                            = var.project_id
  workload_identity_pool_provider_id = "github-actions-oidc-provider"
  workload_identity_pool_id          = google_iam_workload_identity_pool.github_actions.workload_identity_pool_id
  attribute_condition                = "\"${var.github_org_name}/${var.github_org_name}\" == assertion.repository"

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

  attribute_mapping = {
    "google.subject"       = "assertion.sub"
    "attribute.repository" = "assertion.repository"
  }
}

var.github_org_namevar.github_org_nameは、これから連携したいGithubの組織名とリポジトリ名に変更してください。

$ terraform apply
...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

ファイルのApplyが完了すると、Workload Identity Pool Providerが作成されます。

Workload Identity PoolとService Accountを連携する

最後に、Workload Identity PoolとService Accountを連携します。

resource "google_service_account_iam_member" "github_actions_iam_workload_identity_user" {
  service_account_id = "projects/${var.project_id}/serviceAccounts/github-actions@${var.project_id}.iam.gserviceaccount.com"
  role               = "roles/iam.workloadIdentityUser"
  member             = "principal://iam.googleapis.com/${google_iam_workload_identity_pool.github_actions.name}/subject/repo:${var.github_org_name}/${var.github_repo_name}:ref:refs/heads/main"
}

上記リソースを追加したら、再度Terraform Applyを実行します。

$ terraform apply
...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

正常にApplyが完了したら、GCP側の準備は完了です。

※ここでは、refs/heads/mainを指定することで、Githubのmainブランチからのみ、このService Accountを使用できるように制限しています。

Github ActionsでServiceAccountを使用する

name: OIDC Actions

on:
  push:
    branches:
      - main

permissions:
  id-token: write
  contents: read

jobs:
  test:
    name: test
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - uses: google-github-actions/auth@v2
        with:
          workload_identity_provider: "projects/${{ secrets.PRODUCTION_GCP_NUMBER }}/locations/global/workloadIdentityPools/github-actions-oidc/providers/github-actions-oidc-provider"
          service_account: 'github-actions@${{ secrets.PRODUCTION_GCP_ID }}.iam.gserviceaccount.com'

      - name: Test
        run: gcloud iam service-accounts list

Github ActionsのWorkflowファイルを作成します。

上記ファイルを作成後、mainブランチにマージ or Pushしてください。

すると、無事GCPに対して認証が成功して、Test Stepで取得している、サービスアカウントの一覧が表示されます。

Run gcloud iam service-accounts list
...
DISPLAY NAME                            EMAIL                                                      DISABLED
Github Actions                          github-actions@***.iam.gserviceaccount.com  False

以上で、OIDCを利用したGCPへの認証が完了しました。サービスアカウントキーの発行をせずにGithubActionsとGCPを連携できる認証方法のため、より安全にプロダクト運用ができるようになります。

note

勉強法やキャリア構築法など、エンジニアに役立つ記事をnoteで配信しています。

https://note.com/ring_belle/membership

Discussion