# GKE hub module This module allows simplified creation and management of a GKE Hub object and its features for a given set of clusters. The given list of clusters will be registered inside the Hub and all the configured features will be activated. To use this module you must ensure the following APIs are enabled in the target project: - `gkehub.googleapis.com` - `gkeconnect.googleapis.com` - `anthosconfigmanagement.googleapis.com` - `multiclusteringress.googleapis.com` - `multiclusterservicediscovery.googleapis.com` - `mesh.googleapis.com` ## Full GKE Hub example ```hcl module "project" { source = "./fabric/modules/project" billing_account = var.billing_account_id name = "gkehub-test" parent = "folders/12345" services = [ "anthosconfigmanagement.googleapis.com", "container.googleapis.com", "gkeconnect.googleapis.com", "gkehub.googleapis.com", "multiclusteringress.googleapis.com", "multiclusterservicediscovery.googleapis.com", "mesh.googleapis.com" ] } module "vpc" { source = "./fabric/modules/net-vpc" project_id = module.project.project_id name = "network" subnets = [{ ip_cidr_range = "10.0.0.0/24" name = "cluster-1" region = "europe-west1" secondary_ip_range = { pods = "10.1.0.0/16" services = "10.2.0.0/24" } }] } module "cluster_1" { source = "./fabric/modules/gke-cluster-standard" project_id = module.project.project_id name = "cluster-1" location = "europe-west1" vpc_config = { network = module.vpc.self_link subnetwork = module.vpc.subnet_self_links["europe-west1/cluster-1"] master_authorized_ranges = { fc1918_10_8 = "10.0.0.0/8" } master_ipv4_cidr_block = "192.168.0.0/28" } enable_features = { dataplane_v2 = true workload_identity = true } private_cluster_config = { enable_private_endpoint = true master_global_access = false } } module "hub" { source = "./fabric/modules/gke-hub" project_id = module.project.project_id clusters = { cluster-1 = module.cluster_1.id } features = { appdevexperience = false configmanagement = true identityservice = false multiclusteringress = null servicemesh = false multiclusterservicediscovery = false } configmanagement_templates = { default = { binauthz = false config_sync = { git = { gcp_service_account_email = null https_proxy = null policy_dir = "configsync" secret_type = "none" source_format = "hierarchy" sync_branch = "main" sync_repo = "https://github.com/danielmarzini/configsync-platform-example" sync_rev = null sync_wait_secs = null } prevent_drift = false source_format = "hierarchy" } hierarchy_controller = { enable_hierarchical_resource_quota = true enable_pod_tree_labels = true } policy_controller = { audit_interval_seconds = 120 exemptable_namespaces = [] log_denies_enabled = true referential_rules_enabled = true template_library_installed = true } version = "v1" } } configmanagement_clusters = { "default" = ["cluster-1"] } } # tftest modules=4 resources=16 ``` ## Multi-cluster mesh on GKE ```hcl module "project" { source = "./fabric/modules/project" billing_account = "123-456-789" name = "gkehub-test" parent = "folders/12345" services = [ "anthos.googleapis.com", "container.googleapis.com", "gkehub.googleapis.com", "gkeconnect.googleapis.com", "mesh.googleapis.com", "meshconfig.googleapis.com", "meshca.googleapis.com" ] } resource "google_project_iam_member" "gkehub_fix" { member = "serviceAccount:${module.project.service_accounts.robots.fleet}" project = module.project.project_id role = "roles/gkehub.serviceAgent" } module "vpc" { source = "./fabric/modules/net-vpc" project_id = module.project.project_id name = "vpc" mtu = 1500 subnets = [ { ip_cidr_range = "10.0.1.0/24" name = "subnet-cluster-1" region = "europe-west1" secondary_ip_ranges = { pods = "10.1.0.0/16" services = "10.2.0.0/24" } }, { ip_cidr_range = "10.0.2.0/24" name = "subnet-cluster-2" region = "europe-west4" secondary_ip_ranges = { pods = "10.3.0.0/16" services = "10.4.0.0/24" } }, { ip_cidr_range = "10.0.0.0/28" name = "subnet-mgmt" region = "europe-west1" secondary_ip_ranges = null } ] } module "firewall" { source = "./fabric/modules/net-vpc-firewall" project_id = module.project.project_id network = module.vpc.name ingress_rules = { allow-mesh = { description = "Allow mesh" priority = 900 source_ranges = ["10.1.0.0/16", "10.3.0.0/16"] targets = ["cluster-1-node", "cluster-2-node"] }, "allow-cluster-1-istio" = { description = "Allow istio sidecar injection, istioctl version and istioctl ps" source_ranges = ["192.168.1.0/28"] targets = ["cluster-1-node"] rules = [ { protocol = "tcp", ports = [8080, 15014, 15017] } ] }, "allow-cluster-2-istio" = { description = "Allow istio sidecar injection, istioctl version and istioctl ps" source_ranges = ["192.168.2.0/28"] targets = ["cluster-2-node"] rules = [ { protocol = "tcp", ports = [8080, 15014, 15017] } ] } } } module "cluster_1" { source = "./fabric/modules/gke-cluster-standard" project_id = module.project.project_id name = "cluster-1" location = "europe-west1" vpc_config = { network = module.vpc.self_link subnetwork = module.vpc.subnet_self_links["europe-west1/subnet-cluster-1"] master_authorized_ranges = { mgmt = "10.0.0.0/28" pods-cluster-1 = "10.3.0.0/16" } master_ipv4_cidr_block = "192.168.1.0/28" } private_cluster_config = { enable_private_endpoint = false master_global_access = true } release_channel = "REGULAR" labels = { mesh_id = "proj-${module.project.number}" } enable_features = { workload_identity = true dataplane_v2 = true } } module "cluster_1_nodepool" { source = "./fabric/modules/gke-nodepool" project_id = module.project.project_id cluster_name = module.cluster_1.name cluster_id = module.cluster_1.id location = "europe-west1" name = "cluster-1-nodepool" node_count = { initial = 1 } service_account = { create = true } tags = ["cluster-1-node"] } module "cluster_2" { source = "./fabric/modules/gke-cluster-standard" project_id = module.project.project_id name = "cluster-2" location = "europe-west4" vpc_config = { network = module.vpc.self_link subnetwork = module.vpc.subnet_self_links["europe-west4/subnet-cluster-2"] master_authorized_ranges = { mgmt = "10.0.0.0/28" pods-cluster-1 = "10.3.0.0/16" } master_ipv4_cidr_block = "192.168.2.0/28" } private_cluster_config = { enable_private_endpoint = false master_global_access = true } release_channel = "REGULAR" labels = { mesh_id = "proj-${module.project.number}" } enable_features = { workload_identity = true dataplane_v2 = true } } module "cluster_2_nodepool" { source = "./fabric/modules/gke-nodepool" project_id = module.project.project_id cluster_name = module.cluster_2.name cluster_id = module.cluster_2.id location = "europe-west4" name = "cluster-2-nodepool" node_count = { initial = 1 } service_account = { create = true } tags = ["cluster-2-node"] } module "hub" { source = "./fabric/modules/gke-hub" project_id = module.project.project_id depends_on = [google_project_iam_member.gkehub_fix] clusters = { cluster-1 = module.cluster_1.id cluster-2 = module.cluster_2.id } features = { appdevexperience = false configmanagement = false identityservice = false multiclusteringress = null servicemesh = true multiclusterservicediscovery = false } workload_identity_clusters = [ "cluster-1", "cluster-2" ] } # tftest modules=8 resources=32 ``` ## Variables | name | description | type | required | default | |---|---|:---:|:---:|:---:| | [project_id](variables.tf#L87) | GKE hub project ID. | string | ✓ | | | [clusters](variables.tf#L17) | Clusters members of this GKE Hub in name => id format. | map(string) | | {} | | [configmanagement_clusters](variables.tf#L24) | Config management features enabled on specific sets of member clusters, in config name => [cluster name] format. | map(list(string)) | | {} | | [configmanagement_templates](variables.tf#L31) | Sets of config management configurations that can be applied to member clusters, in config name => {options} format. | map(object({…})) | | {} | | [features](variables.tf#L66) | Enable and configue fleet features. | object({…}) | | {…} | | [workload_identity_clusters](variables.tf#L92) | Clusters that will use Fleet Workload Identity. | list(string) | | [] | ## Outputs | name | description | sensitive | |---|---|:---:| | [cluster_ids](outputs.tf#L17) | Ids of all the clusters created. | |