通过terraform为一个服务账号分配多个Google Cloud IAM角色

17

我想通过terraform将多个IAM角色分配给一个服务帐户。我准备了一个TF文件来完成这个任务,但是它出现了错误。对于单个角色,可以成功分配,但是对于多个IAM角色,则会产生错误。

data "google_iam_policy" "auth1" {
  binding {
    role = "roles/cloudsql.admin"
    members = [
      "serviceAccount:${google_service_account.service_account_1.email}",
    ]    
    role = "roles/secretmanager.secretAccessor"
    members = [
      "serviceAccount:${google_service_account.service_account_1.email}",
    ]      
    role = "roles/datastore.owner"
    members = [
      "serviceAccount:${google_service_account.service_account_1.email}",
    ]  
    role = "roles/storage.admin"
    members = [
      "serviceAccount:${google_service_account.service_account_1.email}",
    ]      
  }
}

我如何将多个角色分配给单个服务账户?


嘿,你的问题不是很清楚...如果你告诉我们你得到的错误信息是什么会怎样? - AdolfoOG
没有最好的答案,两个答案都是好的。最佳答案取决于问题中不存在的细节。例如,成员是否已存在于IAM策略中?您是在添加还是替换IAM角色?有四个Terraform资源可以修改项目的IAM策略。这是有原因的,正确的选择需要仔细考虑。 - John Hanley
3个回答

56

我做了类似这样的事情

resource "google_project_iam_member" "member-role" {
  for_each = toset([
    "roles/cloudsql.admin",
    "roles/secretmanager.secretAccessor",
    "roles/datastore.owner",
    "roles/storage.admin",
  ])
  role = each.key
  member = "serviceAccount:${google_service_account.service_account_1.email}"
  project = my_project_id
}

权威与非权威

注意使用哪些资源。

  • google_project_iam_policy - 这是权威的 - 它将替换您 Terraform 代码中的其他策略。每个工作区目录中仅使用一次。

  • google_project_iam_binding - 这是权威的 - 它将覆盖 Terraform 代码中其他地方的角色绑定。每个工作区目录中仅使用一次。

  • google_project_iam_member - 这是非权威的 - 您可以在同一工作区目录中多次使用它 - 如果多次使用它能更好地组织您的代码。

阅读此处: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam


你的回答应该被接受。 - Imad
是的,事实上,如果更多的人投票支持这个答案而不是被接受的答案,它可以一直上升。感谢@intotecho。 - Nitin Garg
这对我有用,在我的情况下它是普通用户帐户,所以我将其更改为 member="user:emailid" - Umamaheswararao Meka
您可以使用具有授权功能的 google_project_iam_policygoogle_project_iam_binding 将自己锁定在资源之外,因为它们确保不授予其他权限。google_project_iam_member 仅将角色添加到资源中。 - intotecho

10

根据文档,每个文档配置必须有一个或多个绑定块,每个绑定块都接受以下参数: ....

你需要像这样重复绑定

data "google_iam_policy" "auth1" {
  binding {
    role = "roles/cloudsql.admin"
    members = [
      "serviceAccount:${google_service_account.service_account_1.email}",
    ]
  }
  binding {
    role = "roles/secretmanager.secretAccessor"
    members = [
      "serviceAccount:${google_service_account.service_account_1.email}",
    ]
  }
  binding {
    role = "roles/datastore.owner"
    members = [
      "serviceAccount:${google_service_account.service_account_1.email}",
    ]
  }
  binding {
    role = "roles/storage.admin"
    members = [
      "serviceAccount:${google_service_account.service_account_1.email}",
    ]
  }
}

当您使用gcloud命令时,情况是相同的,您一次只能在电子邮件列表中添加1个角色。


谢谢你的答复。现在它能工作了。但我在通过Terraform将此服务账户分配给CloudRun服务时遇到了另一个错误。它说该资源不支持 -- googleapi: Error 400: Role roles/datastore.owner 对于这个资源不受支持 helloworld-cloudrun.tf 的第60行,在 resource "google_cloud_run_service_iam_policy" "auth1": 60: resource "google_cloud_run_service_iam_policy" "auth1" { - Aniket
我的云运行代码 -- resource "google_cloud_run_service_iam_policy" "auth1" { location = google_cloud_run_service.helloworld.location project = google_cloud_run_service.helloworld.project service = google_cloud_run_service.helloworld.name policy_data = data.google_iam_policy.auth1.policy_data } - Aniket
IAM角色在一开始可能会让人感到奇怪。可以这样想:我想在服务/项目/组织中授予成员一个角色。你要执行的是我想在Cloud Run服务上为成员授予数据存储所有者角色...。Cloud Run和Datastore之间没有关系。你想在项目上为成员授予数据存储所有者角色...。在Cloud Run上,你只能授予有限数量的角色,我想在Cloud Run服务上为成员授予run.invoker角色...。这样就有意义了。 - guillaume blaquiere
我不知道我是否表达清楚了... 所以使用这个资源 resource "google_project_iam_binding" .... - guillaume blaquiere
Intotecho的答案更好,应该在这里推广。 - Nitin Garg

1

我目前还无法发表评论或点赞,所以这里提供 另外一个答案,但是@intotecho说得对。

我会说,不要使用Terraform创建策略,除非你真的知道自己在做什么!在GCP中,每个项目只允许一个策略。如果您应用了该策略,那么只有服务帐户将拥有访问权限,而没有人员。:)即使我们不希望人类执行人类工作,至少可以查看您拥有的GCP项目。

特别是如果您使用的模型是多个Terraform工作区对项目执行iam操作。如果您使用策略,它将类似于制酒过程,这将是一次搅拌派对!最近应用的策略将获胜(如果使用的服务帐户TF包含在该策略中,否则它将锁定自己!)

可能人类从文件夹或组织本身继承了查看者角色,但使用google_project_iam_member指定多个角色是更好的方法,也是95%的TF权限在GCP中完成的方式。


有时候你希望你的策略能够覆盖其他人所做出的任何更改。如果是这样,使用 google_iam_policy。但通常情况下,即使其他人在之前或之后添加了更多角色,你也希望添加角色 - 在这种情况下,请使用 google_project_iam_member - intotecho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接