Lambdaカクテル

京都在住Webエンジニアの日記です

Invite link for Scalaわいわいランド

Google Cloud+Terraformでアクセス権限をSecretやCloud Buildにつけるのが難しい

難しかったので備忘録です。

追記(2025-10-31)

良いアンサーをいただきました。

scrapbox.io

SAを別のSAから利用できるようにする

例えばCloud Buildを起動しているSAがビルドの終わりにCloud Runを更新して起動する、といったとき、Cloud Runの実行用のSAにバトンタッチする必要がある。そういうときはSAがSAを利用するための権限が必要(なはず)で、以下のように設定する:

variable "runtime_sa_account_id" {
  description = "Account ID (name) for runtime Service Account"
  type        = string
  default     = "runtime"
}

variable "build_sa_account_id" {
  description = "Account ID (name) for build Service Account"
  type        = string
  default     = "builder"
}

resource "google_service_account" "runtime" {
  account_id   = var.runtime_sa_account_id
  display_name = "Runtime Service Account"
}

resource "google_service_account" "builder" {
  account_id   = var.build_sa_account_id
  display_name = "Builder Service Account"
}

// ここが大事

resource "google_service_account_iam_member" "builder_can_use_runtime_sa" {
  service_account_id = google_service_account.runtime.name
  role               = "roles/iam.serviceAccountUser"
  member             = "serviceAccount:${google_service_account.builder.email}"
}

ここでは、google_service_account_iam_memberが必要。

SAがCloud Buildを実行できるようにする

なるほどgoogle_service_account_iam_memberが必要なのね〜と思っていたら罠である。google_service_account_iam_memberSAがSAを利用するためのリソースであって、SAが他のリソースを使うためのリソースではない

例えば、Cloud BuildをSAを使って実行したいときはgoogle_project_iam_memberが必要になる:

resource "google_project_iam_member" "builder_can_run_cloudbuild" {
  project = var.project
  role    = "roles/cloudbuild.builds.builder"
  member  = "serviceAccount:${google_service_account.builder.email}"
}

統一されてねぇのかよ(怒)

SAがSecretにアクセスできるようにする

なるほど一般的にはgoogle_project_iam_memberが必要なのね〜と思っていたら罠である。google_project_iam_memberはあくまでも一般論であって、Secret ManagerのSecretへのアクセスには別のリソースが必要になる。アーハーン?ワッザ?

resource "google_secret_manager_secret" "foobar_secret" {
  secret_id = "foobar_secret"

  replication {
    auto {}
  }
  deletion_protection = true
}

resource "google_secret_manager_secret_iam_member" "builder_can_read_secret" {
  project   = var.project
  secret_id = google_secret_manager_secret.foobar_secret.secret_id
  role      = "roles/secretmanager.secretAccessor"
  member    = "serviceAccount:${google_service_account.builder.email}"
}

統一されてねぇのかよ(怒)(2)

まとめ

とりあえず目的のリソースまわりをTerraform Registryで開いて、そこに専用のIAM用リソースがないかを確認する癖を付けると良さそう。それはそうと罠すぎる。

★記事をRTしてもらえると喜びます
Webアプリケーション開発関連の記事を投稿しています.読者になってみませんか?