diff --git a/fast/stages/00-bootstrap/README.md b/fast/stages/00-bootstrap/README.md index 5b7f495d..26218366 100644 --- a/fast/stages/00-bootstrap/README.md +++ b/fast/stages/00-bootstrap/README.md @@ -461,18 +461,18 @@ 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 and organization id ('nnnnnnnn' or null). | object({…}) | ✓ | | | -| [organization](variables.tf#L179) | Organization details. | object({…}) | ✓ | | | -| [prefix](variables.tf#L194) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | | +| [organization](variables.tf#L181) | Organization details. | object({…}) | ✓ | | | +| [prefix](variables.tf#L196) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | | | [bootstrap_user](variables.tf#L25) | Email of the nominal user running this stage for the first time. | string | | null | | | [cicd_repositories](variables.tf#L31) | 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_role_names](variables.tf#L83) | Names of custom roles defined at the org level. | object({…}) | | {…} | | -| [fast_features](variables.tf#L95) | Selective control for top-level FAST features. | object({…}) | | {…} | | -| [federated_identity_providers](variables.tf#L112) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | map(object({…})) | | {} | | -| [groups](variables.tf#L126) | Group names to grant organization-level permissions. | map(string) | | {…} | | -| [iam](variables.tf#L140) | Organization-level custom IAM settings in role => [principal] format. | map(list(string)) | | {} | | -| [iam_additive](variables.tf#L146) | Organization-level custom IAM settings in role => [principal] format for non-authoritative bindings. | map(list(string)) | | {} | | -| [log_sinks](variables.tf#L154) | Org-level log sinks, in name => {type, filter} format. | map(object({…})) | | {…} | | -| [outputs_location](variables.tf#L188) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable | string | | null | | +| [fast_features](variables.tf#L95) | Selective control for top-level FAST features. | object({…}) | | {…} | | +| [federated_identity_providers](variables.tf#L114) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | map(object({…})) | | {} | | +| [groups](variables.tf#L128) | Group names to grant organization-level permissions. | map(string) | | {…} | | +| [iam](variables.tf#L142) | Organization-level custom IAM settings in role => [principal] format. | map(list(string)) | | {} | | +| [iam_additive](variables.tf#L148) | Organization-level custom IAM settings in role => [principal] format for non-authoritative bindings. | map(list(string)) | | {} | | +| [log_sinks](variables.tf#L156) | Org-level log sinks, in name => {type, filter} format. | map(object({…})) | | {…} | | +| [outputs_location](variables.tf#L190) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable | string | | null | | ## Outputs diff --git a/fast/stages/00-bootstrap/organization.tf b/fast/stages/00-bootstrap/organization.tf index 947269c1..a9fa6af0 100644 --- a/fast/stages/00-bootstrap/organization.tf +++ b/fast/stages/00-bootstrap/organization.tf @@ -163,6 +163,12 @@ module "organization" { ] (var.custom_role_names.service_project_network_admin) = [ "compute.globalOperations.get", + # the following two permissions are used by automation service accounts + # who manage service projects where peering creation might be needed + # (e.g. GKE), if you remove them make sure your network administrators + # should create peerings for service projects + "compute.networks.updatePeering", + "compute.networks.get", "compute.organizations.disableXpnResource", "compute.organizations.enableXpnResource", "compute.projects.get", @@ -170,14 +176,6 @@ module "organization" { "compute.subnetworks.setIamPolicy", "dns.networks.bindPrivateDNSZone", "resourcemanager.projects.get", - - # if you prefer not granting permissions to create peerings to - # service accounts deploying service projects, remove these - # permissions and ask you network administrator to create any - # needed peerings (e.g. if you need to update routes for a GKE - # cluster) - "compute.networks.updatePeering", - "compute.networks.get", ] } logging_sinks = { diff --git a/fast/stages/00-bootstrap/variables.tf b/fast/stages/00-bootstrap/variables.tf index e9cc26e3..10ffdeef 100644 --- a/fast/stages/00-bootstrap/variables.tf +++ b/fast/stages/00-bootstrap/variables.tf @@ -96,12 +96,14 @@ variable "fast_features" { description = "Selective control for top-level FAST features." type = object({ data_platform = bool + gke = bool project_factory = bool sandbox = bool teams = bool }) default = { data_platform = true + gke = true project_factory = true sandbox = true teams = true diff --git a/fast/stages/01-resman/README.md b/fast/stages/01-resman/README.md index 68a9caae..010f5a3d 100644 --- a/fast/stages/01-resman/README.md +++ b/fast/stages/01-resman/README.md @@ -182,29 +182,30 @@ Due to its simplicity, this stage lends itself easily to customizations: adding |---|---|:---:|:---:|:---:|:---:| | [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#L159) | Organization details. | object({…}) | ✓ | | 00-bootstrap | -| [prefix](variables.tf#L183) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 00-bootstrap | +| [organization](variables.tf#L161) | Organization details. | object({…}) | ✓ | | 00-bootstrap | +| [prefix](variables.tf#L185) | 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 | -| [fast_features](variables.tf#L126) | Selective control for top-level FAST features. | object({…}) | | {…} | 00-bootstrap | -| [groups](variables.tf#L144) | Group names to grant organization-level permissions. | map(string) | | {…} | 00-bootstrap | -| [organization_policy_configs](variables.tf#L169) | Organization policies customization. | object({…}) | | null | | -| [outputs_location](variables.tf#L177) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable | string | | null | | -| [tag_names](variables.tf#L194) | Customized names for resource management tags. | object({…}) | | {…} | | -| [team_folders](variables.tf#L211) | Team folders to be created. Format is described in a code comment. | map(object({…})) | | null | | +| [fast_features](variables.tf#L126) | Selective control for top-level FAST features. | object({…}) | | {…} | 00-bootstrap | +| [groups](variables.tf#L146) | Group names to grant organization-level permissions. | map(string) | | {…} | 00-bootstrap | +| [organization_policy_configs](variables.tf#L171) | Organization policies customization. | object({…}) | | null | | +| [outputs_location](variables.tf#L179) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable | string | | null | | +| [tag_names](variables.tf#L196) | Customized names for resource management tags. | object({…}) | | {…} | | +| [team_folders](variables.tf#L213) | Team folders to be created. Format is described in a code comment. | map(object({…})) | | null | | ## Outputs | name | description | sensitive | consumers | |---|---|:---:|---| -| [cicd_repositories](outputs.tf#L154) | WIF configuration for CI/CD repositories. | | | -| [dataplatform](outputs.tf#L168) | Data for the Data Platform stage. | | | -| [networking](outputs.tf#L184) | Data for the networking stage. | | | -| [project_factories](outputs.tf#L193) | Data for the project factories stage. | | | -| [providers](outputs.tf#L209) | Terraform provider files for this stage and dependent stages. | ✓ | 02-networking · 02-security · 03-dataplatform · xx-sandbox · xx-teams | -| [sandbox](outputs.tf#L216) | Data for the sandbox stage. | | xx-sandbox | -| [security](outputs.tf#L230) | Data for the networking stage. | | 02-security | -| [teams](outputs.tf#L240) | Data for the teams stage. | | | -| [tfvars](outputs.tf#L253) | Terraform variable files for the following stages. | ✓ | | +| [cicd_repositories](outputs.tf#L166) | WIF configuration for CI/CD repositories. | | | +| [dataplatform](outputs.tf#L180) | Data for the Data Platform stage. | | | +| [gke_multitenant](outputs.tf#L252) | Data for the GKE multitenant stage. | | 03-gke-multitenant | +| [networking](outputs.tf#L196) | Data for the networking stage. | | | +| [project_factories](outputs.tf#L205) | Data for the project factories stage. | | | +| [providers](outputs.tf#L221) | Terraform provider files for this stage and dependent stages. | ✓ | 02-networking · 02-security · 03-dataplatform · xx-sandbox · xx-teams | +| [sandbox](outputs.tf#L228) | Data for the sandbox stage. | | xx-sandbox | +| [security](outputs.tf#L242) | Data for the networking stage. | | 02-security | +| [teams](outputs.tf#L269) | Data for the teams stage. | | | +| [tfvars](outputs.tf#L282) | Terraform variable files for the following stages. | ✓ | | diff --git a/fast/stages/01-resman/billing.tf b/fast/stages/01-resman/billing.tf index b3223b75..9fa57de7 100644 --- a/fast/stages/01-resman/billing.tf +++ b/fast/stages/01-resman/billing.tf @@ -24,12 +24,12 @@ locals { module.branch-security-sa.iam_email, ], local.branch_dataplatform_sa_iam_emails, + local.branch_gke_sa_iam_emails, + local.branch_pf_sa_iam_emails, # enable if individual teams can create their own projects # [ # for k, v in module.branch-teams-team-sa : v.iam_email # ], - local.branch_teams_pf_sa_iam_emails, - local.branch_gke_multitenant_sa_iam_emails ) } diff --git a/fast/stages/01-resman/branch-gke.tf b/fast/stages/01-resman/branch-gke.tf index 1cfb3d6f..72b3ffec 100644 --- a/fast/stages/01-resman/branch-gke.tf +++ b/fast/stages/01-resman/branch-gke.tf @@ -32,24 +32,24 @@ module "branch-gke-folder" { # GKE-level folders, service accounts and buckets for each individual environment -module "branch-gke-multitenant-prod-folder" { +module "branch-gke-prod-folder" { source = "../../../modules/folder" parent = module.branch-gke-folder.id name = "Production" iam = { "roles/owner" = [ - module.branch-gke-multitenant-prod-sa.iam_email + module.branch-gke-prod-sa.iam_email ] "roles/resourcemanager.projectCreator" = [ - module.branch-gke-multitenant-prod-sa.iam_email + module.branch-gke-prod-sa.iam_email ] "roles/compute.xpnAdmin" = [ - module.branch-gke-multitenant-prod-sa.iam_email + module.branch-gke-prod-sa.iam_email ] } } -module "branch-gke-multitenant-prod-sa" { +module "branch-gke-prod-sa" { source = "../../../modules/iam-service-account" project_id = var.automation.project_id name = "prod-resman-gke-0" @@ -61,36 +61,36 @@ module "branch-gke-multitenant-prod-sa" { } } -module "branch-gke-multitenant-prod-gcs" { +module "branch-gke-prod-gcs" { source = "../../../modules/gcs" project_id = var.automation.project_id name = "prod-resman-gke-0" prefix = var.prefix versioning = true iam = { - "roles/storage.objectAdmin" = [module.branch-gke-multitenant-prod-sa.iam_email] + "roles/storage.objectAdmin" = [module.branch-gke-prod-sa.iam_email] } } -module "branch-gke-multitenant-dev-folder" { +module "branch-gke-dev-folder" { source = "../../../modules/folder" parent = module.branch-gke-folder.id name = "Development" iam = { "roles/owner" = [ - module.branch-gke-multitenant-dev-sa.iam_email + module.branch-gke-dev-sa.iam_email ] "roles/resourcemanager.projectCreator" = [ - module.branch-gke-multitenant-dev-sa.iam_email + module.branch-gke-dev-sa.iam_email ] "roles/compute.xpnAdmin" = [ - module.branch-gke-multitenant-dev-sa.iam_email + module.branch-gke-dev-sa.iam_email ] } } -module "branch-gke-multitenant-dev-sa" { +module "branch-gke-dev-sa" { source = "../../../modules/iam-service-account" project_id = var.automation.project_id name = "dev-resman-gke-0" @@ -102,13 +102,13 @@ module "branch-gke-multitenant-dev-sa" { } } -module "branch-gke-multitenant-dev-gcs" { +module "branch-gke-dev-gcs" { source = "../../../modules/gcs" project_id = var.automation.project_id name = "dev-resman-gke-0" prefix = var.prefix versioning = true iam = { - "roles/storage.objectAdmin" = [module.branch-gke-multitenant-dev-sa.iam_email] + "roles/storage.objectAdmin" = [module.branch-gke-dev-sa.iam_email] } } diff --git a/fast/stages/01-resman/branch-networking.tf b/fast/stages/01-resman/branch-networking.tf index 79a31745..952c8326 100644 --- a/fast/stages/01-resman/branch-networking.tf +++ b/fast/stages/01-resman/branch-networking.tf @@ -53,7 +53,7 @@ module "branch-network-prod-folder" { "roles/compute.xpnAdmin" = compact([ try(module.branch-dp-prod-sa.0.iam_email, ""), try(module.branch-pf-prod-sa.0.iam_email, ""), - module.branch-gke-multitenant-prod-sa.iam_email, + module.branch-gke-prod-sa.iam_email, ]) } tag_bindings = { @@ -71,7 +71,7 @@ module "branch-network-dev-folder" { (local.custom_roles.service_project_network_admin) = compact([ try(module.branch-dp-dev-sa.0.iam_email, ""), try(module.branch-pf-dev-sa.0.iam_email, ""), - module.branch-gke-multitenant-dev-sa.iam_email, + module.branch-gke-dev-sa.iam_email, ]) } tag_bindings = { diff --git a/fast/stages/01-resman/main.tf b/fast/stages/01-resman/main.tf index c4095796..590c4027 100644 --- a/fast/stages/01-resman/main.tf +++ b/fast/stages/01-resman/main.tf @@ -57,7 +57,6 @@ locals { "02-security.auto.tfvars.json" ] } - custom_roles = coalesce(var.custom_roles, {}) groups = { for k, v in var.groups : diff --git a/fast/stages/01-resman/organization.tf b/fast/stages/01-resman/organization.tf index 24e1a5f9..0de7193a 100644 --- a/fast/stages/01-resman/organization.tf +++ b/fast/stages/01-resman/organization.tf @@ -26,12 +26,15 @@ locals { ] : [] ) - # set to the empty list if you remove the teams branch - branch_gke_multitenant_sa_iam_emails = [ - module.branch-gke-multitenant-dev-sa.iam_email, - module.branch-gke-multitenant-prod-sa.iam_email - ] - branch_teams_pf_sa_iam_emails = ( + branch_gke_sa_iam_emails = ( + var.fast_features.gke + ? [ + module.branch-gke-dev-sa.iam_email, + module.branch-gke-prod-sa.iam_email + ] + : [] + ) + branch_pf_sa_iam_emails = ( var.fast_features.project_factory ? [ module.branch-pf-dev-sa.0.iam_email, @@ -76,19 +79,19 @@ module "organization" { ] }, local.billing_org ? { - "roles/billing.costsManager" = local.branch_teams_pf_sa_iam_emails + "roles/billing.costsManager" = local.branch_pf_sa_iam_emails "roles/billing.user" = concat( [ module.branch-network-sa.iam_email, module.branch-security-sa.iam_email, ], local.branch_dataplatform_sa_iam_emails, + local.branch_gke_sa_iam_emails, + local.branch_pf_sa_iam_emails, # enable if individual teams can create their own projects # [ # for k, v in module.branch-teams-team-sa : v.iam_email # ], - local.branch_teams_pf_sa_iam_emails, - local.branch_gke_multitenant_sa_iam_emails ) } : {} ) diff --git a/fast/stages/01-resman/outputs.tf b/fast/stages/01-resman/outputs.tf index 31188d7c..e57a4ca8 100644 --- a/fast/stages/01-resman/outputs.tf +++ b/fast/stages/01-resman/outputs.tf @@ -64,8 +64,8 @@ locals { { data-platform-dev = try(module.branch-dp-dev-folder.0.id, null) data-platform-prod = try(module.branch-dp-prod-folder.0.id, null) - gke-multitenant-dev = module.branch-gke-multitenant-dev-folder.id - gke-multitenant-prod = module.branch-gke-multitenant-prod-folder.id + gke-multitenant-dev = module.branch-gke-dev-folder.id + gke-multitenant-prod = module.branch-gke-prod-folder.id networking = module.branch-network-folder.id networking-dev = module.branch-network-dev-folder.id networking-prod = module.branch-network-prod-folder.id @@ -98,15 +98,15 @@ locals { name = "security" sa = module.branch-security-sa.email }) - "03-gke-multitenant-dev" = templatefile(local._tpl_providers, { - bucket = module.branch-gke-multitenant-dev-gcs.name - name = "gke-multitenant-dev" - sa = module.branch-gke-multitenant-dev-sa.email + "03-gke-dev" = templatefile(local._tpl_providers, { + bucket = module.branch-gke-dev-gcs.name + name = "gke-dev" + sa = module.branch-gke-dev-sa.email }) - "03-gke-multitenant-prod" = templatefile(local._tpl_providers, { - bucket = module.branch-gke-multitenant-prod-gcs.name - name = "gke-multitenant-prod" - sa = module.branch-gke-multitenant-prod-sa.email + "03-gke-prod" = templatefile(local._tpl_providers, { + bucket = module.branch-gke-prod-gcs.name + name = "gke-prod" + sa = module.branch-gke-prod-sa.email }) }, !var.fast_features.data_platform ? {} : { @@ -254,14 +254,14 @@ output "gke_multitenant" { description = "Data for the GKE multitenant stage." value = { "dev" = { - folder = module.branch-gke-multitenant-dev-folder.id - gcs_bucket = module.branch-gke-multitenant-dev-gcs.name - service_account = module.branch-gke-multitenant-dev-sa.email + folder = module.branch-gke-dev-folder.id + gcs_bucket = module.branch-gke-dev-gcs.name + service_account = module.branch-gke-dev-sa.email } "prod" = { - folder = module.branch-gke-multitenant-prod-folder.id - gcs_bucket = module.branch-gke-multitenant-prod-gcs.name - service_account = module.branch-gke-multitenant-prod-sa.email + folder = module.branch-gke-prod-folder.id + gcs_bucket = module.branch-gke-prod-gcs.name + service_account = module.branch-gke-prod-sa.email } } } diff --git a/fast/stages/01-resman/variables.tf b/fast/stages/01-resman/variables.tf index 35a05efe..f52c5fc6 100644 --- a/fast/stages/01-resman/variables.tf +++ b/fast/stages/01-resman/variables.tf @@ -128,12 +128,14 @@ variable "fast_features" { description = "Selective control for top-level FAST features." type = object({ data_platform = bool + gke = bool project_factory = bool sandbox = bool teams = bool }) default = { data_platform = true + gke = true project_factory = true sandbox = true teams = true