diff --git a/fast/stages/03-gke-multitenant/module/gke-hub.tf b/fast/stages/03-gke-multitenant/module/gke-hub.tf index b1e24a9f..a037eba5 100644 --- a/fast/stages/03-gke-multitenant/module/gke-hub.tf +++ b/fast/stages/03-gke-multitenant/module/gke-hub.tf @@ -14,41 +14,31 @@ * limitations under the License. */ +# TODO: service account +# https://cloud.google.com/kubernetes-engine/docs/how-to/msc-setup-with-shared-vpc-networks#shared-service-project-iam +# TODO: add roles/multiclusterservicediscovery.serviceAgent and +# roles/compute.networkViewer to IAM condition for GKE stage SA + +locals { + fleet_enabled = ( + var.fleet_features != null || var.fleet_workload_identity + ) + # TODO: add condition + fleet_mcs_enabled = false +} + module "gke-hub" { source = "../../../../modules/gke-hub" + count = local.fleet_enabled ? 1 : 0 project_id = module.gke-project-0.project_id - member_clusters = { + clusters = { for cluster_id in keys(var.clusters) : cluster_id => module.gke-cluster[cluster_id].id } - member_features = { - configmanagement = { - binauthz = false - config_sync = { - gcp_service_account_email = null - https_proxy = null - policy_dir = "fast/stages/03-gke/config" - secret_type = "none" - source_format = "hierarchy" - sync_branch = "fast-dev-gke-marzi" - sync_repo = "https://github.com/GoogleCloudPlatform/cloud-foundation-fabric" - sync_rev = null - } - hierarchy_controller = null - policy_controller = { - exemptable_namespaces = [ - "asm-system", - "config-management-system", - "config-management-monitoring", - "gatekeeper-system", - "kube-system", - "cos-auditd" - ] - log_denies_enabled = true - referential_rules_enabled = false - template_library_installed = true - } - version = "1.10.2" - } - } + features = var.fleet_features + configmanagement_templates = var.fleet_configmanagement_templates + configmanagement_clusters = var.fleet_configmanagement_clusters + workload_identity_clusters = ( + var.fleet_workload_identity ? keys(var.clusters) : [] + ) } diff --git a/fast/stages/03-gke-multitenant/module/main.tf b/fast/stages/03-gke-multitenant/module/main.tf index 227d1972..626c36b4 100644 --- a/fast/stages/03-gke-multitenant/module/main.tf +++ b/fast/stages/03-gke-multitenant/module/main.tf @@ -44,14 +44,18 @@ module "gke-project-0" { shared_vpc_service_config = { attach = true host_project = var.host_project_ids.dev-spoke-0 - service_identity_iam = { + service_identity_iam = merge({ "roles/compute.networkUser" = [ "cloudservices", "container-engine" ] "roles/container.hostServiceAgentUser" = [ "container-engine" ] - } + }, + !local.fleet_mcs_enabled ? {} : { + "roles/multiclusterservicediscovery.serviceAgent" = ["gke-mcs"] + "roles/compute.networkViewer" = ["gke-mcs-importer"] + }) } # specify project-level org policies here if you need them # policy_boolean = { diff --git a/fast/stages/03-gke-multitenant/module/variables.tf b/fast/stages/03-gke-multitenant/module/variables.tf index 083cbb74..1df64622 100644 --- a/fast/stages/03-gke-multitenant/module/variables.tf +++ b/fast/stages/03-gke-multitenant/module/variables.tf @@ -103,6 +103,69 @@ variable "dns_domain" { default = null } +variable "fleet_configmanagement_clusters" { + description = "Config management features enabled on specific sets of member clusters, in config name => [cluster name] format." + type = map(list(string)) + default = {} + nullable = false +} + + +variable "fleet_configmanagement_templates" { + description = "Sets of config management configurations that can be applied to member clusters, in config name => {options} format." + type = map(object({ + binauthz = bool + config_sync = object({ + git = object({ + gcp_service_account_email = string + https_proxy = string + policy_dir = string + secret_type = string + sync_branch = string + sync_repo = string + sync_rev = string + sync_wait_secs = number + }) + prevent_drift = string + source_format = string + }) + hierarchy_controller = object({ + enable_hierarchical_resource_quota = bool + enable_pod_tree_labels = bool + }) + policy_controller = object({ + audit_interval_seconds = number + exemptable_namespaces = list(string) + log_denies_enabled = bool + referential_rules_enabled = bool + template_library_installed = bool + }) + version = string + })) + default = {} + nullable = false +} + +variable "fleet_features" { + description = "Enable and configue fleet features. Set to null to disable GKE Hub if fleet workload identity is not used." + type = object({ + appdevexperience = bool + configmanagement = bool + identityservice = bool + multiclusteringress = string + multiclusterservicediscovery = bool + servicemesh = bool + }) + default = null +} + +variable "fleet_workload_identity" { + description = "Use Fleet Workload Identity for clusters. Enables GKE Hub if set to true." + type = bool + default = true + nullable = false +} + variable "folder_ids" { # tfdoc:variable:source 01-resman description = "Folders to be used for the networking resources in folders/nnnnnnnnnnn format. If null, folder will be created." @@ -111,6 +174,13 @@ variable "folder_ids" { }) } +variable "group_iam" { + description = "Project-level IAM bindings for groups. Use group emails as keys, list of roles as values." + type = map(list(string)) + default = {} + nullable = false +} + variable "host_project_ids" { # tfdoc:variable:source 02-networking description = "Host project for the shared VPC." @@ -119,13 +189,6 @@ variable "host_project_ids" { }) } -variable "group_iam" { - description = "Project-level IAM bindings for groups. Use group emails as keys, list of roles as values." - type = map(list(string)) - default = {} - nullable = false -} - variable "labels" { description = "Project-level labels." type = map(string) diff --git a/modules/project/service-accounts.tf b/modules/project/service-accounts.tf index af387364..7d584fa7 100644 --- a/modules/project/service-accounts.tf +++ b/modules/project/service-accounts.tf @@ -40,7 +40,9 @@ locals { fleet = "service-%s@gcp-sa-gkehub" gae-flex = "service-%s@gae-api-prod" # TODO: deprecate gcf - gcf = "service-%s@gcf-admin-robot" + gcf = "service-%s@gcf-admin-robot" + # TODO: jit? + gke-mcs = "service-%s@gcp-sa-mcsd" monitoring-notifications = "service-%s@gcp-sa-monitoring-notification" pubsub = "service-%s@gcp-sa-pubsub" secretmanager = "service-%s@gcp-sa-secretmanager" @@ -55,10 +57,15 @@ locals { service_account_cloud_services = ( "${local.project.number}@cloudservices.gserviceaccount.com" ) - service_accounts_robots = { - for k, v in local._service_accounts_robot_services : - k => "${format(v, local.project.number)}.iam.gserviceaccount.com" - } + service_accounts_robots = merge( + { + for k, v in local._service_accounts_robot_services : + k => "${format(v, local.project.number)}.iam.gserviceaccount.com" + }, + { + gke-mcs-importer = "${local.project.project_id}.svc.id.goog[gke-mcs/gke-mcs-importer]" + } + ) service_accounts_jit_services = [ "cloudasset.googleapis.com", "gkehub.googleapis.com",