Terraform で GCP のサービスアカウントを管理する
なぜ書いたか
Terraform Google Provider のIAM周りのリソースはたくさんある。
google_project_iam_policygoogle_project_iam_bindinggoogle_project_iam_membergoogle_service_account_iam_policygoogle_service_account_iam_bindinggoogle_service_account_iam_membergoogle_cloud_run_service_iam_policy- ...
たくさんある。
「手動でぽちぽちサービスアカウントを作るのも嫌だけど、Terraform のIAMも怖いし…」という気持ちになったので、これを機に整理してみます。もし間違いなどがありましたら、指摘していただけるととても喜びます。
やりたいこと
Terraform で任意の権限を付与した GCP のサービスアカウントを作成(管理)したい。
tl;dr
google_service_accountでサービスアカウントを作成- 特定サービスの全リソースに対する権限を付与したい場合は
google_project_iam_memberを使う - 特定サービスの特定リソースに対しての権限を付与したい場合は
google_*_iam_memberを使う- e.g.
- Cloud Run:
google_cloud_run_service_iam_member - Cloud Storage:
google_storage_bucket_iam_member
- Cloud Run:
- e.g.
特定サービス(の全リソース)に対する権限を付与したい
例として、 sample というサービスアカウントに Cloud Run管理者(roles/run.admin) の権限を付与します。
resource "google_service_account" "sample" {
project = "<YOUR_PROJECT_ID>"
account_id = "sample"
display_name = "Sample Service Account"
}
resource "google_project_iam_member" "sample" {
project = "<YOUR_PROJECT_ID>"
role = "roles/run.admin"
member = "serviceAccount:${google_service_account.sample.email}"
}

想定通りのサービスアカウントができました。
このように 特定サービスの全リソースに対する権限を付与したい場合は google_project_iam_member を使います。
特定サービスの特定リソースに対しての権限を付与したい
例として、 sample というサービスアカウントに sample-bucket-kaito2 というバケットの管理者権限を付与します。
resource "google_storage_bucket" "sample" {
project = "<YOUR_PROJECT_ID>"
name = "sample-bucket-kaito2"
}
resource "google_service_account" "sample" {
project = "<YOUR_PROJECT_ID>"
account_id = "sample"
display_name = "Sample Service Account"
}
resource "google_storage_bucket_iam_member" "sample" {
bucket = google_storage_bucket.sample.name
role = "roles/storage.admin"
member = "serviceAccount:${google_service_account.sample.email}"
}
コンソールから INFO PANEL を確認すると sample-bucket-kaito2 バケットのみに対して想定通りの権限が付与されています。
このようにサービス内の特定のリソースに対してのみ権限を付与したい場合は、 google_*_iam_member を使用します。
今回は GCS のため、 google_storage_bucket_iam_member でした。
まとめ
google_service_accountでサービスアカウントを作成- 特定サービスの全リソースに対する権限を付与したい場合はgoogle_project_iam_memberを使う
- 特定サービスの特定リソースに対しての権限を付与したい場合は
google_*_iam_memberを使う- e.g.
- Cloud Run:
google_cloud_run_service_iam_member - Cloud Storage:
google_storage_bucket_iam_member
- Cloud Run:
- e.g.
おまけ
google_service_account_iam_member がややこしい
google_service_account_iam_member は 特定サービスの特定リソースに対しての権限を付与したい で説明した google_*_iam_member に該当します。つまり、「特定のサービスアカウントに対しての権限を別のサービスアカウントに付与する」という目的で使います。ややこしいので注意してください。
なぜ *_iam_member を使うのか
IAM policy for projects や IAM policy for Cloud Storage Bucketを見ると、権限を付与するためのリソースとして、
*_iam_policy*_iam_binding*_iam_member
のバリエーションがあります。
その中で *_iam_member 以外のリソースは "Authoritative" と記載されており、これらは明示的に設定していないものをApply時に削除するという動作をします。
実際にドキュメントにも以下のような記述があるため 、 "Non-Authoritative" な *_iam_member を使うほうが安全です。
Authoritative. Sets the IAM policy for the project and replaces any existing policy already attached.
参考
Terraform(google provider) で Service Account に Role をバインドするときの罠 - Qiita
