Authoritative Vs non-Authoritative Terraform resources for GCP IAM policies

Once the services/resources (like GCS bucket, BigQuery dataset) are deployed to GCP, permissions are needed to access those services/resources.

We can grant access to Google Cloud services/resources by using allow policies, also known as Identity and Access Management (IAM) policies, which are attached to services/resources.

A Policy is a collection of bindings. A binding binds one or more members, or principals, to a single role. Principals can be user accounts, service accounts, Google groups, and domains (such as G Suite). A role is a named list of permissions; each role can be an IAM predefined role or a user-created custom role.

We are handling both the deployment of services/resources and granting the access on the services/resources via Terraform.

There are different resources in Terraform to help us manage the IAM policy for a GCP project.

We started using google_project_iam_binding resource for granting access on the project to Service Accounts. The Terraform code we used for this resource is

This code grants bigquery.dataEditor role on the project to an User ID and a Service Account.

Then, we tried to create a new Service Account and grant permission to it using service-account-iam module in the same .tf file having the google_project_iam_binding resource. The code we used is

The new Service Account got created and the permission was applied fine during the first run.

Then, we noticed something unusual during the next run. The bigquery.dataEditor permission for the new Service Account got revoked.

After some digging, we found that this happened due to google_project_iam_binding resource.

There are 2 categories in the Terraform resources present to help in managing the IAM policies for the GCP project.

Authoritative — Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the project are preserved.

Non-authoritative — Updates the IAM policy to grant a role to a new member. Other members for the role for the project are preserved.

This is what happened in our case, google_project_iam_binding resource preserved the permission granted to User ID and Service Account, and revoked the permission of the new Service Account which is not part of that resource as google_project_iam_binding resource is Authoritative.

To avoid any such problems in future, we changed all the Terraform resources in our code to Non-authoritative. This is the new code.

Disclaimer: The posts here represent my personal views and not those of my employer or any specific vendor. Any technical advice or instructions are based on my own personal knowledge and experience.