terraform-google-modules / terraform-example-foundation

Shows how the CFT modules can be composed to build a secure cloud foundation
https://cloud.google.com/architecture/security-foundations
Apache License 2.0
1.21k stars 708 forks source link

Terraform service account permissions for resources in created projects #592

Closed tomasgareau closed 2 years ago

tomasgareau commented 2 years ago

The Cloud Security Foundations Guide mentions in section 5.3.6. that

There are two project editors associated with a project. One is the custom service account that's used by the deployment pipeline in the seed project. The other project editor is a firecall account ...

It's not clear to me where (or if) these permissions are configured for the Terraform service account in the 0-bootstrap module.

In my specific case, I've replaced the Cloudbuild/Jenkins project with a custom CI/CD project that creates:

I then successfully deployed this manually to create the seed & CI/CD projects. Now, I'm trying to plan this while impersonating the Terraform service account from the seed project and I'm getting errors refreshing my state:

╷
│ Error: Error when reading or editing SQL Database Instance "REDACTED": googleapi: Error 403: The client is not authorized to make this request., notAuthorized
│
│   with module.concourse_bootstrap.google_sql_database_instance.db_concourse,
│   on modules/concourse-cluster/main.tf line 104, in resource "google_sql_database_instance" "db_concourse":
│  104: resource "google_sql_database_instance" "db_concourse" {
│
╵
╷
│ Error: Error when reading or editing Container Registry Storage Bucket "REDACTED": googleapi: Error 403: org-terraform@REDACTED.com does not have storage.buckets.get access to the Google Cloud Storage bucket., forbidden
│
│   with module.concourse_bootstrap.google_container_registry.cicd,
│   on modules/concourse-cluster/main.tf line 220, in resource "google_container_registry" "cicd":
│  220: resource "google_container_registry" "cicd" {
│
╵
╷
│ Error: Error when reading or editing Storage Bucket "REDACTED": googleapi: Error 403: org-terraform@REDACTED.com does not have storage.buckets.get access to the Google Cloud Storage bucket., forbidden
│
│   with module.concourse_bootstrap.google_storage_bucket.cicd_artifacts,
│   on modules/concourse-cluster/main.tf line 260, in resource "google_storage_bucket" "cicd_artifacts":
│  260: resource "google_storage_bucket" "cicd_artifacts" {
│
╵
╷
│ Error: Error when reading or editing Container Cluster "REDACTED": googleapi: Error 403: Required "container.clusters.get" permission(s) for "REDACTED"., forbidden
│
│   with module.concourse_bootstrap.module.gke_concourse.google_container_cluster.primary,
│   on .terraform/modules/concourse_bootstrap.gke_concourse/cluster.tf line 22, in resource "google_container_cluster" "primary":
│   22: resource "google_container_cluster" "primary" {
│
╵

Just wondering what the recommended approach is here per the CFT guide & this example repo. Should I:

Or have I simply goofed the manual bootstrapping steps and this should already be working?

morgante commented 2 years ago

If projects are created using the bootstrap process + examples in this repo, the Terraform account should get owner access already.

if you're using some other process to create the projects (it's not entirely clear where your implementation diverged from the example), you should go ahead and grant the Terraform service account editor permission. You can add that to the roles granted in the bootstrap by overriding sa_org_iam_permissions.

tomasgareau commented 2 years ago

(it's not entirely clear where your implementation diverged from the example)

Agreed, haha -- I'm trying to nail down exactly how the org-terraform account is granted owner access since this seems to be missing from our implementation.

To clarify, our bootstrap module is loosely based on the jenkins-agent example from this repo. Instead of uncommenting the jenkins-agent lines from


That said, I think I've figured this out.

I suspect that what I'm bumping into is similar to this Github issue from the terraform-google-bootstrap module. Since I initially ran the Terraform module manually, it was my user account that created the seed & CICD projects, and so my user account was set as the project owner. :chicken: :egg:

The linked issue above suggests that an iam_binding resource could be used to move "owner" permissions to the org-terraform account. Something like this?

resource "google_project_iam_binding" "owner" {
  project = module.cicd_project.project_id
  role    = "roles/owner"
  member  = "serviceAccount:${module.seed_bootstrap.terraform_sa_email}"
}

Then for future steps (1-org, 2-environments...) this shouldn't be a problem since the org-terraform account would be the one creating the projects (and hence will automatically be set as the owner).


Is this is the case then great, we can close this issue. If you think it would be worth expanding the README documentation in this repo to describe this let me know -- I'd be happy to submit a PR for review.

morgante commented 2 years ago

Yep, iam_binding should fix that for you! Since this should be working automatically out of the box if people use this repo directly, we probably don't need additional docs for it quite yet (they can find this issue in search).