
はじめに
GitHub Actions から Google Cloud にアクセスするときに「サービスアカウントキー」ではなく「Workload Identity Federation (WIF)」を使うことが推奨されている.長期的な認証情報を管理する必要がなくて安全に使える.今回はプリンシパルに直接アクセス権限を渡す Direct Workload Identity Federation(google-github-actions/auth に載っている名称)を使って GitHub Actions で Google Cloud プロジェクトに対して Terraform コマンドを実行する仕組みを Terraform で作る❗️
Workload Identity プール
まず最初に Workload Identity プールを作る.google_iam_workload_identity_pool リソースを使う.
resource "google_iam_workload_identity_pool" "github_actions" { workload_identity_pool_id = "github-actions" display_name = "GitHub Actions" }
Workload Identity プロバイダー
次に Workload Identity プールにプロバイダを紐付ける.google_iam_workload_identity_pool_provider リソースを使う.GitHub Actions から OIDC トークンを受け付けられるようにする設定で attribute_condition で GitHub リポジトリのオーナーを制限できる.イシュアとして設定する URL は GitHub Actions のドキュメントに載っている https://token.actions.githubusercontent.com にしておく👌
resource "google_iam_workload_identity_pool_provider" "github_actions" { workload_identity_pool_id = google_iam_workload_identity_pool.github_actions.workload_identity_pool_id workload_identity_pool_provider_id = "github" display_name = "GitHub Actions" attribute_mapping = { "google.subject" = "assertion.sub" "attribute.actor" = "assertion.actor" "attribute.repository" = "assertion.repository" } attribute_condition = "assertion.repository_owner == 'kakakakakku'" oidc { issuer_uri = "https://token.actions.githubusercontent.com" } }
IAM
Direct Workload Identity Federation ではサービスアカウントを使わず,Workload Identity プールのプリンシパルに対して直接 IAM ロールを付与できる.今回は Terraform の CI/CD で使う検証環境なので roles/writer を付与しているけど,本来は最小権限の原則を意識する必要がある⚠️
resource "google_project_iam_member" "github_actions_writer" { project = "xxxxx" role = "roles/writer" member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github_actions.name}/attribute.repository/kakakakakku/xxxxx" }
ちなみに今回検証で使っている Terraform プロジェクトでは google_billing_budget リソースを使った Google Cloud プロジェクトの「予算アラート」も設定しているため,さらに請求アカウントに対する roles/billing.viewer の付与も必要だった.
resource "google_billing_account_iam_member" "github_actions_billing_viewer" { billing_account_id = "XXXXXX-XXXXXX-XXXXXX" role = "roles/billing.viewer" member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.github_actions.name}/attribute.repository/kakakakakku/xxxxx" }
Terraform の Google Cloud Storage (GCS) Backend
今回のように Direct Workload Identity Federation を使っていて,Terraform のステートを Google Cloud Storage (GCS) で管理している場合は「均一なバケットレベルのアクセス」を有効化しておく必要がある.ドキュメントには以下のように書いてあった.
Uniform bucket-level access must be enabled to grant Workforce Identity Federation or Workload Identity Federation entities access to Cloud Storage resources.
google_storage_bucket リソースだと uniform_bucket_level_access = true で設定できる👌
resource "google_storage_bucket" "tfstate" { name = "xxxxx" location = "asia-northeast1" uniform_bucket_level_access = true versioning { enabled = true } }
GitHub Actions ワークフロー
最後に GitHub Actions ワークフローを作る.google-github-actions/auth で Direct Workload Identity Federation を使ってアクセス権限を取得しつつ,最終的に terraform plan コマンドを実行している💪
name: Terraform Plan on: pull_request: branches: - main workflow_dispatch: jobs: plan: runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 with: workload_identity_provider: 'projects/00000000000/locations/global/workloadIdentityPools/github-actions/providers/github' project_id: 'xxxxx' - uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v4.0.0 with: terraform_version: 1.14.0 - run: terraform init - run: terraform plan
適当に Pub/Sub トピックを追加するプルリクエストを作ったら,自動的に terraform plan を実行できた \( 'ω')/

まとめ
今回は GitHub Actions で Google Cloud プロジェクトに対して Terraform コマンドを実行する仕組みを作りたくて,google-github-actions/auth に載っている3種類の選択肢の中で Preferred と書いてある Direct Workload Identity Federation を使ってみた.期待した通りに terraform plan コマンドを実行できるようになって良かった❗️
- (Preferred) Direct Workload Identity Federation
- Workload Identity Federation through a Service Account
- Service Account Key JSON



