From 2eb996d33d806b34bc4c0d52f140f68401d9224e Mon Sep 17 00:00:00 2001 From: "agusramirez@google.com" Date: Wed, 15 Jun 2022 19:12:11 -0500 Subject: [PATCH 01/11] sourcerepo and cloudbuild at 01-resman --- fast/stages/00-bootstrap/automation.tf | 3 ++- fast/stages/01-resman/cicd-networking.tf | 2 +- fast/stages/01-resman/cicd-security.tf | 2 +- fast/stages/01-resman/cicd-teams.tf | 4 ++-- fast/stages/01-resman/outputs.tf | 8 +++++--- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/fast/stages/00-bootstrap/automation.tf b/fast/stages/00-bootstrap/automation.tf index 0874fc4ff6..11a8b34d8d 100644 --- a/fast/stages/00-bootstrap/automation.tf +++ b/fast/stages/00-bootstrap/automation.tf @@ -36,7 +36,8 @@ module "automation-project" { # machine (service accounts) IAM bindings iam = { "roles/owner" = [ - module.automation-tf-bootstrap-sa.iam_email + module.automation-tf-bootstrap-sa.iam_email, + module.automation-tf-resman-sa.iam_email ] "roles/iam.serviceAccountAdmin" = [ module.automation-tf-resman-sa.iam_email diff --git a/fast/stages/01-resman/cicd-networking.tf b/fast/stages/01-resman/cicd-networking.tf index 541d8bda06..9bb96f7968 100644 --- a/fast/stages/01-resman/cicd-networking.tf +++ b/fast/stages/01-resman/cicd-networking.tf @@ -35,7 +35,7 @@ module "branch-network-cicd-repo" { fast-02-networking = { filename = ".cloudbuild/workflow.yaml" included_files = ["**/*tf", ".cloudbuild/workflow.yaml"] - service_account = module.branch-network-sa.id + service_account = module.branch-network-sa-cicd.0.id substitutions = {} template = { project_id = null diff --git a/fast/stages/01-resman/cicd-security.tf b/fast/stages/01-resman/cicd-security.tf index d6b0b86917..ff456166af 100644 --- a/fast/stages/01-resman/cicd-security.tf +++ b/fast/stages/01-resman/cicd-security.tf @@ -35,7 +35,7 @@ module "branch-security-cicd-repo" { fast-02-security = { filename = ".cloudbuild/workflow.yaml" included_files = ["**/*tf", ".cloudbuild/workflow.yaml"] - service_account = module.branch-security-sa.id + service_account = module.branch-security-sa-cicd.0.id substitutions = {} template = { project_id = null diff --git a/fast/stages/01-resman/cicd-teams.tf b/fast/stages/01-resman/cicd-teams.tf index 2766e301e0..931b0a7cae 100644 --- a/fast/stages/01-resman/cicd-teams.tf +++ b/fast/stages/01-resman/cicd-teams.tf @@ -37,7 +37,7 @@ module "branch-teams-dev-pf-cicd-repo" { included_files = [ "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" ] - service_account = module.branch-teams-dev-pf-sa.iam_email + service_account = module.branch-teams-dev-pf-sa-cicd.0.id substitutions = {} template = { project_id = null @@ -68,7 +68,7 @@ module "branch-teams-prod-pf-cicd-repo" { included_files = [ "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" ] - service_account = module.branch-teams-prod-pf-sa.iam_email + service_account = module.branch-teams-prod-pf-sa-cicd.0.id substitutions = {} template = { project_id = null diff --git a/fast/stages/01-resman/outputs.tf b/fast/stages/01-resman/outputs.tf index f91a843d81..b7de52409b 100644 --- a/fast/stages/01-resman/outputs.tf +++ b/fast/stages/01-resman/outputs.tf @@ -144,9 +144,11 @@ output "cicd_repositories" { description = "WIF configuration for CI/CD repositories." value = { for k, v in local.cicd_repositories : k => { - branch = v.branch - name = v.name - provider = local.identity_providers[v.identity_provider].name + branch = v.branch + name = v.name + provider = try( + local.identity_providers[v.identity_provider].name, null + ) service_account = local.cicd_workflow_attrs[k].service_account } if v != null } From e3d91e84e4463162cac6ca9d96645bc2787a17ec Mon Sep 17 00:00:00 2001 From: "agusramirez@google.com" Date: Wed, 15 Jun 2022 21:34:26 -0500 Subject: [PATCH 02/11] sourcerepo and cloudbuild at 01-resman --- fast/stages/01-resman/cicd-data-platform.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fast/stages/01-resman/cicd-data-platform.tf b/fast/stages/01-resman/cicd-data-platform.tf index e62a022086..66247d2696 100644 --- a/fast/stages/01-resman/cicd-data-platform.tf +++ b/fast/stages/01-resman/cicd-data-platform.tf @@ -37,7 +37,7 @@ module "branch-dp-dev-cicd-repo" { included_files = [ "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" ] - service_account = module.branch-dp-dev-sa.iam_email + service_account = module.branch-dp-dev-sa-cicd.0.id substitutions = {} template = { project_id = null @@ -68,7 +68,7 @@ module "branch-dp-prod-cicd-repo" { included_files = [ "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" ] - service_account = module.branch-dp-prod-sa.iam_email + service_account = module.branch-dp-prod-sa-cicd.0.id substitutions = {} template = { project_id = null From f163bad220972d58d36de4864a36c4f459276f2f Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 16 Jun 2022 21:56:18 +0200 Subject: [PATCH 03/11] add automation project number to stage 0 outputs --- fast/stages/00-bootstrap/automation.tf | 7 ++++++- fast/stages/00-bootstrap/outputs.tf | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/fast/stages/00-bootstrap/automation.tf b/fast/stages/00-bootstrap/automation.tf index 11a8b34d8d..bba34d06f4 100644 --- a/fast/stages/00-bootstrap/automation.tf +++ b/fast/stages/00-bootstrap/automation.tf @@ -36,7 +36,9 @@ module "automation-project" { # machine (service accounts) IAM bindings iam = { "roles/owner" = [ - module.automation-tf-bootstrap-sa.iam_email, + module.automation-tf-bootstrap-sa.iam_email + ] + "roles/cloudbuild.builds.editor" = [ module.automation-tf-resman-sa.iam_email ] "roles/iam.serviceAccountAdmin" = [ @@ -45,6 +47,9 @@ module "automation-project" { "roles/iam.workloadIdentityPoolAdmin" = [ module.automation-tf-resman-sa.iam_email ] + "roles/source.admin" = [ + module.automation-tf-resman-sa.iam_email + ] "roles/storage.admin" = [ module.automation-tf-resman-sa.iam_email ] diff --git a/fast/stages/00-bootstrap/outputs.tf b/fast/stages/00-bootstrap/outputs.tf index cfb2460b87..9104586510 100644 --- a/fast/stages/00-bootstrap/outputs.tf +++ b/fast/stages/00-bootstrap/outputs.tf @@ -57,6 +57,7 @@ locals { federated_identity_providers = local.wif_providers outputs_bucket = module.automation-tf-output-gcs.name project_id = module.automation-project.project_id + project_number = module.automation-project.number } custom_roles = local.custom_roles } From c87c645bf088e37521ea54b956a316a4bc3e980f Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 16 Jun 2022 21:56:48 +0200 Subject: [PATCH 04/11] add missing try to stage 1 outputs --- fast/stages/01-resman/outputs.tf | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fast/stages/01-resman/outputs.tf b/fast/stages/01-resman/outputs.tf index b7de52409b..73ed2eedd5 100644 --- a/fast/stages/01-resman/outputs.tf +++ b/fast/stages/01-resman/outputs.tf @@ -52,9 +52,11 @@ locals { for k, v in local.cicd_repositories : k => templatefile( "${path.module}/templates/workflow-${v.type}.yaml", merge(local.cicd_workflow_attrs[k], { - identity_provider = local.identity_providers[v.identity_provider].name - outputs_bucket = var.automation.outputs_bucket - stage_name = k + identity_provider = try( + local.identity_providers[v.identity_provider].name, null + ) + outputs_bucket = var.automation.outputs_bucket + stage_name = k }) ) } From 2b61efb722187ba548dd79aff08a9f41ad20212d Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 16 Jun 2022 21:57:09 +0200 Subject: [PATCH 05/11] add project number to sgae 1 values --- fast/stages/01-resman/variables.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/fast/stages/01-resman/variables.tf b/fast/stages/01-resman/variables.tf index c31e677904..c1d534bca6 100644 --- a/fast/stages/01-resman/variables.tf +++ b/fast/stages/01-resman/variables.tf @@ -23,6 +23,7 @@ variable "automation" { type = object({ outputs_bucket = string project_id = string + project_number = string federated_identity_pool = string federated_identity_providers = map(object({ issuer = string From da17d5786346eace988e6ed8a95c7cad6b848b33 Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 16 Jun 2022 21:59:44 +0200 Subject: [PATCH 06/11] fix tfdoc --- fast/stages/00-bootstrap/README.md | 20 +++++++-------- fast/stages/01-resman/README.md | 40 +++++++++++++++--------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/fast/stages/00-bootstrap/README.md b/fast/stages/00-bootstrap/README.md index c217a50f7b..3fcfb66c17 100644 --- a/fast/stages/00-bootstrap/README.md +++ b/fast/stages/00-bootstrap/README.md @@ -457,15 +457,15 @@ The remaining configuration is manual, as it regards the repositories themselves | name | description | sensitive | consumers | |---|---|:---:|---| -| [automation](outputs.tf#L81) | Automation resources. | | | -| [billing_dataset](outputs.tf#L86) | BigQuery dataset prepared for billing export. | | | -| [cicd_repositories](outputs.tf#L91) | CI/CD repository configurations. | | | -| [custom_roles](outputs.tf#L103) | Organization-level custom roles. | | | -| [federated_identity](outputs.tf#L108) | Workload Identity Federation pool and providers. | | | -| [outputs_bucket](outputs.tf#L118) | GCS bucket where generated output files are stored. | | | -| [project_ids](outputs.tf#L123) | Projects created by this stage. | | | -| [providers](outputs.tf#L142) | Terraform provider files for this stage and dependent stages. | ✓ | stage-01 | -| [service_accounts](outputs.tf#L132) | Automation service accounts created by this stage. | | | -| [tfvars](outputs.tf#L151) | Terraform variable files for the following stages. | ✓ | | +| [automation](outputs.tf#L82) | Automation resources. | | | +| [billing_dataset](outputs.tf#L87) | BigQuery dataset prepared for billing export. | | | +| [cicd_repositories](outputs.tf#L92) | CI/CD repository configurations. | | | +| [custom_roles](outputs.tf#L104) | Organization-level custom roles. | | | +| [federated_identity](outputs.tf#L109) | Workload Identity Federation pool and providers. | | | +| [outputs_bucket](outputs.tf#L119) | GCS bucket where generated output files are stored. | | | +| [project_ids](outputs.tf#L124) | Projects created by this stage. | | | +| [providers](outputs.tf#L143) | Terraform provider files for this stage and dependent stages. | ✓ | stage-01 | +| [service_accounts](outputs.tf#L133) | Automation service accounts created by this stage. | | | +| [tfvars](outputs.tf#L152) | Terraform variable files for the following stages. | ✓ | | diff --git a/fast/stages/01-resman/README.md b/fast/stages/01-resman/README.md index 8ec133ce01..a054106f61 100644 --- a/fast/stages/01-resman/README.md +++ b/fast/stages/01-resman/README.md @@ -178,30 +178,30 @@ Due to its simplicity, this stage lends itself easily to customizations: adding | name | description | type | required | default | producer | |---|---|:---:|:---:|:---:|:---:| -| [automation](variables.tf#L20) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 00-bootstrap | -| [billing_account](variables.tf#L37) | Billing account id and organization id ('nnnnnnnn' or null). | object({…}) | ✓ | | 00-bootstrap | -| [organization](variables.tf#L140) | Organization details. | object({…}) | ✓ | | 00-bootstrap | -| [prefix](variables.tf#L164) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 00-bootstrap | -| [cicd_repositories](variables.tf#L46) | CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | object({…}) | | null | | -| [custom_roles](variables.tf#L116) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 00-bootstrap | -| [groups](variables.tf#L125) | Group names to grant organization-level permissions. | map(string) | | {…} | 00-bootstrap | -| [organization_policy_configs](variables.tf#L150) | Organization policies customization. | object({…}) | | null | | -| [outputs_location](variables.tf#L158) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable | string | | null | | -| [tag_names](variables.tf#L175) | Customized names for resource management tags. | object({…}) | | {…} | | -| [team_folders](variables.tf#L192) | Team folders to be created. Format is described in a code comment. | map(object({…})) | | null | | +| [automation](variables.tf#L20) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 00-bootstrap | +| [billing_account](variables.tf#L38) | Billing account id and organization id ('nnnnnnnn' or null). | object({…}) | ✓ | | 00-bootstrap | +| [organization](variables.tf#L141) | Organization details. | object({…}) | ✓ | | 00-bootstrap | +| [prefix](variables.tf#L165) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 00-bootstrap | +| [cicd_repositories](variables.tf#L47) | CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | object({…}) | | null | | +| [custom_roles](variables.tf#L117) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 00-bootstrap | +| [groups](variables.tf#L126) | Group names to grant organization-level permissions. | map(string) | | {…} | 00-bootstrap | +| [organization_policy_configs](variables.tf#L151) | Organization policies customization. | object({…}) | | null | | +| [outputs_location](variables.tf#L159) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable | string | | null | | +| [tag_names](variables.tf#L176) | Customized names for resource management tags. | object({…}) | | {…} | | +| [team_folders](variables.tf#L193) | Team folders to be created. Format is described in a code comment. | map(object({…})) | | null | | ## Outputs | name | description | sensitive | consumers | |---|---|:---:|---| -| [cicd_repositories](outputs.tf#L143) | WIF configuration for CI/CD repositories. | | | -| [dataplatform](outputs.tf#L155) | Data for the Data Platform stage. | | | -| [networking](outputs.tf#L171) | Data for the networking stage. | | | -| [project_factories](outputs.tf#L180) | Data for the project factories stage. | | | -| [providers](outputs.tf#L196) | Terraform provider files for this stage and dependent stages. | ✓ | 02-networking · 02-security · 03-dataplatform · xx-sandbox · xx-teams | -| [sandbox](outputs.tf#L203) | Data for the sandbox stage. | | xx-sandbox | -| [security](outputs.tf#L213) | Data for the networking stage. | | 02-security | -| [teams](outputs.tf#L223) | Data for the teams stage. | | | -| [tfvars](outputs.tf#L236) | Terraform variable files for the following stages. | ✓ | | +| [cicd_repositories](outputs.tf#L145) | WIF configuration for CI/CD repositories. | | | +| [dataplatform](outputs.tf#L159) | Data for the Data Platform stage. | | | +| [networking](outputs.tf#L175) | Data for the networking stage. | | | +| [project_factories](outputs.tf#L184) | Data for the project factories stage. | | | +| [providers](outputs.tf#L200) | Terraform provider files for this stage and dependent stages. | ✓ | 02-networking · 02-security · 03-dataplatform · xx-sandbox · xx-teams | +| [sandbox](outputs.tf#L207) | Data for the sandbox stage. | | xx-sandbox | +| [security](outputs.tf#L217) | Data for the networking stage. | | 02-security | +| [teams](outputs.tf#L227) | Data for the teams stage. | | | +| [tfvars](outputs.tf#L240) | Terraform variable files for the following stages. | ✓ | | From 528219bbf34ad6a2f2caf280e7edb9dad4c8fd46 Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 16 Jun 2022 22:03:08 +0200 Subject: [PATCH 07/11] fix stage1 tests --- tests/fast/stages/s01_resman/fixture/main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/fast/stages/s01_resman/fixture/main.tf b/tests/fast/stages/s01_resman/fixture/main.tf index ddb9aafef4..57d35b1634 100644 --- a/tests/fast/stages/s01_resman/fixture/main.tf +++ b/tests/fast/stages/s01_resman/fixture/main.tf @@ -20,6 +20,7 @@ module "stage" { federated_identity_pool = null federated_identity_providers = null project_id = "fast-prod-automation" + project_number = 123456 outputs_bucket = "test" } billing_account = { From 6d8f3f7e22f071b9a8e6ef77db3deb4339df6b5b Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 16 Jun 2022 22:16:20 +0200 Subject: [PATCH 08/11] depend service account outputs on iam roles --- modules/iam-service-account/README.md | 12 ++++++------ modules/iam-service-account/outputs.tf | 13 +++++++++++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/modules/iam-service-account/README.md b/modules/iam-service-account/README.md index ab6b1882c8..fe07ddbff1 100644 --- a/modules/iam-service-account/README.md +++ b/modules/iam-service-account/README.md @@ -62,11 +62,11 @@ module "myproject-default-service-accounts" { | name | description | sensitive | |---|---|:---:| | [email](outputs.tf#L17) | Service account email. | | -| [iam_email](outputs.tf#L25) | IAM-format service account email. | | -| [id](outputs.tf#L33) | Service account id. | | -| [key](outputs.tf#L38) | Service account key. | ✓ | -| [name](outputs.tf#L44) | Service account name. | | -| [service_account](outputs.tf#L49) | Service account resource. | | -| [service_account_credentials](outputs.tf#L54) | Service account json credential templates for uploaded public keys data. | | +| [iam_email](outputs.tf#L27) | IAM-format service account email. | | +| [id](outputs.tf#L37) | Service account id. | | +| [key](outputs.tf#L47) | Service account key. | ✓ | +| [name](outputs.tf#L53) | Service account name. | | +| [service_account](outputs.tf#L58) | Service account resource. | | +| [service_account_credentials](outputs.tf#L63) | Service account json credential templates for uploaded public keys data. | | diff --git a/modules/iam-service-account/outputs.tf b/modules/iam-service-account/outputs.tf index 4f0e0aa522..2823910bd0 100644 --- a/modules/iam-service-account/outputs.tf +++ b/modules/iam-service-account/outputs.tf @@ -18,7 +18,9 @@ output "email" { description = "Service account email." value = local.resource_email_static depends_on = [ - local.service_account + local.service_account, + google_service_account_iam_binding.roles, + google_service_account_iam_member.additive ] } @@ -26,13 +28,20 @@ output "iam_email" { description = "IAM-format service account email." value = local.resource_iam_email_static depends_on = [ - local.service_account + local.service_account, + google_service_account_iam_binding.roles, + google_service_account_iam_member.additive ] } output "id" { description = "Service account id." value = local.service_account.id + depends_on = [ + local.service_account, + google_service_account_iam_binding.roles, + google_service_account_iam_member.additive + ] } output "key" { From a35ed1ca0f2665f1e88c1b967b0287445a4d1ef7 Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 16 Jun 2022 22:16:43 +0200 Subject: [PATCH 09/11] allow using cicd service accounts in build triggers --- fast/stages/01-resman/cicd-data-platform.tf | 8 ++++++-- fast/stages/01-resman/cicd-networking.tf | 4 +++- fast/stages/01-resman/cicd-security.tf | 4 +++- fast/stages/01-resman/cicd-teams.tf | 8 ++++++-- fast/stages/01-resman/main.tf | 6 ++++++ 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/fast/stages/01-resman/cicd-data-platform.tf b/fast/stages/01-resman/cicd-data-platform.tf index 66247d2696..c5c08d7f39 100644 --- a/fast/stages/01-resman/cicd-data-platform.tf +++ b/fast/stages/01-resman/cicd-data-platform.tf @@ -96,7 +96,9 @@ module "branch-dp-dev-sa-cicd" { iam = ( each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos - ? {} + ? { + "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + } # impersonated via workload identity federation for external repos : { "roles/iam.workloadIdentityUser" = [ @@ -135,7 +137,9 @@ module "branch-dp-prod-sa-cicd" { iam = ( each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos - ? {} + ? { + "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + } # impersonated via workload identity federation for external repos : { "roles/iam.workloadIdentityUser" = [ diff --git a/fast/stages/01-resman/cicd-networking.tf b/fast/stages/01-resman/cicd-networking.tf index 9bb96f7968..2853db8859 100644 --- a/fast/stages/01-resman/cicd-networking.tf +++ b/fast/stages/01-resman/cicd-networking.tf @@ -63,7 +63,9 @@ module "branch-network-sa-cicd" { iam = ( each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos - ? {} + ? { + "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + } # impersonated via workload identity federation for external repos : { "roles/iam.workloadIdentityUser" = [ diff --git a/fast/stages/01-resman/cicd-security.tf b/fast/stages/01-resman/cicd-security.tf index ff456166af..601b7cc564 100644 --- a/fast/stages/01-resman/cicd-security.tf +++ b/fast/stages/01-resman/cicd-security.tf @@ -63,7 +63,9 @@ module "branch-security-sa-cicd" { iam = ( each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos - ? {} + ? { + "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + } # impersonated via workload identity federation for external repos : { "roles/iam.workloadIdentityUser" = [ diff --git a/fast/stages/01-resman/cicd-teams.tf b/fast/stages/01-resman/cicd-teams.tf index 931b0a7cae..67b333f67d 100644 --- a/fast/stages/01-resman/cicd-teams.tf +++ b/fast/stages/01-resman/cicd-teams.tf @@ -96,7 +96,9 @@ module "branch-teams-dev-pf-sa-cicd" { iam = ( each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos - ? {} + ? { + "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + } # impersonated via workload identity federation for external repos : { "roles/iam.workloadIdentityUser" = [ @@ -135,7 +137,9 @@ module "branch-teams-prod-pf-sa-cicd" { iam = ( each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos - ? {} + ? { + "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + } # impersonated via workload identity federation for external repos : { "roles/iam.workloadIdentityUser" = [ diff --git a/fast/stages/01-resman/main.tf b/fast/stages/01-resman/main.tf index 6cefbd25d9..5520c03aa9 100644 --- a/fast/stages/01-resman/main.tf +++ b/fast/stages/01-resman/main.tf @@ -16,6 +16,10 @@ locals { # convenience flags that express where billing account resides + automation_resman_sa = format( + "serviceAccount:%s", + data.google_client_openid_userinfo.provider_identity.email + ) billing_ext = var.billing_account.organization_id == null billing_org = var.billing_account.organization_id == var.organization.id billing_org_ext = !local.billing_ext && !local.billing_org @@ -64,3 +68,5 @@ locals { try(var.automation.federated_identity_providers, null), {} ) } + +data "google_client_openid_userinfo" "provider_identity" {} From ee23694fed4cc3373578ee9fb1bf874da209adb7 Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 16 Jun 2022 23:09:35 +0200 Subject: [PATCH 10/11] revert service account modules changes to outputs --- modules/iam-service-account/README.md | 14 ++++++++------ modules/iam-service-account/outputs.tf | 12 +++--------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/modules/iam-service-account/README.md b/modules/iam-service-account/README.md index fe07ddbff1..ad39c389e9 100644 --- a/modules/iam-service-account/README.md +++ b/modules/iam-service-account/README.md @@ -2,6 +2,8 @@ This module allows simplified creation and management of one a service account and its IAM bindings. A key can optionally be generated and will be stored in Terraform state. To use it create a sensitive output in your root modules referencing the `key` output, then extract the private key from the JSON formatted outputs. Alternatively, the `key` can be generated with `openssl` library and only public part uploaded to the Service Account, for more refer to the [Onprem SA Key Management](../../examples/cloud-operations/onprem-sa-key-management/) example. +Note that this module does not fully comply with our design principles, as outputs have no dependencies on IAM bindings to prevent resource cycles. + ## Example ```hcl @@ -62,11 +64,11 @@ module "myproject-default-service-accounts" { | name | description | sensitive | |---|---|:---:| | [email](outputs.tf#L17) | Service account email. | | -| [iam_email](outputs.tf#L27) | IAM-format service account email. | | -| [id](outputs.tf#L37) | Service account id. | | -| [key](outputs.tf#L47) | Service account key. | ✓ | -| [name](outputs.tf#L53) | Service account name. | | -| [service_account](outputs.tf#L58) | Service account resource. | | -| [service_account_credentials](outputs.tf#L63) | Service account json credential templates for uploaded public keys data. | | +| [iam_email](outputs.tf#L25) | IAM-format service account email. | | +| [id](outputs.tf#L33) | Service account id. | | +| [key](outputs.tf#L41) | Service account key. | ✓ | +| [name](outputs.tf#L47) | Service account name. | | +| [service_account](outputs.tf#L52) | Service account resource. | | +| [service_account_credentials](outputs.tf#L57) | Service account json credential templates for uploaded public keys data. | | diff --git a/modules/iam-service-account/outputs.tf b/modules/iam-service-account/outputs.tf index 2823910bd0..42196534c3 100644 --- a/modules/iam-service-account/outputs.tf +++ b/modules/iam-service-account/outputs.tf @@ -18,9 +18,7 @@ output "email" { description = "Service account email." value = local.resource_email_static depends_on = [ - local.service_account, - google_service_account_iam_binding.roles, - google_service_account_iam_member.additive + local.service_account ] } @@ -28,9 +26,7 @@ output "iam_email" { description = "IAM-format service account email." value = local.resource_iam_email_static depends_on = [ - local.service_account, - google_service_account_iam_binding.roles, - google_service_account_iam_member.additive + local.service_account ] } @@ -38,9 +34,7 @@ output "id" { description = "Service account id." value = local.service_account.id depends_on = [ - local.service_account, - google_service_account_iam_binding.roles, - google_service_account_iam_member.additive + local.service_account ] } From a09eb39a962f075ab8330fabd10aa7da3afa584b Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 16 Jun 2022 23:11:08 +0200 Subject: [PATCH 11/11] disable provider data source when not needed, explicitly depend on CI/CD SAs --- fast/stages/01-resman/cicd-data-platform.tf | 6 ++++-- fast/stages/01-resman/cicd-networking.tf | 3 ++- fast/stages/01-resman/cicd-security.tf | 3 ++- fast/stages/01-resman/cicd-teams.tf | 6 ++++-- fast/stages/01-resman/main.tf | 13 +++++++++---- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/fast/stages/01-resman/cicd-data-platform.tf b/fast/stages/01-resman/cicd-data-platform.tf index c5c08d7f39..4a5c6d3f59 100644 --- a/fast/stages/01-resman/cicd-data-platform.tf +++ b/fast/stages/01-resman/cicd-data-platform.tf @@ -47,6 +47,7 @@ module "branch-dp-dev-cicd-repo" { } } } + depends_on = [module.branch-dp-dev-sa-cicd] } module "branch-dp-prod-cicd-repo" { @@ -78,6 +79,7 @@ module "branch-dp-prod-cicd-repo" { } } } + depends_on = [module.branch-dp-prod-sa-cicd] } # SAs used by CI/CD workflows to impersonate automation SAs @@ -97,7 +99,7 @@ module "branch-dp-dev-sa-cicd" { each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos ? { - "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + "roles/iam.serviceAccountUser" = local.automation_resman_sa } # impersonated via workload identity federation for external repos : { @@ -138,7 +140,7 @@ module "branch-dp-prod-sa-cicd" { each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos ? { - "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + "roles/iam.serviceAccountUser" = local.automation_resman_sa } # impersonated via workload identity federation for external repos : { diff --git a/fast/stages/01-resman/cicd-networking.tf b/fast/stages/01-resman/cicd-networking.tf index 2853db8859..9517704755 100644 --- a/fast/stages/01-resman/cicd-networking.tf +++ b/fast/stages/01-resman/cicd-networking.tf @@ -45,6 +45,7 @@ module "branch-network-cicd-repo" { } } } + depends_on = [module.branch-network-sa-cicd] } # SA used by CI/CD workflows to impersonate automation SAs @@ -64,7 +65,7 @@ module "branch-network-sa-cicd" { each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos ? { - "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + "roles/iam.serviceAccountUser" = local.automation_resman_sa } # impersonated via workload identity federation for external repos : { diff --git a/fast/stages/01-resman/cicd-security.tf b/fast/stages/01-resman/cicd-security.tf index 601b7cc564..86fd84fdb1 100644 --- a/fast/stages/01-resman/cicd-security.tf +++ b/fast/stages/01-resman/cicd-security.tf @@ -45,6 +45,7 @@ module "branch-security-cicd-repo" { } } } + depends_on = [module.branch-security-sa-cicd] } # SA used by CI/CD workflows to impersonate automation SAs @@ -64,7 +65,7 @@ module "branch-security-sa-cicd" { each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos ? { - "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + "roles/iam.serviceAccountUser" = local.automation_resman_sa } # impersonated via workload identity federation for external repos : { diff --git a/fast/stages/01-resman/cicd-teams.tf b/fast/stages/01-resman/cicd-teams.tf index 67b333f67d..f5e81fd3f2 100644 --- a/fast/stages/01-resman/cicd-teams.tf +++ b/fast/stages/01-resman/cicd-teams.tf @@ -47,6 +47,7 @@ module "branch-teams-dev-pf-cicd-repo" { } } } + depends_on = [module.branch-teams-dev-pf-sa-cicd] } module "branch-teams-prod-pf-cicd-repo" { @@ -78,6 +79,7 @@ module "branch-teams-prod-pf-cicd-repo" { } } } + depends_on = [module.branch-teams-prod-pf-sa-cicd] } # SAs used by CI/CD workflows to impersonate automation SAs @@ -97,7 +99,7 @@ module "branch-teams-dev-pf-sa-cicd" { each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos ? { - "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + "roles/iam.serviceAccountUser" = local.automation_resman_sa } # impersonated via workload identity federation for external repos : { @@ -138,7 +140,7 @@ module "branch-teams-prod-pf-sa-cicd" { each.value.type == "sourcerepo" # used directly from the cloud build trigger for source repos ? { - "roles/iam.serviceAccountUser" = [local.automation_resman_sa] + "roles/iam.serviceAccountUser" = local.automation_resman_sa } # impersonated via workload identity federation for external repos : { diff --git a/fast/stages/01-resman/main.tf b/fast/stages/01-resman/main.tf index 5520c03aa9..c40957964f 100644 --- a/fast/stages/01-resman/main.tf +++ b/fast/stages/01-resman/main.tf @@ -16,9 +16,12 @@ locals { # convenience flags that express where billing account resides - automation_resman_sa = format( - "serviceAccount:%s", - data.google_client_openid_userinfo.provider_identity.email + automation_resman_sa = try( + [format( + "serviceAccount:%s", + data.google_client_openid_userinfo.provider_identity.0.email + )], + [] ) billing_ext = var.billing_account.organization_id == null billing_org = var.billing_account.organization_id == var.organization.id @@ -69,4 +72,6 @@ locals { ) } -data "google_client_openid_userinfo" "provider_identity" {} +data "google_client_openid_userinfo" "provider_identity" { + count = length(local.cicd_repositories) > 0 ? 1 : 0 +}