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

Viewed 445

I'm coming from AWS and still learning how IAM/Policies work in GCP. In AWS, if I wanted to grant a role access to multiple buckets I would do something like this in 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}
}

I've been trying to figure out how to do it in GCP, but all I've found so far is that I need to attach a policy to each bucket individually, like so:

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
}

Is this the correct way (or best practice?) to grant a service account access to multiple buckets?

2 Answers

Yes, Google IAM is resource-centric (my understanding that AWS flips this and is identity-centric), you apply policies to resources.

Because the container (i.e. a Project) may contain many Buckets, you're only alternative is to apply the binding to the Project itself but then, every Bucket in the Project will have the binding.

The approach you're taking yields precision (only those buckets granted the role have it) albeit slightly onerous for the role binding phase (something done infrequently).

DazWikin answer is right, but on GCP you can cheat. In fact, you can use IAM conditions and build something like that:

  • Grant the account (service or user) at the folder or organisation level, to grant it the access to all the resources. For example, grant the role storage Admin
  • Use condition to enforce this role on only a subset of bucket

Like that

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"
  }
}

It's not so clean, especially to update when you have new buckets that you want to add in the list, but it's a workaround at your question.

Related