Aniket
Aniket

Reputation: 545

Want to assign multiple Google cloud IAM roles to a service account via terraform

I want to assign multiple IAM roles to a single service account through terraform. I prepared a TF file to do that, but it has an error. With a single role it can be successfully assigned but with multiple IAM roles, it gave an error.

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

How can I assign multiple roles against a single service account?

Upvotes: 20

Views: 23133

Answers (3)

intotecho
intotecho

Reputation: 5684

I did something like this

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
}

Authoritative vs non-Authoritative

Pay attention to which of the resources you are using.

  • google_project_iam_policy - This is Authoritative - it will replace other policies in your Terraform code. Only use once per workspace directory.

  • google_project_iam_binding - This is Authoritative - it will override other bindings to the role elsewhere in your Terraform code. Only use once per workspace directory.

  • google_project_iam_member - This is non-Authoritative - This you can use many times in the same workspace directory - if using it multiple times better organizes your code.

Read here: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam

Upvotes: 67

Will Beebe
Will Beebe

Reputation: 11

I can't comment or upvote yet so here's another answer, but @intotecho is right.

I'd say do not create a policy with Terraform unless you really know what you're doing! In GCP, there's only one policy allowed per project. If you apply that policy, only the service accounts will have access, no humans. :) Even though we don't want humans to do human things, it's helpful to at least have view access to the GCP project you own.

Especccciallyy if you use the model that there are multiple Terraform workspaces performing iam operations on the project. If you use policies it will be similar to how wine is made, it will be a stomping party! The most recently applied policy will win (if the service account TF is using is included in that policy, otherwise it will lock itself out!)

It's possible humans get an inherited viewer role from a folder or the org itself, but assigning multiple roles using the google_project_iam_member is a much much better way and how 95% of the permissions are done with TF in GCP.

Upvotes: 1

guillaume blaquiere
guillaume blaquiere

Reputation: 75715

According with the documentation

Each document configuration must have one or more binding blocks, which each accept the following arguments: ....

You have to repeat the binding, like this

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

It's the same thing with you use the gcloud command, you can add only 1 role at the time on a list of email.

Upvotes: 10

Related Questions