塀の備忘録

上伊那ぼたん描いてます

google_project_iam_bindingでtfファイルをstraightforwardに書く

概要

TerraformでGCP IAM設定をする際、google_project_iam_bindingの利用には注意が必要だ。

bindingリソースの挙動を把握していないと、新規にロールを有効化した際に既存のbindingリソースから意図せずロールを剥奪してしまう可能性があるからだ。

では、google_project_iam_bindingは使わないほうが良いのかーというと、別にそうでもないという話。

Terraform で GCP IAM 設定

google_project_iam_bindingは、任意のロールとその権限を有するアカウントとの対応関係を1:1マッピングする。そのため、誤って同一ロールに対してbindingリソースを複数作成すると、新しく作られたリソースが優先され、古いリソースからはロールが剥奪されてしまう。

一方、google_project_iam_memberはその対応関係を1:nマッピングできる。ゆえに、memberリソースを追加しても既存のリソースに影響を及ぼさず、複数のmemberリソースすべてに対してロールが有効化される。

この点は下記の記事に詳しい。 zenn.dev

google_project_iam_bindingを使うメリット

上記のような認識から、なんとなくgoogle_project_iam_bindingは指定せず、google_project_iam_memberを使えばいいじゃん……と思わないだろうか。

だが、bindingを指定することで整理されたtfが書ける。というのも、memberとbindingではロールを指定する方法が若干異なるためだ。

memberはひとつのリソースに対して、下記のようにメールアドレスが1件ずつしか指定できない。だから、同一のロールを複数のアカウントに紐付けたい場合は、memberリソースを繰り返し指定する必要があり、冗長な書き方を強いられる。

resource "google_project_iam_member" "project" {
  project = "hoge-project-id"
  role    = "roles/editor"
  member  = "user:taro@example.com"
}

1件ずつロールとアカウントの紐付けを管理し、かつ管理外の設定(他のmemberリソース)と共存できる……というのがgoogle_project_iam_memberのpolicyなので、意味のある冗長さではあるのだが。

一方、bindingはメールアドレスをstringのスライスで書くため、下記のように複数行にわたって指定できる。

resource "google_project_iam_binding" "project" {
  project = "hoge-project-id"
  role    = "roles/editor"

  members = [
    "user:taro@example.com",
    "user:hanako@example.com",
  ]
}

同一のロールを複数のアカウントに紐付けたい場合、memberよりもbindingを使うほうがstraightforwardなtfファイルが書ける。 bindingリソースのAuthoritativeな挙動を認識していれば、単純に書く分にはbindingを使うで良いと思う。

参考

memberやbindingにはそれぞれメリデメがあるので、悩んだら下記記事など参考にすると良さそう。

scrapbox.io