Terraform配置GCP:多用户绑定同一服务账号角色异常问题
问题根源与解决方案
问题1:google_service_account_iam_binding导致旧用户权限被移除的原因
你用for_each为每个用户创建了独立的google_service_account_iam_binding资源,但这个资源的特性是权威性绑定——它会完全覆盖指定角色的所有成员列表。也就是说,每个iam_binding都会把roles/iam.serviceAccountTokenCreator的成员设置成自己的members值,后创建的资源会直接覆盖之前的配置,最终只有最后一个用户的权限生效,旧用户被自动移除。
问题2:google_service_account_iam_member的参数错误
google_service_account_iam_member是单个成员绑定的资源,它的参数是单数的member,而非复数的members,这就是你报错的直接原因。
方案一:使用google_service_account_iam_binding(无for_each)
直接将所有用户打包成members列表,一次性管理该角色的所有成员,避免多次绑定覆盖的问题。
修改后的代码:
resource "google_service_account_iam_binding" "super-admin-impersonators" { provider = google.as_super_admin service_account_id = google_service_account.terraform-super-admin.name role = "roles/iam.serviceAccountTokenCreator" members = [ for user in var.user_accs_impersonators_info.as_super_admin : "${user.acc_type}:${user.acc_details.email}" ] }
- 优点:配置简洁,适合成员列表变化不频繁的场景
- 缺点:任何成员变更都会触发整个绑定资源的更新
方案二:使用google_service_account_iam_member(推荐)
每个用户对应一个独立的iam_member资源,粒度更细,增删用户只会影响对应的资源,不会干扰其他用户的权限。
修正参数后的代码:
resource "google_service_account_iam_member" "super-admin-impersonators" { provider = google.as_super_admin for_each = toset([ for user in var.user_accs_impersonators_info.as_super_admin : "${user.acc_type}:${user.acc_details.email}" ]) service_account_id = google_service_account.terraform-super-admin.name role = "roles/iam.serviceAccountTokenCreator" member = each.key # 替换为单数参数member }
- 优点:
- 新增用户仅创建新资源,不修改现有配置
- 删除用户仅销毁对应资源,其他用户权限不受影响
- 资源粒度清晰,便于排查问题
验证方法
修改inputs.tfvars添加新用户后,执行terraform plan,应该看到仅新增1个iam_member资源,无删除操作;apply完成后,两个用户都会拥有roles/iam.serviceAccountTokenCreator权限。
内容的提问来源于stack exchange,提问作者Imad
相关产品推荐
相关产品推荐

