如何在 terraform 中正确创建具有角色的 gcp 服务帐户
Posted
技术标签:
【中文标题】如何在 terraform 中正确创建具有角色的 gcp 服务帐户【英文标题】:How to properly create gcp service-account with roles in terraform 【发布时间】:2020-07-15 02:28:41 【问题描述】:这是我用来创建服务帐户并将角色绑定到它的 terraform 代码:
resource "google_service_account" "sa-name"
account_id = "sa-name"
display_name = "SA"
resource "google_project_iam_binding" "firestore_owner_binding"
role = "roles/datastore.owner"
members = [
"serviceAccount:sa-name@$var.project.iam.gserviceaccount.com",
]
depends_on = [google_service_account.sa-name]
上面的代码效果很好...除了它从项目中先前分配此角色的任何其他服务帐户中删除了datastore.owner
。我们有许多团队使用的单个项目,并且有由不同团队管理的服务帐户。我的 terraform 代码只有我们团队的服务帐户,我们最终可能会破坏其他团队的服务帐户。
在 terraform 中还有其他方法可以做到这一点吗?
这当然可以通过 GCP UI 或 gcloud cli 完成,不会出现任何问题或影响其他 SA。
【问题讨论】:
其他服务也是用 terraform 创建的吗?命令terraform plan
的结果是什么?
其中很多是手动创建的,无法控制其他团队正在做什么。计划或申请从未显示出任何破坏。
【参考方案1】:
来自 terraform docs,“google_project_iam_binding”是Authoritative. Sets the IAM policy for the project and replaces any existing policy already attached
。这意味着它完全替换了其中给定角色的成员。
要仅将角色添加到新服务帐户,而不编辑该角色中的其他所有人,您应该使用资源“google_project_iam_member”:
resource "google_service_account" "sa-name"
account_id = "sa-name"
display_name = "SA"
resource "google_project_iam_member" "firestore_owner_binding"
project = <your_gcp_project_id_here>
role = "roles/datastore.owner"
member = "serviceAccount:$google_service_account.sa-name.email"
您的示例的额外更改:使用服务帐户资源email
生成的属性来删除显式depends_on
。如果您这样做,则不需要depends_on
,并且可以避免错误配置导致的错误。
Terraform 可以通过使用另一个资源的变量来推断依赖关系。检查the docs here 以更好地了解此行为。
【讨论】:
从文档中,保留项目的 IAM 策略的其他角色。 google_project_iam_binding:给定角色的权威。更新 IAM 策略以将角色授予成员列表。项目的 IAM 策略中的其他角色被保留。【参考方案2】:这是 Terraform 的常见问题。要么你用它做所有事情,要么什么都不做。如果您介于两者之间,可能会发生意想不到的事情!
如果你想使用 terraform,你必须将现有的导入 tfstate。 Here the doc for the bindind,当然,您必须在 Terraform 文件中添加所有帐户。如果没有,绑定将被删除,但这一次,您会在tf plan
中看到删除。
【讨论】:
以上是关于如何在 terraform 中正确创建具有角色的 gcp 服务帐户的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Terraform 创建没有代入角色策略的 AWS IAM 角色?
Terraform:将 AWS 托管策略附加到角色的正确方法?