Terraform で GCP のサービスアカウントを管理する
なぜ書いたか
Terraform Google Provider のIAM周りのリソースはたくさんある。
google_project_iam_policy
google_project_iam_binding
google_project_iam_member
google_service_account_iam_policy
google_service_account_iam_binding
google_service_account_iam_member
google_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