Reputation: 545
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
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
}
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
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
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