cloud-foundation-fabric/modules/gke-hub
Ludovico Magnocavallo 6941313c7d
Factories refactor (#1843)
* factories refactor doc

* Adds file schema and filesystem organization

* Update 20231106-factories.md

* move factories out of blueprints and create new factories  README

* align factory in billing-account module

* align factory in dataplex-datascan module

* align factory in billing-account module

* align factory in net-firewall-policy module

* align factory in dns-response-policy module

* align factory in net-vpc-firewall module

* align factory in net-vpc module

* align factory variable names in FAST

* remove decentralized firewall blueprint

* bump terraform version

* bump module versions

* update top-level READMEs

* move project factory to modules

* fix variable names and tests

* tfdoc

* remove changelog link

* add project factory to top-level README

* fix cludrun eventarc diff

* fix README

* fix cludrun eventarc diff

---------

Co-authored-by: Simone Ruffilli <sruffilli@google.com>
2024-02-26 10:16:52 +00:00
..
README.md Add example to FAST GKE stage, streamline GKE Hub module variables and usage (#1977) 2024-01-20 10:06:38 +00:00
main.tf removing deprecated field from gke-hub 2023-03-30 12:47:39 +02:00
outputs.tf Ensure all modules have an `id` output (#1410) 2023-06-02 16:07:22 +02:00
variables.tf Add example to FAST GKE stage, streamline GKE Hub module variables and usage (#1977) 2024-01-20 10:06:38 +00:00
versions.tf Factories refactor (#1843) 2024-02-26 10:16:52 +00:00

README.md

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

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 = {
      rfc1918_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 = {
    configmanagement = true
  }
  configmanagement_templates = {
    default = {
      config_sync = {
        git = {
          policy_dir    = "configsync"
          source_format = "hierarchy"
          sync_branch   = "main"
          sync_repo     = "https://github.com/danielmarzini/configsync-platform-example"
        }
        source_format = "hierarchy"
      }
      hierarchy_controller = {
        enable_hierarchical_resource_quota = true
        enable_pod_tree_labels             = true
      }
      policy_controller = {
        audit_interval_seconds     = 120
        log_denies_enabled         = true
        referential_rules_enabled  = true
        template_library_installed = true
      }
      version = "v1"
    }
  }
  configmanagement_clusters = {
    "default" = ["cluster-1"]
  }
}

# tftest modules=4 resources=18 inventory=full.yaml

Multi-cluster mesh on GKE

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=34

Variables

name description type required default
project_id GKE hub project ID. string
clusters Clusters members of this GKE Hub in name => id format. map(string) {}
configmanagement_clusters Config management features enabled on specific sets of member clusters, in config name => [cluster name] format. map(list(string)) {}
configmanagement_templates Sets of config management configurations that can be applied to member clusters, in config name => {options} format. map(object({…})) {}
features Enable and configure fleet features. object({…}) {}
workload_identity_clusters Clusters that will use Fleet Workload Identity. list(string) []

Outputs

name description sensitive
cluster_ids Fully qualified ids of all clusters.