From 202d7994947f645d61d7357663b28e302c876a96 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 15 Jul 2025 15:20:36 +0300 Subject: [PATCH] Fixed gke-hub module to support regional deployment (#3218) * Fixed gke-hub module to support regional deployment * Co-authored-by: Julio Castillo Adding location param for Regional Cluster Memebership,mesh feature default config for managed ASM Updated Readme * Updated fleet_default_member_config to match provider * Fixed tf fmt for readme example * Fix README * Fix linter * Fix variable order * Fix tests * Fixing tests --------- Co-authored-by: Julio Castillo --- modules/gke-hub/README.md | 74 +++++++++++++++++++++++- modules/gke-hub/main.tf | 68 ++++++++++++++++++---- modules/gke-hub/variables.tf | 38 +++++++++++- tests/modules/gke_hub/examples/full.yaml | 15 ++++- 4 files changed, 178 insertions(+), 17 deletions(-) diff --git a/modules/gke-hub/README.md b/modules/gke-hub/README.md index 7be0510d0..9d51da585 100644 --- a/modules/gke-hub/README.md +++ b/modules/gke-hub/README.md @@ -70,6 +70,7 @@ module "cluster_1" { module "hub" { source = "./fabric/modules/gke-hub" project_id = module.project.project_id + location = "europe-west1" clusters = { cluster-1 = module.cluster_1.id } @@ -291,17 +292,86 @@ module "hub" { # tftest modules=8 resources=44 ``` + +## Fleet Default Member Configuration Example + +This example demonstrates how to use the enhanced `fleet_default_member_config` to configure default settings for all member clusters in the fleet: + +```hcl +module "hub" { + source = "./fabric/modules/gke-hub" + project_id = module.project.project_id + location = "europe-west1" + clusters = { + cluster-1 = module.cluster_1.id + cluster-2 = module.cluster_2.id + } + features = { + configmanagement = true + servicemesh = true + } + + # Fleet default member configuration + fleet_default_member_config = { + # Service Mesh configuration + mesh = { + management = "MANAGEMENT_AUTOMATIC" + } + + # Config Management configuration + configmanagement = { + version = "v1" + + # Config Sync configuration + config_sync = { + prevent_drift = true + source_format = "hierarchy" + enabled = true + git = { + sync_repo = "https://github.com/your-org/config-repo" + policy_dir = "configsync" + gcp_service_account_email = "config-sync@your-project.iam.gserviceaccount.com" + secret_type = "gcenode" + sync_branch = "main" + sync_rev = "HEAD" + sync_wait_secs = 15 + } + } + } + } + + # Individual cluster configurations (these will override fleet defaults if specified) + configmanagement_templates = { + cluster-specific = { + config_sync = { + git = { + sync_repo = "https://github.com/your-org/cluster-specific-config" + policy_dir = "cluster-specific" + sync_branch = "main" + } + source_format = "hierarchy" + } + version = "v1" + } + } + configmanagement_clusters = { + "cluster-specific" = ["cluster-1"] + } +} +``` ## Variables | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [project_id](variables.tf#L80) | GKE hub project ID. | string | ✓ | | +| [project_id](variables.tf#L116) | 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 configure fleet features. | object({…}) | | {} | -| [workload_identity_clusters](variables.tf#L85) | Clusters that will use Fleet Workload Identity. | list(string) | | [] | +| [fleet_default_member_config](variables.tf#L80) | Fleet default member config. | object({…}) | | null | +| [location](variables.tf#L109) | GKE hub location, will also be used for the membership location. | string | | null | +| [workload_identity_clusters](variables.tf#L121) | Clusters that will use Fleet Workload Identity. | list(string) | | [] | ## Outputs diff --git a/modules/gke-hub/main.tf b/modules/gke-hub/main.tf index 740890d6b..57c3fe439 100644 --- a/modules/gke-hub/main.tf +++ b/modules/gke-hub/main.tf @@ -38,6 +38,7 @@ resource "google_gke_hub_membership" "default" { provider = google-beta for_each = var.clusters project = var.project_id + location = var.location membership_id = each.key endpoint { gke_cluster { @@ -68,15 +69,57 @@ resource "google_gke_hub_feature" "default" { } } } + dynamic "fleet_default_member_config" { + for_each = var.fleet_default_member_config != null ? { 1 = 1 } : {} + content { + dynamic "mesh" { + for_each = var.fleet_default_member_config.mesh != null ? { 1 = 1 } : {} + content { + management = try(mesh.value.management, "MANAGEMENT_AUTOMATIC") + } + } + + dynamic "configmanagement" { + for_each = var.fleet_default_member_config.configmanagement != null ? { 1 = 1 } : {} + content { + version = configmanagement.value.version + + dynamic "config_sync" { + for_each = configmanagement.value.config_sync != null ? { 1 = 1 } : {} + content { + prevent_drift = config_sync.value.prevent_drift + source_format = config_sync.value.source_format + enabled = config_sync.value.enabled + + dynamic "git" { + for_each = config_sync.value.git != null ? { 1 = 1 } : {} + content { + gcp_service_account_email = git.value.gcp_service_account_email + https_proxy = git.value.https_proxy + policy_dir = git.value.policy_dir + secret_type = git.value.secret_type + sync_branch = git.value.sync_branch + sync_repo = git.value.sync_repo + sync_rev = git.value.sync_rev + sync_wait_secs = git.value.sync_wait_secs + } + } + } + } + } + } + } + } } resource "google_gke_hub_feature_membership" "servicemesh" { - provider = google-beta - for_each = var.features.servicemesh ? var.clusters : {} - project = var.project_id - location = "global" - feature = google_gke_hub_feature.default["servicemesh"].name - membership = google_gke_hub_membership.default[each.key].membership_id + provider = google-beta + for_each = var.features.servicemesh ? var.clusters : {} + project = var.project_id + location = "global" + feature = google_gke_hub_feature.default["servicemesh"].name + membership = google_gke_hub_membership.default[each.key].membership_id + membership_location = var.location mesh { management = "MANAGEMENT_AUTOMATIC" @@ -84,12 +127,13 @@ resource "google_gke_hub_feature_membership" "servicemesh" { } resource "google_gke_hub_feature_membership" "default" { - provider = google-beta - for_each = local.cluster_cm_config - project = var.project_id - location = "global" - feature = google_gke_hub_feature.default["configmanagement"].name - membership = google_gke_hub_membership.default[each.key].membership_id + provider = google-beta + for_each = local.cluster_cm_config + project = var.project_id + location = "global" + feature = google_gke_hub_feature.default["configmanagement"].name + membership = google_gke_hub_membership.default[each.key].membership_id + membership_location = var.location configmanagement { version = each.value.version diff --git a/modules/gke-hub/variables.tf b/modules/gke-hub/variables.tf index 8f31d32b6..8149c8466 100644 --- a/modules/gke-hub/variables.tf +++ b/modules/gke-hub/variables.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * Copyright 2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,6 +77,42 @@ variable "features" { nullable = false } +variable "fleet_default_member_config" { + description = "Fleet default member config." + type = object({ + mesh = optional(object({ + management = optional(string, "MANAGEMENT_AUTOMATIC") + })) + configmanagement = optional(object({ + version = optional(string) + config_sync = optional(object({ + prevent_drift = optional(bool) + source_format = optional(string, "hierarchy") + enabled = optional(bool) + git = optional(object({ + gcp_service_account_email = optional(string) + https_proxy = optional(string) + policy_dir = optional(string) + secret_type = optional(string, "none") + sync_branch = optional(string) + sync_repo = optional(string) + sync_rev = optional(string) + sync_wait_secs = optional(number) + })) + })) + })) + }) + default = null + nullable = true +} + +variable "location" { + description = "GKE hub location, will also be used for the membership location." + type = string + default = null + nullable = true +} + variable "project_id" { description = "GKE hub project ID." type = string diff --git a/tests/modules/gke_hub/examples/full.yaml b/tests/modules/gke_hub/examples/full.yaml index 586bb815c..903069b1a 100644 --- a/tests/modules/gke_hub/examples/full.yaml +++ b/tests/modules/gke_hub/examples/full.yaml @@ -72,6 +72,7 @@ values: enable_shielded_nodes: false enable_tpu: false fleet: [] + in_transit_encryption_config: null initial_node_count: 1 location: europe-west1 logging_config: @@ -96,6 +97,7 @@ values: managed_prometheus: - enabled: true name: cluster-1 + network_performance_config: [] network_policy: [] node_config: - advanced_machine_features: [] @@ -124,6 +126,14 @@ values: storage_pools: null tags: null taint: [] + node_pool_auto_config: + - linux_node_config: + - {} + network_tags: + - tags: [] + node_kubelet_config: + - insecure_kubelet_readonly_port_enabled: 'TRUE' + resource_manager_tags: null node_pool_defaults: - node_config_defaults: - containerd_config: [] @@ -192,7 +202,7 @@ values: feature: configmanagement location: global membership: cluster-1 - membership_location: null + membership_location: europe-west1 mesh: [] policycontroller: [] project: gkehub-test @@ -206,7 +216,7 @@ values: - gke_cluster: - {} labels: null - location: global + location: europe-west1 membership_id: cluster-1 project: gkehub-test terraform_labels: @@ -321,6 +331,7 @@ values: name: network network_firewall_policy_enforcement_order: AFTER_CLASSIC_FIREWALL network_profile: null + params: [] project: gkehub-test routing_mode: GLOBAL timeouts: null