I'm new to Google Cloud Platform and have set up a Service Account that I'm using to allow Terraform to set up some services through a GitHub Actions workflow. It seems like everything is linked up between my GitHub and GCP accounts because I'm able to run Terraform init and plan from my workflow and I can see that it's creating state files in a GCP storage bucket that I created manually. However, the apply step (which is just trying to create another storage bucket) is failing with with the following error:
Error: googleapi: Error 403: Caller does not have storage.buckets.create access to the Google Cloud project. Permission 'storage.buckets.create' denied on resource (or it may not exist)., forbidden
When I check the IAM tab in the web console (IAM & Admin), I can see that the Service Account principal used by Terraform has the 'Storage Admin', 'Service Account Token Creator', and 'Service Account User' roles attached to it.
However, when I check the same principal under the Service Accounts tab, it only shows the 'Service Account Token Creator' and 'Service Account User' roles attached to it. I also cannot add 'Storage Admin' from here.
I would have expected the Service Account principal to have the same roles attached to it regardless of which table I was viewing it in, or that I would be able to attach the needed role to it to resolve the above error. Are these dashboards actually showing different things, and if so, how can I grant the 'Storage Admin' role to my Service Account to allow Terraform to use it to create a new storage bucket?
That's a good question because of the service account duality.
Service Account is an identity, a technical account. In the IAM page, you can use the service account email, as any other user email, to grant the service account on services, like Cloud Storage, BigQuery and others.
When you use the IAM page, you grant the permission at the project level. The ressource is the project. You can go to some services, like Cloud Storage or BigQuery, and you have also a permission tab to grant identities (user/service accounts) at the resource level, the bucket, the dataset or the table.
I'm mentioning the "resource" level, because here come the Service account duality. Service account is also a resource, and you can grant permission on it, in the permission tab on a service account.
Ok, it's a bit disturbing. I do not know why it is possible to grant so many role on a service account. I usually use 2: Service Account User and Service Account Token Creator.
This 2 roles allow you creating impersonation on a service account. Let imagine this: As a user, I would be able to impersonate a single one service account, but not ALL the service account of the project.
In that case, your user email do not must be granted in the IAM page, because it's a the project resource level, but only on the dedicated service account, so at the service account resource level; the permissions tab on your service account page.
And yes, a day you will land on this absurd situation where you will have to grant a service account (so the email, the identity) on itself (so the resource) as Service Account Token Creator, for, for instance, make it able to generated an Identity Token (required to invoke Cloud Run or Cloud Function) on Composer 3 (I did it the past week!)