From 0885e4a2916df1c351f288509721490cfd85ab8e Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Mon, 10 Jun 2024 11:02:55 +0200 Subject: [PATCH] Remove support for source repositories from FAST CI/CD (#2352) * stage 0 * stage 1 * stage 1 mt * remove unused locals from resman * remove unused locals from resman * tfdoc --- fast/stages/0-bootstrap/README.md | 38 ++-- fast/stages/0-bootstrap/automation.tf | 1 - fast/stages/0-bootstrap/cicd.tf | 110 +++------- fast/stages/0-bootstrap/variables.tf | 12 +- fast/stages/1-resman/README.md | 26 +-- fast/stages/1-resman/cicd-data-platform.tf | 198 +++++------------- fast/stages/1-resman/cicd-gcve.tf | 198 +++++------------- fast/stages/1-resman/cicd-gke.tf | 198 +++++------------- fast/stages/1-resman/cicd-networking.tf | 96 +++------ fast/stages/1-resman/cicd-project-factory.tf | 194 +++++------------ fast/stages/1-resman/cicd-security.tf | 96 +++------ fast/stages/1-resman/main.tf | 31 ++- fast/stages/1-resman/variables.tf | 12 +- fast/stages/1-tenant-factory/README.md | 2 +- .../tenant-fast-automation.tf | 1 - .../1-tenant-factory/tenant-fast-cicd.tf | 98 +++------ tests/fast/stages/s0_bootstrap/checklist.yaml | 4 +- tests/fast/stages/s0_bootstrap/simple.yaml | 4 +- .../fast/stages/s1_tenant_factory/simple.yaml | 4 +- 19 files changed, 362 insertions(+), 961 deletions(-) diff --git a/fast/stages/0-bootstrap/README.md b/fast/stages/0-bootstrap/README.md index 5d9cecd0db..d5abcbb110 100644 --- a/fast/stages/0-bootstrap/README.md +++ b/fast/stages/0-bootstrap/README.md @@ -80,7 +80,7 @@ The only current exception to the factory approach is the `iam.allowedPolicyMemb Organization policy exceptions are managed via a dedicated resource management tag hierarchy, rooted in the `org-policies` tag key. A default condition is already present for the the `iam.allowedPolicyMemberDomains` constraint, that relaxes the policy on resources that have the `org-policies/allowed-policy-member-domains-all` tag value bound or inherited. -Further tag values can be defined via the `org_policies_config.tag_values` variable, and IAM access can be granted on them via the same variable. Once a tag value has been created, its id can be used in constraint rule conditions. Note that only one tag value from a given tag key can be bound to a node (organization, folder, or project) in the resource hierarchy. Since these tag values are all rooted in the `org-policies` key, this limits the ability to apply fine-grained policy constraints. It may be more desirable to model policy overrides using coarser groups of tag values to create a policy "profile". For example, instead of separating `compute.skipDefaultNetworkCreation` and `compute.vmExternalIpAccess`, enforce both constraints by default and relax them both using the same tag value such as `sandbox`. See [tags overview](https://cloud.google.com/resource-manager/docs/tags/tags-overview) for more information. +Further tag values can be defined via the `org_policies_config.tag_values` variable, and IAM access can be granted on them via the same variable. Once a tag value has been created, its id can be used in constraint rule conditions. Note that only one tag value from a given tag key can be bound to a node (organization, folder, or project) in the resource hierarchy. Since these tag values are all rooted in the `org-policies` key, this limits the ability to apply fine-grained policy constraints. It may be more desirable to model policy overrides using coarser groups of tag values to create a policy "profile". For example, instead of separating `compute.skipDefaultNetworkCreation` and `compute.vmExternalIpAccess`, enforce both constraints by default and relax them both using the same tag value such as `sandbox`. See [tags overview](https://cloud.google.com/resource-manager/docs/tags/tags-overview) for more information. Management of the rest of the tag hierarchy is delegated to the resource management stage, as that is often intimately tied to the folder hierarchy design. @@ -575,7 +575,7 @@ cicd_repositories = { } ``` -The `type` attribute can be set to one of the supported repository types: `github`, `gitlab`, or `sourcerepo`. +The `type` attribute can be set to one of the supported repository types: `github` or `gitlab`. Once the stage is applied the generated output files will contain pre-configured workflow files for each repository, that will use Workload Identity Federation via a dedicated service account for each repository to impersonate the automation service account for the stage. @@ -617,7 +617,7 @@ The remaining configuration is manual, as it regards the repositories themselves | [automation.tf](./automation.tf) | Automation project and resources. | gcs · iam-service-account · project | | | [billing.tf](./billing.tf) | Billing export project and dataset. | bigquery-dataset · project | google_billing_account_iam_member | | [checklist.tf](./checklist.tf) | None | gcs | google_storage_bucket_object | -| [cicd.tf](./cicd.tf) | Workload Identity Federation configurations for CI/CD. | iam-service-account · source-repository | | +| [cicd.tf](./cicd.tf) | Workload Identity Federation configurations for CI/CD. | iam-service-account | | | [identity-providers-defs.tf](./identity-providers-defs.tf) | Identity provider definitions. | | | | [identity-providers.tf](./identity-providers.tf) | Workload Identity Federation provider definitions. | | google_iam_workforce_pool · google_iam_workforce_pool_provider · google_iam_workload_identity_pool · google_iam_workload_identity_pool_provider | | [log-export.tf](./log-export.tf) | Audit log project and sink. | bigquery-dataset · gcs · logging-bucket · project · pubsub | | @@ -634,24 +634,24 @@ The remaining configuration is manual, as it regards the repositories themselves | name | description | type | required | default | producer | |---|---|:---:|:---:|:---:|:---:| | [billing_account](variables.tf#L17) | Billing account id. If billing account is not part of the same org set `is_org_level` to `false`. To disable handling of billing IAM roles set `no_iam` to `true`. | object({…}) | ✓ | | | -| [organization](variables.tf#L234) | Organization details. | object({…}) | ✓ | | | -| [prefix](variables.tf#L249) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | | +| [organization](variables.tf#L230) | Organization details. | object({…}) | ✓ | | | +| [prefix](variables.tf#L245) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | | | [bootstrap_user](variables.tf#L27) | Email of the nominal user running this stage for the first time. | string | | null | | | [cicd_repositories](variables.tf#L33) | CI/CD repository configuration. Identity providers reference keys in the `federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | object({…}) | | null | | -| [custom_roles](variables.tf#L85) | Map of role names => list of permissions to additionally create at the organization level. | map(list(string)) | | {} | | -| [essential_contacts](variables.tf#L92) | Email used for essential contacts, unset if null. | string | | null | | -| [factories_config](variables.tf#L98) | Configuration for the resource factories or external data. | object({…}) | | {} | | -| [groups](variables.tf#L110) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | object({…}) | | {} | | -| [iam](variables.tf#L126) | Organization-level custom IAM settings in role => [principal] format. | map(list(string)) | | {} | | -| [iam_bindings_additive](variables.tf#L133) | Organization-level custom additive IAM bindings. Keys are arbitrary. | map(object({…})) | | {} | | -| [iam_by_principals](variables.tf#L148) | Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable. | map(list(string)) | | {} | | -| [locations](variables.tf#L155) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {} | | -| [log_sinks](variables.tf#L169) | Org-level log sinks, in name => {type, filter} format. | map(object({…})) | | {…} | | -| [org_policies_config](variables.tf#L217) | Organization policies customization. | object({…}) | | {} | | -| [outputs_location](variables.tf#L243) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | | -| [project_parent_ids](variables.tf#L258) | Optional parents for projects created here in folders/nnnnnnn format. Null values will use the organization as parent. | object({…}) | | {} | | -| [workforce_identity_providers](variables.tf#L269) | Workforce Identity Federation pools. | map(object({…})) | | {} | | -| [workload_identity_providers](variables.tf#L285) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | map(object({…})) | | {} | | +| [custom_roles](variables.tf#L81) | Map of role names => list of permissions to additionally create at the organization level. | map(list(string)) | | {} | | +| [essential_contacts](variables.tf#L88) | Email used for essential contacts, unset if null. | string | | null | | +| [factories_config](variables.tf#L94) | Configuration for the resource factories or external data. | object({…}) | | {} | | +| [groups](variables.tf#L106) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | object({…}) | | {} | | +| [iam](variables.tf#L122) | Organization-level custom IAM settings in role => [principal] format. | map(list(string)) | | {} | | +| [iam_bindings_additive](variables.tf#L129) | Organization-level custom additive IAM bindings. Keys are arbitrary. | map(object({…})) | | {} | | +| [iam_by_principals](variables.tf#L144) | Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable. | map(list(string)) | | {} | | +| [locations](variables.tf#L151) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {} | | +| [log_sinks](variables.tf#L165) | Org-level log sinks, in name => {type, filter} format. | map(object({…})) | | {…} | | +| [org_policies_config](variables.tf#L213) | Organization policies customization. | object({…}) | | {} | | +| [outputs_location](variables.tf#L239) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | | +| [project_parent_ids](variables.tf#L254) | Optional parents for projects created here in folders/nnnnnnn format. Null values will use the organization as parent. | object({…}) | | {} | | +| [workforce_identity_providers](variables.tf#L265) | Workforce Identity Federation pools. | map(object({…})) | | {} | | +| [workload_identity_providers](variables.tf#L281) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | map(object({…})) | | {} | | ## Outputs diff --git a/fast/stages/0-bootstrap/automation.tf b/fast/stages/0-bootstrap/automation.tf index a4648a9e35..bd7ce232c5 100644 --- a/fast/stages/0-bootstrap/automation.tf +++ b/fast/stages/0-bootstrap/automation.tf @@ -145,7 +145,6 @@ module "automation-project" { "pubsub.googleapis.com", "servicenetworking.googleapis.com", "serviceusage.googleapis.com", - "sourcerepo.googleapis.com", "stackdriver.googleapis.com", "storage-component.googleapis.com", "storage.googleapis.com", diff --git a/fast/stages/0-bootstrap/cicd.tf b/fast/stages/0-bootstrap/cicd.tf index c276171ab5..72c9d39d86 100644 --- a/fast/stages/0-bootstrap/cicd.tf +++ b/fast/stages/0-bootstrap/cicd.tf @@ -36,13 +36,9 @@ locals { if( v != null && - ( - try(v.type, null) == "sourcerepo" - || - contains( - keys(local.workload_identity_providers), - coalesce(try(v.identity_provider, null), ":") - ) + contains( + keys(local.workload_identity_providers), + coalesce(try(v.identity_provider, null), ":") ) && fileexists( @@ -71,44 +67,6 @@ locals { } } -# source repository - -module "automation-tf-cicd-repo" { - source = "../../../modules/source-repository" - for_each = { - for k, v in local.cicd_repositories : k => v if v.type == "sourcerepo" - } - project_id = module.automation-project.project_id - name = each.value.name - iam = { - "roles/source.admin" = [ - each.key == "bootstrap" - ? module.automation-tf-bootstrap-sa.iam_email - : module.automation-tf-resman-sa.iam_email - ] - "roles/source.reader" = concat( - [module.automation-tf-cicd-sa[each.key].iam_email], - each.key == "bootstrap" - ? [module.automation-tf-bootstrap-r-sa.iam_email] - : [module.automation-tf-resman-r-sa.iam_email] - ) - } - triggers = { - "fast-0-${each.key}" = { - filename = ".cloudbuild/workflow.yaml" - included_files = ["**/*tf", ".cloudbuild/workflow.yaml"] - service_account = module.automation-tf-cicd-sa[each.key].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } -} - # SAs used by CI/CD workflows to impersonate automation SAs module "automation-tf-cicd-sa" { @@ -118,28 +76,22 @@ module "automation-tf-cicd-sa" { name = "${each.key}-1" display_name = "Terraform CI/CD ${each.key} service account." prefix = local.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.workload_identity_providers_defs[each.value.type].principal_repo, - google_iam_workload_identity_pool.default[0].name, - each.value.name - ) - : format( - local.workload_identity_providers_defs[each.value.type].principal_branch, - google_iam_workload_identity_pool.default[0].name, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.workload_identity_providers_defs[each.value.type].principal_repo, + google_iam_workload_identity_pool.default[0].name, + each.value.name + ) + : format( + local.workload_identity_providers_defs[each.value.type].principal_branch, + google_iam_workload_identity_pool.default[0].name, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (module.automation-project.project_id) = ["roles/logging.logWriter"] } @@ -155,21 +107,15 @@ module "automation-tf-cicd-r-sa" { name = "${each.key}-1r" display_name = "Terraform CI/CD ${each.key} service account (read-only)." prefix = local.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.workload_identity_providers_defs[each.value.type].principal_repo, - google_iam_workload_identity_pool.default[0].name, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.workload_identity_providers_defs[each.value.type].principal_repo, + google_iam_workload_identity_pool.default[0].name, + each.value.name + ) + ] + } iam_project_roles = { (module.automation-project.project_id) = ["roles/logging.logWriter"] } diff --git a/fast/stages/0-bootstrap/variables.tf b/fast/stages/0-bootstrap/variables.tf index b4b698a315..db9cb9da6f 100644 --- a/fast/stages/0-bootstrap/variables.tf +++ b/fast/stages/0-bootstrap/variables.tf @@ -63,22 +63,18 @@ variable "cicd_repositories" { validation { condition = alltrue([ for k, v in coalesce(var.cicd_repositories, {}) : - v == null || ( - try(v.identity_provider, null) != null - || - try(v.type, null) == "sourcerepo" - ) + v == null || try(v.identity_provider, null) != null ]) - error_message = "Non-null repositories need a non-null provider unless type is 'sourcerepo'." + error_message = "Non-null repositories need a non-null provider." } validation { condition = alltrue([ for k, v in coalesce(var.cicd_repositories, {}) : v == null || ( - contains(["github", "gitlab", "sourcerepo"], coalesce(try(v.type, null), "null")) + contains(["github", "gitlab"], coalesce(try(v.type, null), "null")) ) ]) - error_message = "Invalid repository type, supported types: 'github' 'gitlab' or 'sourcerepo'." + error_message = "Invalid repository type, supported types: 'github' or 'gitlab'." } } diff --git a/fast/stages/1-resman/README.md b/fast/stages/1-resman/README.md index 9bf572d606..f0d291cc70 100644 --- a/fast/stages/1-resman/README.md +++ b/fast/stages/1-resman/README.md @@ -241,12 +241,12 @@ A full reference of IAM roles managed by this stage [is available here](./IAM.md | [branch-sandbox.tf](./branch-sandbox.tf) | Sandbox stage resources. | folder · gcs · iam-service-account | | | [branch-security.tf](./branch-security.tf) | Security stage resources. | folder · gcs · iam-service-account | | | [checklist.tf](./checklist.tf) | None | folder | | -| [cicd-data-platform.tf](./cicd-data-platform.tf) | CI/CD resources for the data platform branch. | iam-service-account · source-repository | | -| [cicd-gcve.tf](./cicd-gcve.tf) | CI/CD resources for the GCVE branch. | iam-service-account · source-repository | | -| [cicd-gke.tf](./cicd-gke.tf) | CI/CD resources for the GKE multitenant branch. | iam-service-account · source-repository | | -| [cicd-networking.tf](./cicd-networking.tf) | CI/CD resources for the networking branch. | iam-service-account · source-repository | | -| [cicd-project-factory.tf](./cicd-project-factory.tf) | CI/CD resources for the project factories. | iam-service-account · source-repository | | -| [cicd-security.tf](./cicd-security.tf) | CI/CD resources for the security branch. | iam-service-account · source-repository | | +| [cicd-data-platform.tf](./cicd-data-platform.tf) | CI/CD resources for the data platform branch. | iam-service-account | | +| [cicd-gcve.tf](./cicd-gcve.tf) | CI/CD resources for the GCVE branch. | iam-service-account | | +| [cicd-gke.tf](./cicd-gke.tf) | CI/CD resources for the GKE multitenant branch. | iam-service-account | | +| [cicd-networking.tf](./cicd-networking.tf) | CI/CD resources for the networking branch. | iam-service-account | | +| [cicd-project-factory.tf](./cicd-project-factory.tf) | CI/CD resources for the project factories. | iam-service-account | | +| [cicd-security.tf](./cicd-security.tf) | CI/CD resources for the security branch. | iam-service-account | | | [iam.tf](./iam.tf) | Organization or root node-level IAM bindings. | | | | [main.tf](./main.tf) | Module-level locals and resources. | | | | [organization.tf](./organization.tf) | Organization policies. | organization | | @@ -270,16 +270,16 @@ A full reference of IAM roles managed by this stage [is available here](./IAM.md | [prefix](variables-fast.tf#L124) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap | | [cicd_repositories](variables.tf#L20) | 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-fast.tf#L53) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap | -| [factories_config](variables.tf#L114) | Configuration for the resource factories or external data. | object({…}) | | {} | | -| [fast_features](variables.tf#L125) | Selective control for top-level FAST features. | object({…}) | | {} | | -| [folder_iam](variables.tf#L138) | Authoritative IAM for top-level folders. | object({…}) | | {} | | +| [factories_config](variables.tf#L110) | Configuration for the resource factories or external data. | object({…}) | | {} | | +| [fast_features](variables.tf#L121) | Selective control for top-level FAST features. | object({…}) | | {} | | +| [folder_iam](variables.tf#L134) | Authoritative IAM for top-level folders. | object({…}) | | {} | | | [groups](variables-fast.tf#L65) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | object({…}) | | {} | 0-bootstrap | | [locations](variables-fast.tf#L80) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {} | 0-bootstrap | -| [outputs_location](variables.tf#L152) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | | +| [outputs_location](variables.tf#L148) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | | | [root_node](variables-fast.tf#L130) | Root node for the hierarchy, if running in tenant mode. | string | | null | 0-bootstrap | -| [tag_names](variables.tf#L158) | Customized names for resource management tags. | object({…}) | | {} | | -| [tags](variables.tf#L172) | Custom secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | | -| [top_level_folders](variables.tf#L193) | Additional top-level folders. Keys are used for service account and bucket names, values implement the folders module interface with the addition of the 'automation' attribute. | map(object({…})) | | {} | | +| [tag_names](variables.tf#L154) | Customized names for resource management tags. | object({…}) | | {} | | +| [tags](variables.tf#L168) | Custom secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | | +| [top_level_folders](variables.tf#L189) | Additional top-level folders. Keys are used for service account and bucket names, values implement the folders module interface with the addition of the 'automation' attribute. | map(object({…})) | | {} | | ## Outputs diff --git a/fast/stages/1-resman/cicd-data-platform.tf b/fast/stages/1-resman/cicd-data-platform.tf index a544f5c367..d99a3d1986 100644 --- a/fast/stages/1-resman/cicd-data-platform.tf +++ b/fast/stages/1-resman/cicd-data-platform.tf @@ -16,76 +16,6 @@ # tfdoc:file:description CI/CD resources for the data platform branch. -# source repositories - -module "branch-dp-dev-cicd-repo" { - source = "../../../modules/source-repository" - for_each = ( - try(local.cicd_repositories.data_platform_dev.type, null) == "sourcerepo" - ? { 0 = local.cicd_repositories.data_platform_dev } - : {} - ) - project_id = var.automation.project_id - name = each.value.name - iam = { - "roles/source.admin" = compact([ - try(module.branch-dp-dev-sa[0].iam_email, "") - ]) - "roles/source.reader" = compact([ - try(module.branch-dp-dev-sa-cicd[0].iam_email, "") - ]) - } - triggers = { - fast-03-dp-dev = { - filename = ".cloudbuild/workflow.yaml" - included_files = [ - "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" - ] - service_account = module.branch-dp-dev-sa-cicd[0].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.branch-dp-dev-sa-cicd] -} - -module "branch-dp-prod-cicd-repo" { - source = "../../../modules/source-repository" - for_each = ( - try(local.cicd_repositories.data_platform_prod.type, null) == "sourcerepo" - ? { 0 = local.cicd_repositories.data_platform_prod } - : {} - ) - project_id = var.automation.project_id - name = each.value.name - iam = { - "roles/source.admin" = [module.branch-dp-prod-sa[0].iam_email] - "roles/source.reader" = [module.branch-dp-prod-sa-cicd[0].iam_email] - } - triggers = { - fast-03-dp-prod = { - filename = ".cloudbuild/workflow.yaml" - included_files = [ - "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" - ] - service_account = module.branch-dp-prod-sa-cicd[0].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.branch-dp-prod-sa-cicd] -} - # read-write (apply) SAs used by CI/CD workflows to impersonate automation SAs module "branch-dp-dev-sa-cicd" { @@ -99,30 +29,22 @@ module "branch-dp-dev-sa-cicd" { name = "dev-resman-dp-1" display_name = "Terraform CI/CD data platform development service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? { - "roles/iam.serviceAccountUser" = local.automation_resman_sa_iam - } - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -142,30 +64,22 @@ module "branch-dp-prod-sa-cicd" { name = "prod-resman-dp-1" display_name = "Terraform CI/CD data platform production service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? { - "roles/iam.serviceAccountUser" = local.automation_resman_sa_iam - } - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -187,21 +101,15 @@ module "branch-dp-dev-r-sa-cicd" { name = "dev-resman-dp-1r" display_name = "Terraform CI/CD data platform development service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -221,21 +129,15 @@ module "branch-dp-prod-r-sa-cicd" { name = "prod-resman-dp-1r" display_name = "Terraform CI/CD data platform production service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } diff --git a/fast/stages/1-resman/cicd-gcve.tf b/fast/stages/1-resman/cicd-gcve.tf index 119ae8bba8..c4acf1d50c 100644 --- a/fast/stages/1-resman/cicd-gcve.tf +++ b/fast/stages/1-resman/cicd-gcve.tf @@ -16,76 +16,6 @@ # tfdoc:file:description CI/CD resources for the GCVE branch. -# source repositories - -module "branch-gcve-dev-cicd-repo" { - source = "../../../modules/source-repository" - for_each = ( - try(local.cicd_repositories.gcve_dev.type, null) == "sourcerepo" - ? { 0 = local.cicd_repositories.gcve_dev } - : {} - ) - project_id = var.automation.project_id - name = each.value.name - iam = { - "roles/source.admin" = compact([ - try(module.branch-gcve-dev-sa[0].iam_email, "") - ]) - "roles/source.reader" = compact([ - try(module.branch-gcve-dev-sa-cicd[0].iam_email, "") - ]) - } - triggers = { - fast-03-gcve-dev = { - filename = ".cloudbuild/workflow.yaml" - included_files = [ - "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" - ] - service_account = module.branch-gcve-dev-sa-cicd[0].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.branch-gcve-dev-sa-cicd] -} - -module "branch-gcve-prod-cicd-repo" { - source = "../../../modules/source-repository" - for_each = ( - try(local.cicd_repositories.gcve_prod.type, null) == "sourcerepo" - ? { 0 = local.cicd_repositories.gcve_prod } - : {} - ) - project_id = var.automation.project_id - name = each.value.name - iam = { - "roles/source.admin" = [module.branch-gcve-prod-sa[0].iam_email] - "roles/source.reader" = [module.branch-gcve-prod-sa-cicd[0].iam_email] - } - triggers = { - fast-03-gcve-prod = { - filename = ".cloudbuild/workflow.yaml" - included_files = [ - "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" - ] - service_account = module.branch-gcve-prod-sa-cicd[0].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.branch-gcve-prod-sa-cicd] -} - # read-write (apply) SAs used by CI/CD workflows to impersonate automation SAs module "branch-gcve-dev-sa-cicd" { @@ -99,30 +29,22 @@ module "branch-gcve-dev-sa-cicd" { name = "dev-resman-gcve-1" display_name = "Terraform CI/CD GCVE development service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? { - "roles/iam.serviceAccountUser" = local.automation_resman_sa_iam - } - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -142,30 +64,22 @@ module "branch-gcve-prod-sa-cicd" { name = "prod-resman-gcve-1" display_name = "Terraform CI/CD GCVE production service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? { - "roles/iam.serviceAccountUser" = local.automation_resman_sa_iam - } - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -187,21 +101,15 @@ module "branch-gcve-dev-r-sa-cicd" { name = "dev-resman-gcve-1r" display_name = "Terraform CI/CD GCVE development service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -221,21 +129,15 @@ module "branch-gcve-prod-r-sa-cicd" { name = "prod-resman-gcve-1r" display_name = "Terraform CI/CD GCVE production service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } diff --git a/fast/stages/1-resman/cicd-gke.tf b/fast/stages/1-resman/cicd-gke.tf index 4125104bb2..ec31fe8782 100644 --- a/fast/stages/1-resman/cicd-gke.tf +++ b/fast/stages/1-resman/cicd-gke.tf @@ -16,76 +16,6 @@ # tfdoc:file:description CI/CD resources for the GKE multitenant branch. -# source repositories - -module "branch-gke-dev-cicd-repo" { - source = "../../../modules/source-repository" - for_each = ( - try(local.cicd_repositories.gke_dev.type, null) == "sourcerepo" - ? { 0 = local.cicd_repositories.gke_dev } - : {} - ) - project_id = var.automation.project_id - name = each.value.name - iam = { - "roles/source.admin" = compact([ - try(module.branch-gke-dev-sa[0].iam_email, "") - ]) - "roles/source.reader" = compact([ - try(module.branch-gke-dev-sa-cicd[0].iam_email, "") - ]) - } - triggers = { - fast-03-gke-dev = { - filename = ".cloudbuild/workflow.yaml" - included_files = [ - "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" - ] - service_account = module.branch-gke-dev-sa-cicd[0].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.branch-gke-dev-sa-cicd] -} - -module "branch-gke-prod-cicd-repo" { - source = "../../../modules/source-repository" - for_each = ( - try(local.cicd_repositories.gke_prod.type, null) == "sourcerepo" - ? { 0 = local.cicd_repositories.gke_prod } - : {} - ) - project_id = var.automation.project_id - name = each.value.name - iam = { - "roles/source.admin" = [module.branch-gke-prod-sa[0].iam_email] - "roles/source.reader" = [module.branch-gke-prod-sa-cicd[0].iam_email] - } - triggers = { - fast-03-gke-prod = { - filename = ".cloudbuild/workflow.yaml" - included_files = [ - "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" - ] - service_account = module.branch-gke-prod-sa-cicd[0].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.branch-gke-prod-sa-cicd] -} - # read-write (apply) SAs used by CI/CD workflows to impersonate automation SAs module "branch-gke-dev-sa-cicd" { @@ -99,30 +29,22 @@ module "branch-gke-dev-sa-cicd" { name = "dev-resman-gke-1" display_name = "Terraform CI/CD GKE development service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? { - "roles/iam.serviceAccountUser" = local.automation_resman_sa_iam - } - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -142,30 +64,22 @@ module "branch-gke-prod-sa-cicd" { name = "prod-resman-gke-1" display_name = "Terraform CI/CD GKE production service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? { - "roles/iam.serviceAccountUser" = local.automation_resman_sa_iam - } - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -187,21 +101,15 @@ module "branch-gke-dev-r-sa-cicd" { name = "dev-resman-gke-1r" display_name = "Terraform CI/CD gke multitenant development service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -221,21 +129,15 @@ module "branch-gke-prod-r-sa-cicd" { name = "prod-resman-gke-1r" display_name = "Terraform CI/CD gke multitenant production service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } diff --git a/fast/stages/1-resman/cicd-networking.tf b/fast/stages/1-resman/cicd-networking.tf index 2215e9baa5..7a4b5c17f6 100644 --- a/fast/stages/1-resman/cicd-networking.tf +++ b/fast/stages/1-resman/cicd-networking.tf @@ -16,38 +16,6 @@ # tfdoc:file:description CI/CD resources for the networking branch. -# source repository - -module "branch-network-cicd-repo" { - source = "../../../modules/source-repository" - for_each = ( - try(local.cicd_repositories.networking.type, null) == "sourcerepo" - ? { 0 = local.cicd_repositories.networking } - : {} - ) - project_id = var.automation.project_id - name = each.value.name - iam = { - "roles/source.admin" = [module.branch-network-sa.iam_email] - "roles/source.reader" = [module.branch-network-sa-cicd[0].iam_email] - } - triggers = { - fast-02-networking = { - filename = ".cloudbuild/workflow.yaml" - included_files = ["**/*tf", ".cloudbuild/workflow.yaml"] - service_account = module.branch-network-sa-cicd[0].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.branch-network-sa-cicd] -} - # read-write (apply) SA used by CI/CD workflows to impersonate automation SA module "branch-network-sa-cicd" { @@ -61,30 +29,22 @@ module "branch-network-sa-cicd" { name = "prod-resman-net-1" display_name = "Terraform CI/CD stage 2 networking service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? { - "roles/iam.serviceAccountUser" = local.automation_resman_sa_iam - } - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -106,21 +66,15 @@ module "branch-network-r-sa-cicd" { name = "prod-resman-net-1r" display_name = "Terraform CI/CD stage 2 networking service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } diff --git a/fast/stages/1-resman/cicd-project-factory.tf b/fast/stages/1-resman/cicd-project-factory.tf index 7be7a47962..a5c244818b 100644 --- a/fast/stages/1-resman/cicd-project-factory.tf +++ b/fast/stages/1-resman/cicd-project-factory.tf @@ -16,72 +16,6 @@ # tfdoc:file:description CI/CD resources for the project factories. -# source repositories - -module "branch-pf-dev-cicd-repo" { - source = "../../../modules/source-repository" - for_each = ( - try(local.cicd_repositories.project_factory_dev.type, null) == "sourcerepo" - ? { 0 = local.cicd_repositories.project_factory_dev } - : {} - ) - project_id = var.automation.project_id - name = each.value.name - iam = { - "roles/source.admin" = [module.branch-pf-dev-sa[0].iam_email] - "roles/source.reader" = [module.branch-pf-dev-sa-cicd[0].iam_email] - } - triggers = { - fast-03-pf-dev = { - filename = ".cloudbuild/workflow.yaml" - included_files = [ - "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" - ] - service_account = module.branch-pf-dev-sa-cicd[0].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.branch-pf-dev-sa-cicd] -} - -module "branch-pf-prod-cicd-repo" { - source = "../../../modules/source-repository" - for_each = ( - try(local.cicd_repositories.project_factory_prod.type, null) == "sourcerepo" - ? { 0 = local.cicd_repositories.project_factory_prod } - : {} - ) - project_id = var.automation.project_id - name = each.value.name - iam = { - "roles/source.admin" = [module.branch-pf-prod-sa[0].iam_email] - "roles/source.reader" = [module.branch-pf-prod-sa-cicd[0].iam_email] - } - triggers = { - fast-03-pf-prod = { - filename = ".cloudbuild/workflow.yaml" - included_files = [ - "**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml" - ] - service_account = module.branch-pf-prod-sa-cicd[0].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.branch-pf-prod-sa-cicd] -} - # read-write (apply) SAs used by CI/CD workflows to impersonate automation SAs module "branch-pf-dev-sa-cicd" { @@ -95,30 +29,22 @@ module "branch-pf-dev-sa-cicd" { name = "dev-pf-resman-pf-1" display_name = "Terraform CI/CD project factory development service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? { - "roles/iam.serviceAccountUser" = local.automation_resman_sa_iam - } - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -138,30 +64,22 @@ module "branch-pf-prod-sa-cicd" { name = "prod-pf-resman-pf-1" display_name = "Terraform CI/CD project factory production service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? { - "roles/iam.serviceAccountUser" = local.automation_resman_sa_iam - } - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -183,21 +101,15 @@ module "branch-pf-dev-r-sa-cicd" { name = "dev-resman-pf-1r" display_name = "Terraform CI/CD project factory development service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -217,21 +129,15 @@ module "branch-pf-prod-r-sa-cicd" { name = "prod-resman-pf-1r" display_name = "Terraform CI/CD project factory production service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } diff --git a/fast/stages/1-resman/cicd-security.tf b/fast/stages/1-resman/cicd-security.tf index 90eb955eee..1fbb444d13 100644 --- a/fast/stages/1-resman/cicd-security.tf +++ b/fast/stages/1-resman/cicd-security.tf @@ -16,38 +16,6 @@ # tfdoc:file:description CI/CD resources for the security branch. -# source repository - -module "branch-security-cicd-repo" { - source = "../../../modules/source-repository" - for_each = ( - try(local.cicd_repositories.security.type, null) == "sourcerepo" - ? { 0 = local.cicd_repositories.security } - : {} - ) - project_id = var.automation.project_id - name = each.value.name - iam = { - "roles/source.admin" = [module.branch-security-sa.iam_email] - "roles/source.reader" = [module.branch-security-sa-cicd[0].iam_email] - } - triggers = { - fast-02-security = { - filename = ".cloudbuild/workflow.yaml" - included_files = ["**/*tf", ".cloudbuild/workflow.yaml"] - service_account = module.branch-security-sa-cicd[0].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.branch-security-sa-cicd] -} - # read-write (apply) SA used by CI/CD workflows to impersonate automation SA module "branch-security-sa-cicd" { @@ -61,30 +29,22 @@ module "branch-security-sa-cicd" { name = "prod-resman-sec-1" display_name = "Terraform CI/CD stage 2 security service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? { - "roles/iam.serviceAccountUser" = local.automation_resman_sa_iam - } - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } @@ -106,21 +66,15 @@ module "branch-security-r-sa-cicd" { name = "prod-resman-sec-1r" display_name = "Terraform CI/CD stage 2 security service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (var.automation.project_id) = ["roles/logging.logWriter"] } diff --git a/fast/stages/1-resman/main.tf b/fast/stages/1-resman/main.tf index af3df9b5f2..cd156224a6 100644 --- a/fast/stages/1-resman/main.tf +++ b/fast/stages/1-resman/main.tf @@ -15,15 +15,12 @@ */ locals { - # convenience flags that express where billing account resides - automation_resman_sa = try( - data.google_client_openid_userinfo.provider_identity[0].email, null - ) - automation_resman_sa_iam = ( - local.automation_resman_sa == null - ? [] - : ["serviceAccount:${local.automation_resman_sa}"] - ) + # leaving this here to document how to get self identity in a stage + + # automation_resman_sa = try( + # data.google_client_openid_userinfo.provider_identity[0].email, null + # ) + # service accounts that receive additional grants on networking/security branch_optional_sa_lists = { dp-dev = compact([try(module.branch-dp-dev-sa[0].iam_email, "")]) @@ -50,13 +47,9 @@ locals { for k, v in coalesce(var.cicd_repositories, {}) : k => v if( v != null && - ( - try(v.type, null) == "sourcerepo" - || - contains( - keys(local.identity_providers), - coalesce(try(v.identity_provider, null), ":") - ) + contains( + keys(local.identity_providers), + coalesce(try(v.identity_provider, null), ":") ) && fileexists("${path.module}/templates/workflow-${try(v.type, "")}.yaml") ) @@ -113,6 +106,6 @@ locals { ) } -data "google_client_openid_userinfo" "provider_identity" { - count = length(local.cicd_repositories) > 0 ? 1 : 0 -} +# data "google_client_openid_userinfo" "provider_identity" { +# count = length(local.cicd_repositories) > 0 ? 1 : 0 +# } diff --git a/fast/stages/1-resman/variables.tf b/fast/stages/1-resman/variables.tf index 6e3c8200dd..aadd3bf7b5 100644 --- a/fast/stages/1-resman/variables.tf +++ b/fast/stages/1-resman/variables.tf @@ -92,22 +92,18 @@ variable "cicd_repositories" { validation { condition = alltrue([ for k, v in coalesce(var.cicd_repositories, {}) : - v == null || ( - try(v.identity_provider, null) != null - || - try(v.type, null) == "sourcerepo" - ) + v == null || try(v.identity_provider, null) != null ]) - error_message = "Non-null repositories need a non-null provider unless type is 'sourcerepo'." + error_message = "Non-null repositories need a non-null provider." } validation { condition = alltrue([ for k, v in coalesce(var.cicd_repositories, {}) : v == null || ( - contains(["github", "gitlab", "sourcerepo"], coalesce(try(v.type, null), "null")) + contains(["github", "gitlab"], coalesce(try(v.type, null), "null")) ) ]) - error_message = "Invalid repository type, supported types: 'github' 'gitlab' or 'sourcerepo'." + error_message = "Invalid repository type, supported types: 'github' or 'gitlab'." } } diff --git a/fast/stages/1-tenant-factory/README.md b/fast/stages/1-tenant-factory/README.md index 9746a17513..024221d89f 100644 --- a/fast/stages/1-tenant-factory/README.md +++ b/fast/stages/1-tenant-factory/README.md @@ -295,7 +295,7 @@ gcloud alpha storage cp gs://{prefix}-{tenant-shortname}-prod-iac-core-0/tfvars/ | [tenant-billing-iam.tf](./tenant-billing-iam.tf) | Per-tenant billing IAM. | billing-account · organization | | | [tenant-core.tf](./tenant-core.tf) | Per-tenant centrally managed resources. | folder · logging-bucket | | | [tenant-fast-automation.tf](./tenant-fast-automation.tf) | Per-tenant FAST bootstrap emulation (automation). | gcs · iam-service-account · project | | -| [tenant-fast-cicd.tf](./tenant-fast-cicd.tf) | Per-tenant CI/CD resources. | iam-service-account · source-repository | | +| [tenant-fast-cicd.tf](./tenant-fast-cicd.tf) | Per-tenant CI/CD resources. | iam-service-account | | | [tenant-fast-identity-providers.tf](./tenant-fast-identity-providers.tf) | Per-tenant Workload Identity Federation providers. | | google_iam_workload_identity_pool · google_iam_workload_identity_pool_provider | | [tenant-fast-logging.tf](./tenant-fast-logging.tf) | Per-tenant FAST bootstrap emulation (logging). | project | | | [tenant-fast-vpcsc.tf](./tenant-fast-vpcsc.tf) | Per-tenant VPC-SC resources. | vpc-sc | | diff --git a/fast/stages/1-tenant-factory/tenant-fast-automation.tf b/fast/stages/1-tenant-factory/tenant-fast-automation.tf index c7e3a2e7d0..9146b2606d 100644 --- a/fast/stages/1-tenant-factory/tenant-fast-automation.tf +++ b/fast/stages/1-tenant-factory/tenant-fast-automation.tf @@ -71,7 +71,6 @@ module "tenant-automation-project" { "pubsub.googleapis.com", "servicenetworking.googleapis.com", "serviceusage.googleapis.com", - "sourcerepo.googleapis.com", "stackdriver.googleapis.com", "storage-component.googleapis.com", "storage.googleapis.com", diff --git a/fast/stages/1-tenant-factory/tenant-fast-cicd.tf b/fast/stages/1-tenant-factory/tenant-fast-cicd.tf index 6320b45874..52c2ee0408 100644 --- a/fast/stages/1-tenant-factory/tenant-fast-cicd.tf +++ b/fast/stages/1-tenant-factory/tenant-fast-cicd.tf @@ -65,9 +65,6 @@ locals { && # either ( - # don't need a WIF provider, or - try(v.fast_config.cicd_config.type, null) == "sourcerepo" - || # use an org-level WIF provider, or try(var.automation.federated_identity_providers[v.wif_provider], null) != null || @@ -85,39 +82,6 @@ locals { } } -module "tenant-cicd-repo" { - source = "../../../modules/source-repository" - for_each = { - for k, v in local.cicd_repositories : - k => v if v.type == "sourcerepo" - } - project_id = module.tenant-automation-project[each.key].project_id - name = "tenant-${each.key}-resman" - iam = { - "roles/source.admin" = [ - module.tenant-automation-tf-resman-sa[each.key].iam_email - ] - "roles/source.reader" = [ - module.tenant-automation-tf-cicd-sa[each.key].iam_email - ] - } - triggers = { - fast-02-security = { - filename = ".cloudbuild/workflow.yaml" - included_files = ["**/*tf", ".cloudbuild/workflow.yaml"] - service_account = module.tenant-automation-tf-cicd-sa[each.key].id - substitutions = {} - template = { - project_id = null - branch_name = each.value.branch - repo_name = each.value.name - tag_name = null - } - } - } - depends_on = [module.tenant-automation-tf-cicd-sa] -} - # read-write (apply) SA used by CI/CD workflows to impersonate automation SA module "tenant-automation-tf-cicd-sa" { @@ -127,28 +91,22 @@ module "tenant-automation-tf-cicd-sa" { name = "${each.key}-1" display_name = "Terraform CI/CD ${each.key} service account." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # used directly from the cloud build trigger for source repos - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - each.value.branch == null - ? format( - local.identity_providers[each.value.tenant][each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - : format( - local.identity_providers[each.value.tenant][each.value.identity_provider].principal_branch, - var.automation.federated_identity_pool, - each.value.name, - each.value.branch - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + each.value.branch == null + ? format( + local.identity_providers[each.value.tenant][each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + : format( + local.identity_providers[each.value.tenant][each.value.identity_provider].principal_branch, + var.automation.federated_identity_pool, + each.value.name, + each.value.branch + ) + ] + } iam_project_roles = { (module.tenant-automation-project[each.key].project_id) = [ "roles/logging.logWriter" @@ -170,21 +128,15 @@ module "automation-tf-cicd-r-sa" { name = "tenant-${each.key}-1r" display_name = "Terraform CI/CD ${each.key} service account (read-only)." prefix = var.prefix - iam = ( - each.value.type == "sourcerepo" - # build trigger for read-only SA is optionally defined by users - ? {} - # impersonated via workload identity federation for external repos - : { - "roles/iam.workloadIdentityUser" = [ - format( - local.identity_providers[each.value.tenant][each.value.identity_provider].principal_repo, - var.automation.federated_identity_pool, - each.value.name - ) - ] - } - ) + iam = { + "roles/iam.workloadIdentityUser" = [ + format( + local.identity_providers[each.value.tenant][each.value.identity_provider].principal_repo, + var.automation.federated_identity_pool, + each.value.name + ) + ] + } iam_project_roles = { (module.tenant-automation-project[each.key].project_id) = [ "roles/logging.logWriter" diff --git a/tests/fast/stages/s0_bootstrap/checklist.yaml b/tests/fast/stages/s0_bootstrap/checklist.yaml index 0afc1ba30c..14b9d6d961 100644 --- a/tests/fast/stages/s0_bootstrap/checklist.yaml +++ b/tests/fast/stages/s0_bootstrap/checklist.yaml @@ -383,7 +383,7 @@ counts: google_project_iam_audit_config: 1 google_project_iam_binding: 19 google_project_iam_member: 7 - google_project_service: 31 + google_project_service: 30 google_project_service_identity: 4 google_service_account: 4 google_service_account_iam_binding: 2 @@ -395,4 +395,4 @@ counts: google_tags_tag_key: 1 google_tags_tag_value: 1 modules: 18 - resources: 206 + resources: 205 diff --git a/tests/fast/stages/s0_bootstrap/simple.yaml b/tests/fast/stages/s0_bootstrap/simple.yaml index d7b4ddbac6..f115226986 100644 --- a/tests/fast/stages/s0_bootstrap/simple.yaml +++ b/tests/fast/stages/s0_bootstrap/simple.yaml @@ -50,7 +50,7 @@ counts: google_project_iam_audit_config: 1 google_project_iam_binding: 19 google_project_iam_member: 7 - google_project_service: 31 + google_project_service: 30 google_project_service_identity: 4 google_service_account: 4 google_service_account_iam_binding: 2 @@ -63,7 +63,7 @@ counts: google_tags_tag_value: 1 local_file: 8 modules: 17 - resources: 198 + resources: 197 outputs: custom_roles: diff --git a/tests/fast/stages/s1_tenant_factory/simple.yaml b/tests/fast/stages/s1_tenant_factory/simple.yaml index 62e2398cdf..a0cddf8100 100644 --- a/tests/fast/stages/s1_tenant_factory/simple.yaml +++ b/tests/fast/stages/s1_tenant_factory/simple.yaml @@ -29,7 +29,7 @@ counts: google_project_iam_audit_config: 2 google_project_iam_binding: 32 google_project_iam_member: 18 - google_project_service: 56 + google_project_service: 54 google_project_service_identity: 8 google_service_account: 16 google_service_account_iam_binding: 6 @@ -43,4 +43,4 @@ counts: google_tags_tag_key: 1 google_tags_tag_value: 4 modules: 50 - resources: 274 + resources: 272