我可以在单个策略中授予服务帐户对多个存储桶的访问权限吗?

Can I grant a service account access to multiple buckets in a single policy?

我来自 AWS,并且仍在学习 IAM/Policies 如何在 GCP 中工作。在 AWS 中,如果我想授予一个角色访问多个存储桶的权限,我会在 terraform 中做这样的事情:

data "aws_iam_policy_document" "policy" {

  statement {
    actions = [
      "s3:Get*"
    ]

    resources = [
      "${var.bucket1_arn}/*",
      "${var.bucket2_arn}/*",
      "${var.bucket3_arn}/*",
    ]
  }

}

resource "aws_iam_policy" "policy" {
  name   = "my-policy"
  policy = data.aws_iam_policy_document.policy.json
}


resource "aws_iam_role_policy_attachment" "policy_attachment" {
  policy_arn = aws_iam_policy.policy.arn
  role       = ${var.role_name}
}

我一直在尝试弄清楚如何在 GCP 中执行此操作,但到目前为止我发现的是我需要将策略单独附加到每个存储桶,如下所示:

data "google_iam_policy" "policy" {
  binding {
    role = "roles/storage.objectViewer"

    members = [
      "serviceAccount:${service_account}",
    ]
  }

}

resource "google_storage_bucket_iam_policy" "bucket_1" {
  bucket = google_storage_bucket.bucket_1.name
  policy_data = data.google_iam_policy.policy.policy_data
}

resource "google_storage_bucket_iam_policy" "bucket_2" {
  bucket = google_storage_bucket.bucket_2.name
  policy_data = data.google_iam_policy.policy.policy_data
}

resource "google_storage_bucket_iam_policy" "bucket_3" {
  bucket = google_storage_bucket.bucket_3.name
  policy_data = data.google_iam_policy.policy.policy_data
}

这是授予服务帐户访问多个存储桶的正确方法(或最佳做法吗?)?

是的,Google IAM 是以资源为中心的(我的理解是 AWS 翻转了这一点并且以身份为中心),您将策略应用于资源。

因为容器(即一个项目)可能包含许多 Bucket,您唯一的选择是将绑定应用到项目本身,然后,项目中的每个 Bucket 都会有绑定。

您采用的方法会产生精确度(只有那些被授予角色的存储桶才具有精确度),尽管对于角色绑定阶段(很少进行的操作)来说有点繁琐。

DazWikin 的答案是正确的,但在 GCP 上你可以作弊。事实上,您可以使用 IAM 条件并构建类似的东西:

  • 在文件夹或组织级别授予帐户(服务或用户),以授予其对所有资源的访问权限。例如,授予角色 storage Admin
  • 使用条件仅在存储桶的子集上强制执行此角色

像那样

resource "google_organization_iam_binding" "Binding" {
  members = ["<ACCOUNT_EMAIL>"]
  org_id = "<YOUR_ORG_ID>"
  role = "roldes/storage.admin"
  condition {
    expression = 'resource.name.startsWith("projects/_/buckets/<BUCKET1>") || resource.name.startsWith("projects/_/buckets/<BUCKET2>")'
    title = "bucket filter"
  }
}

它不是很干净,尤其是当您有要添加到列表中的新存储桶时进行更新,但它是您问题的解决方法。