Refactor GKE nodepool and blueprints (#875)

* first shot, untested

* example tests working

* module tests

* work on gke blueprints

* multitenant fleet doc examples

* fix gke hub doc examples

* blueprint tests

* move master range to vpc config

* fast stage 3 gke test

* tfdoc

* bump provider versions

* and bump provider again to latest
This commit is contained in:
Ludovico Magnocavallo
2022-10-12 12:59:36 +02:00
committed by GitHub
parent bb4aacd152
commit e8056577ce
116 changed files with 1254 additions and 1404 deletions

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -88,24 +88,24 @@ module "cluster" {
name = "${local.prefix}cluster"
location = var.zone
vpc_config = {
network = module.vpc.self_link
subnetwork = module.vpc.subnet_self_links["${var.region}/subnet"]
master_ipv4_cidr_block = var.master_cidr_block
network = module.vpc.self_link
subnetwork = module.vpc.subnet_self_links["${var.region}/subnet"]
}
private_cluster_config = {
enable_private_endpoint = false
master_ipv4_cidr_block = var.master_cidr_block
master_global_access = false
}
}
module "cluster_nodepool" {
source = "../../../modules/gke-nodepool"
project_id = module.project.project_id
cluster_name = module.cluster.name
location = var.zone
name = "nodepool"
node_service_account_create = true
initial_node_count = 3
source = "../../../modules/gke-nodepool"
project_id = module.project.project_id
cluster_name = module.cluster.name
location = var.zone
name = "nodepool"
service_account = {}
node_count = { initial = 3 }
}
module "kms" {

View File

@@ -1,6 +1,6 @@
# Multi-cluster mesh on GKE (fleet API)
The following blueprint shows how to create a multi-cluster mesh for two private clusters on GKE. Anthos Service Mesh with automatic control plane management is set up for clusters using the Fleet API. This can only be done if the clusters are in a single project and in the same VPC. In this particular case both clusters having being deployed to different subnets in a shared VPC.
The following blueprint shows how to create a multi-cluster mesh for two private clusters on GKE. Anthos Service Mesh with automatic control plane management is set up for clusters using the Fleet API. This can only be done if the clusters are in a single project and in the same VPC. In this particular case both clusters having being deployed to different subnets in a shared VPC.
The diagram below depicts the architecture of the blueprint.
@@ -39,14 +39,26 @@ Once terraform completes do the following:
ansible-playbook -v playbook.yaml
## Testing the blueprint
The last two commands executed with Ansible Send requests from a sleep pod to the hello-world service from both clusters. If you see in the output of those two commands responses from alternative versions, everything works as expected.
Once done testing, you can clean up resources by running `terraform destroy`.
<!-- TFDOC OPTS files:1 -->
<!-- BEGIN TFDOC -->
## Files
| name | description | modules | resources |
|---|---|---|---|
| [ansible.tf](./ansible.tf) | Ansible generated files. | | <code>local_file</code> |
| [gke.tf](./gke.tf) | GKE cluster and hub resources. | <code>gke-cluster</code> · <code>gke-hub</code> · <code>gke-nodepool</code> | |
| [main.tf](./main.tf) | Project resources. | <code>project</code> | |
| [variables.tf](./variables.tf) | Module variables. | | |
| [vm.tf](./vm.tf) | Management server. | <code>compute-vm</code> | |
| [vpc.tf](./vpc.tf) | Networking resources. | <code>net-cloudnat</code> · <code>net-vpc</code> · <code>net-vpc-firewall</code> | |
## Variables
| name | description | type | required | default |

View File

@@ -0,0 +1,38 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
# tfdoc:file:description Ansible generated files.
resource "local_file" "vars_file" {
content = templatefile("${path.module}/templates/vars.yaml.tpl", {
istio_version = var.istio_version
region = var.region
clusters = keys(var.clusters_config)
service_account_email = module.mgmt_server.service_account_email
project_id = module.fleet_project.project_id
})
filename = "${path.module}/ansible/vars/vars.yaml"
file_permission = "0666"
}
resource "local_file" "gssh_file" {
content = templatefile("${path.module}/templates/gssh.sh.tpl", {
project_id = var.mgmt_project_id
zone = var.mgmt_server_config.zone
})
filename = "${path.module}/ansible/gssh.sh"
file_permission = "0777"
}

View File

@@ -0,0 +1,73 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
# tfdoc:file:description GKE cluster and hub resources.
module "clusters" {
for_each = var.clusters_config
source = "../../../modules/gke-cluster"
project_id = module.fleet_project.project_id
name = each.key
location = var.region
vpc_config = {
network = module.svpc.self_link
subnetwork = module.svpc.subnet_self_links["${var.region}/subnet-${each.key}"]
master_authorized_ranges = merge({
mgmt : var.mgmt_subnet_cidr_block
},
{ for key, config in var.clusters_config :
"pods-${key}" => config.pods_cidr_block if key != each.key
})
master_ipv4_cidr_block = each.value.master_cidr_block
}
private_cluster_config = {
enable_private_endpoint = true
master_global_access = true
}
release_channel = "REGULAR"
labels = {
mesh_id = "proj-${module.fleet_project.number}"
}
}
module "cluster_nodepools" {
for_each = var.clusters_config
source = "../../../modules/gke-nodepool"
project_id = module.fleet_project.project_id
cluster_name = module.clusters[each.key].name
location = var.region
name = "nodepool-${each.key}"
node_count = { initial = 1 }
service_account = {}
tags = ["${each.key}-node"]
}
module "hub" {
source = "../../../modules/gke-hub"
project_id = module.fleet_project.project_id
clusters = { for k, v in module.clusters : k => v.id }
features = {
appdevexperience = false
configmanagement = false
identityservice = false
multiclusteringress = null
servicemesh = true
multiclusterservicediscovery = false
}
depends_on = [
module.fleet_project
]
}

View File

@@ -14,8 +14,12 @@
* limitations under the License.
*/
# tfdoc:file:description Project resources.
locals {
np_service_account_iam_email = [for k, v in module.cluster_nodepools : v.service_account_iam_email]
np_service_account_iam_email = [
for k, v in module.cluster_nodepools : v.service_account_iam_email
]
}
module "host_project" {
@@ -90,170 +94,3 @@ module "fleet_project" {
disable_dependent_services = true
}
}
module "svpc" {
source = "../../../modules/net-vpc"
project_id = module.host_project.project_id
name = "svpc"
mtu = 1500
subnets = concat([for key, config in var.clusters_config : {
ip_cidr_range = config.subnet_cidr_block
name = "subnet-${key}"
region = var.region
secondary_ip_range = {
pods = config.pods_cidr_block
services = config.services_cidr_block
}
}], [{
ip_cidr_range = var.mgmt_subnet_cidr_block
name = "subnet-mgmt"
region = var.mgmt_server_config.region
secondary_ip_range = null
}])
}
module "mgmt_server" {
source = "../../../modules/compute-vm"
project_id = module.mgmt_project.project_id
zone = var.mgmt_server_config.zone
name = "mgmt"
instance_type = var.mgmt_server_config.instance_type
network_interfaces = [{
network = module.svpc.self_link
subnetwork = module.svpc.subnet_self_links["${var.mgmt_server_config.region}/subnet-mgmt"]
nat = false
addresses = null
}]
service_account_create = true
boot_disk = {
image = var.mgmt_server_config.image
type = var.mgmt_server_config.disk_type
size = var.mgmt_server_config.disk_size
}
}
module "clusters" {
for_each = var.clusters_config
source = "../../../modules/gke-cluster"
project_id = module.fleet_project.project_id
name = each.key
location = var.region
vpc_config = {
network = module.svpc.self_link
subnetwork = module.svpc.subnet_self_links["${var.region}/subnet-${each.key}"]
master_authorized_ranges = merge({
mgmt : var.mgmt_subnet_cidr_block
},
{ for key, config in var.clusters_config :
"pods-${key}" => config.pods_cidr_block if key != each.key
})
}
private_cluster_config = {
enable_private_endpoint = true
master_ipv4_cidr_block = each.value.master_cidr_block
master_global_access = true
}
release_channel = "REGULAR"
labels = {
mesh_id = "proj-${module.fleet_project.number}"
}
}
module "cluster_nodepools" {
for_each = var.clusters_config
source = "../../../modules/gke-nodepool"
project_id = module.fleet_project.project_id
cluster_name = module.clusters[each.key].name
location = var.region
name = "nodepool-${each.key}"
node_service_account_create = true
initial_node_count = 1
node_machine_type = "e2-standard-4"
node_tags = ["${each.key}-node"]
}
module "firewall" {
source = "../../../modules/net-vpc-firewall"
project_id = module.host_project.project_id
network = module.svpc.name
custom_rules = merge({ allow-mesh = {
description = "Allow "
direction = "INGRESS"
action = "allow"
sources = []
ranges = [for k, v in var.clusters_config : v.pods_cidr_block]
targets = [for k, v in var.clusters_config : "${k}-node"]
use_service_accounts = false
rules = [{ protocol = "tcp", ports = null },
{ protocol = "udp", ports = null },
{ protocol = "icmp", ports = null },
{ protocol = "esp", ports = null },
{ protocol = "ah", ports = null },
{ protocol = "sctp", ports = null }]
extra_attributes = {
priority = 900
}
} },
{ for k, v in var.clusters_config : "allow-${k}-istio" => {
description = "Allow "
direction = "INGRESS"
action = "allow"
sources = []
ranges = [v.master_cidr_block]
targets = ["${k}-node"]
use_service_accounts = false
rules = [{ protocol = "tcp", ports = [8080, 15014, 15017] }]
extra_attributes = {
priority = 1000
}
}
}
)
}
module "nat" {
source = "../../../modules/net-cloudnat"
project_id = module.host_project.project_id
region = var.region
name = "nat"
router_create = true
router_network = module.svpc.name
}
module "hub" {
source = "../../../modules/gke-hub"
project_id = module.fleet_project.project_id
clusters = { for k, v in module.clusters : k => v.id }
features = {
appdevexperience = false
configmanagement = false
identityservice = false
multiclusteringress = null
servicemesh = true
multiclusterservicediscovery = false
}
depends_on = [
module.fleet_project
]
}
resource "local_file" "vars_file" {
content = templatefile("${path.module}/templates/vars.yaml.tpl", {
istio_version = var.istio_version
region = var.region
clusters = keys(var.clusters_config)
service_account_email = module.mgmt_server.service_account_email
project_id = module.fleet_project.project_id
})
filename = "${path.module}/ansible/vars/vars.yaml"
file_permission = "0666"
}
resource "local_file" "gssh_file" {
content = templatefile("${path.module}/templates/gssh.sh.tpl", {
project_id = var.mgmt_project_id
zone = var.mgmt_server_config.zone
})
filename = "${path.module}/ansible/gssh.sh"
file_permission = "0777"
}

View File

@@ -0,0 +1,38 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
# tfdoc:file:description Management server.
module "mgmt_server" {
source = "../../../modules/compute-vm"
project_id = module.mgmt_project.project_id
zone = var.mgmt_server_config.zone
name = "mgmt"
instance_type = var.mgmt_server_config.instance_type
network_interfaces = [{
network = module.svpc.self_link
subnetwork = module.svpc.subnet_self_links["${var.mgmt_server_config.region}/subnet-mgmt"]
nat = false
addresses = null
}]
service_account_create = true
boot_disk = {
image = var.mgmt_server_config.image
type = var.mgmt_server_config.disk_type
size = var.mgmt_server_config.disk_size
}
}

View File

@@ -0,0 +1,87 @@
/**
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
# tfdoc:file:description Networking resources.
module "svpc" {
source = "../../../modules/net-vpc"
project_id = module.host_project.project_id
name = "svpc"
mtu = 1500
subnets = concat([for key, config in var.clusters_config : {
ip_cidr_range = config.subnet_cidr_block
name = "subnet-${key}"
region = var.region
secondary_ip_range = {
pods = config.pods_cidr_block
services = config.services_cidr_block
}
}], [{
ip_cidr_range = var.mgmt_subnet_cidr_block
name = "subnet-mgmt"
region = var.mgmt_server_config.region
secondary_ip_range = null
}])
}
module "firewall" {
source = "../../../modules/net-vpc-firewall"
project_id = module.host_project.project_id
network = module.svpc.name
custom_rules = merge({ allow-mesh = {
description = "Allow "
direction = "INGRESS"
action = "allow"
sources = []
ranges = [for k, v in var.clusters_config : v.pods_cidr_block]
targets = [for k, v in var.clusters_config : "${k}-node"]
use_service_accounts = false
rules = [{ protocol = "tcp", ports = null },
{ protocol = "udp", ports = null },
{ protocol = "icmp", ports = null },
{ protocol = "esp", ports = null },
{ protocol = "ah", ports = null },
{ protocol = "sctp", ports = null }]
extra_attributes = {
priority = 900
}
} },
{ for k, v in var.clusters_config : "allow-${k}-istio" => {
description = "Allow "
direction = "INGRESS"
action = "allow"
sources = []
ranges = [v.master_cidr_block]
targets = ["${k}-node"]
use_service_accounts = false
rules = [{ protocol = "tcp", ports = [8080, 15014, 15017] }]
extra_attributes = {
priority = 1000
}
}
}
)
}
module "nat" {
source = "../../../modules/net-cloudnat"
project_id = module.host_project.project_id
region = var.region
name = "nat"
router_create = true
router_network = module.svpc.name
}

View File

@@ -41,21 +41,28 @@ The overall architecture is based on the following design decisions:
## Basic usage
The following example shows how to deploy a single cluster and a single node pool
The following example shows how to deploy two clusters and one node pool for each
```hcl
module "gke" {
locals {
cluster_defaults = {
private_cluster_config = {
enable_private_endpoint = true
master_global_access = true
}
}
subnet_self_links = {
ew1 = "projects/prj-host/regions/europe-west1/subnetworks/gke-0"
ew3 = "projects/prj-host/regions/europe-west3/subnetworks/gke-0"
}
}
module "gke-fleet" {
source = "./fabric/blueprints/gke/multitenant-fleet/"
project_id = var.project_id
billing_account_id = var.billing_account_id
folder_id = var.folder_id
prefix = "myprefix"
vpc_config = {
host_project_id = "my-host-project-id"
vpc_self_link = "projects/my-host-project-id/global/networks/my-network"
}
authenticator_security_group = "gke-rbac-base@example.com"
group_iam = {
"gke-admin@example.com" = [
"roles/container.admin"
@@ -66,129 +73,52 @@ module "gke" {
"cicd@my-cicd-project.iam.gserviceaccount.com"
]
}
clusters = {
mycluster = {
cluster_autoscaling = null
description = "My cluster"
dns_domain = null
location = "europe-west1"
labels = {}
net = {
master_range = "172.17.16.0/28"
pods = "pods"
services = "services"
subnet = "projects/my-host-project-id/regions/europe-west1/subnetworks/mycluster-subnet"
cluster-0 = {
location = "europe-west1"
private_cluster_config = local.cluster_defaults.private_cluster_config
vpc_config = {
subnetwork = local.subnet_self_links.ew1
master_ipv4_cidr_block = "172.16.10.0/28"
}
}
cluster-1 = {
location = "europe-west3"
private_cluster_config = local.cluster_defaults.private_cluster_config
vpc_config = {
subnetwork = local.subnet_self_links.ew3
master_ipv4_cidr_block = "172.16.20.0/28"
}
overrides = null
}
}
nodepools = {
mycluster = {
mynodepool = {
initial_node_count = 1
node_count = 1
node_type = "n2-standard-4"
overrides = null
spot = false
cluster-0 = {
nodepool-0 = {
node_config = {
disk_type = "pd-balanced"
machine_type = "n2-standard-4"
spot = true
}
}
}
cluster-1 = {
nodepool-0 = {
node_config = {
disk_type = "pd-balanced"
machine_type = "n2-standard-4"
}
}
}
}
}
# tftest modules=5 resources=26
```
## Creating Multiple Clusters
The following example shows how to deploy two clusters with different configurations.
The first cluster `cluster-euw1` defines the mandatory configuration parameters (description, location, network setup) and inherits the some defaults from the `cluster_defaults` and `nodepool_deaults` variables. These two variables are used whenever the `override` key of the `clusters` and `nodepools` variables are set to `null`.
On the other hand, the second cluster (`cluster-euw3`) defines its own configuration by providing a value to the `overrides` key.
```hcl
module "gke" {
source = "./fabric/blueprints/gke/multitenant-fleet/"
project_id = var.project_id
billing_account_id = var.billing_account_id
folder_id = var.folder_id
prefix = "myprefix"
vpc_config = {
host_project_id = "my-host-project-id"
vpc_self_link = "projects/my-host-project-id/global/networks/my-network"
}
clusters = {
cluster-euw1 = {
cluster_autoscaling = null
description = "Cluster for europ-west1"
dns_domain = null
location = "europe-west1"
labels = {}
net = {
master_range = "172.17.16.0/28"
pods = "pods"
services = "services"
subnet = "projects/my-host-project-id/regions/europe-west1/subnetworks/euw1-subnet"
}
overrides = null
}
cluster-euw3 = {
cluster_autoscaling = null
description = "Cluster for europe-west3"
dns_domain = null
location = "europe-west3"
labels = {}
net = {
master_range = "172.17.17.0/28"
pods = "pods"
services = "services"
subnet = "projects/my-host-project-id/regions/europe-west3/subnetworks/euw3-subnet"
}
overrides = {
cloudrun_config = false
database_encryption_key = null
gcp_filestore_csi_driver_config = true
master_authorized_ranges = {
rfc1918_1 = "10.0.0.0/8"
}
max_pods_per_node = 64
pod_security_policy = true
release_channel = "STABLE"
vertical_pod_autoscaling = false
}
}
}
nodepools = {
cluster-euw1 = {
pool-euw1 = {
initial_node_count = 1
node_count = 1
node_type = "n2-standard-4"
overrides = null
spot = false
}
}
cluster-euw3 = {
pool-euw3 = {
initial_node_count = 1
node_count = 1
node_type = "n2-standard-4"
overrides = {
image_type = "UBUNTU_CONTAINERD"
max_pods_per_node = 64
node_locations = []
node_tags = []
node_taints = []
}
spot = true
}
}
vpc_self_link = "projects/prj-host/global/networks/prod-0"
}
}
# tftest modules=7 resources=28
# tftest modules=7 resources=26
```
## Multiple clusters with GKE Fleet
## GKE Fleet
This example deploys two clusters and configures several GKE Fleet features:
@@ -198,72 +128,57 @@ This example deploys two clusters and configures several GKE Fleet features:
- The two clusters are configured to use the `default` Config Management template.
```hcl
locals {
subnet_self_links = {
ew1 = "projects/prj-host/regions/europe-west1/subnetworks/gke-0"
ew3 = "projects/prj-host/regions/europe-west3/subnetworks/gke-0"
}
}
module "gke" {
source = "./fabric/blueprints/gke/multitenant-fleet/"
project_id = var.project_id
billing_account_id = var.billing_account_id
folder_id = var.folder_id
prefix = "myprefix"
vpc_config = {
host_project_id = "my-host-project-id"
vpc_self_link = "projects/my-host-project-id/global/networks/my-network"
}
clusters = {
cluster-euw1 = {
cluster_autoscaling = null
description = "Cluster for europe-west1"
dns_domain = null
location = "europe-west1"
labels = {}
net = {
master_range = "172.17.16.0/28"
pods = "pods"
services = "services"
subnet = "projects/my-host-project-id/regions/europe-west1/subnetworks/euw1-subnet"
cluster-0 = {
location = "europe-west1"
vpc_config = {
subnetwork = local.subnet_self_links.ew1
}
overrides = null
}
cluster-euw3 = {
cluster_autoscaling = null
description = "Cluster for europe-west3"
dns_domain = null
location = "europe-west3"
labels = {}
net = {
master_range = "172.17.17.0/28"
pods = "pods"
services = "services"
subnet = "projects/my-host-project-id/regions/europe-west3/subnetworks/euw3-subnet"
cluster-1 = {
location = "europe-west3"
vpc_config = {
subnetwork = local.subnet_self_links.ew3
}
overrides = null
}
}
nodepools = {
cluster-euw1 = {
pool-euw1 = {
initial_node_count = 1
node_count = 1
node_type = "n2-standard-4"
overrides = null
spot = false
cluster-0 = {
nodepool-0 = {
node_config = {
disk_type = "pd-balanced"
machine_type = "n2-standard-4"
spot = true
}
}
}
cluster-euw3 = {
pool-euw3 = {
initial_node_count = 1
node_count = 1
node_type = "n2-standard-4"
overrides = null
spot = true
cluster-1 = {
nodepool-0 = {
node_config = {
disk_type = "pd-balanced"
machine_type = "n2-standard-4"
}
}
}
}
fleet_features = {
appdevexperience = false
configmanagement = true
identityservice = true
multiclusteringress = "cluster-euw1"
multiclusteringress = "cluster-0"
multiclusterservicediscovery = true
servicemesh = true
}
@@ -301,58 +216,57 @@ module "gke" {
}
}
fleet_configmanagement_clusters = {
default = ["cluster-euw1", "cluster-euw3"]
default = ["cluster-0", "cluster-1"]
}
vpc_config = {
host_project_id = "my-host-project-id"
vpc_self_link = "projects/prj-host/global/networks/prod-0"
}
}
# tftest modules=8 resources=39
# tftest modules=8 resources=35
```
<!-- TFDOC OPTS files:1 show_extra:1 -->
<!-- TFDOC OPTS files:1 -->
<!-- BEGIN TFDOC -->
## Files
| name | description | modules |
|---|---|---|
| [gke-clusters.tf](./gke-clusters.tf) | None | <code>gke-cluster</code> |
| [gke-hub.tf](./gke-hub.tf) | None | <code>gke-hub</code> |
| [gke-nodepools.tf](./gke-nodepools.tf) | None | <code>gke-nodepool</code> |
| [main.tf](./main.tf) | Module-level locals and resources. | <code>bigquery-dataset</code> · <code>project</code> |
| [gke-clusters.tf](./gke-clusters.tf) | GKE clusters. | <code>gke-cluster</code> |
| [gke-hub.tf](./gke-hub.tf) | GKE hub configuration. | <code>gke-hub</code> |
| [gke-nodepools.tf](./gke-nodepools.tf) | GKE nodepools. | <code>gke-nodepool</code> |
| [main.tf](./main.tf) | Project and usage dataset. | <code>bigquery-dataset</code> · <code>project</code> |
| [outputs.tf](./outputs.tf) | Output variables. | |
| [variables.tf](./variables.tf) | Module variables. | |
## Variables
| name | description | type | required | default | producer |
|---|---|:---:|:---:|:---:|:---:|
| [billing_account_id](variables.tf#L23) | Billing account id. | <code>string</code> | ✓ | | |
| [clusters](variables.tf#L57) | | <code title="map&#40;object&#40;&#123;&#10; cluster_autoscaling &#61; object&#40;&#123;&#10; cpu_min &#61; number&#10; cpu_max &#61; number&#10; memory_min &#61; number&#10; memory_max &#61; number&#10; &#125;&#41;&#10; description &#61; string&#10; dns_domain &#61; string&#10; labels &#61; map&#40;string&#41;&#10; location &#61; string&#10; net &#61; object&#40;&#123;&#10; master_range &#61; string&#10; pods &#61; string&#10; services &#61; string&#10; subnet &#61; string&#10; &#125;&#41;&#10; overrides &#61; object&#40;&#123;&#10; cloudrun_config &#61; bool&#10; database_encryption_key &#61; string&#10; master_authorized_ranges &#61; map&#40;string&#41;&#10; max_pods_per_node &#61; number&#10; pod_security_policy &#61; bool&#10; release_channel &#61; string&#10; vertical_pod_autoscaling &#61; bool&#10; gcp_filestore_csi_driver_config &#61; bool&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | ✓ | | |
| [folder_id](variables.tf#L158) | Folder used for the GKE project in folders/nnnnnnnnnnn format. | <code>string</code> | ✓ | | |
| [nodepools](variables.tf#L201) | | <code title="map&#40;map&#40;object&#40;&#123;&#10; node_count &#61; number&#10; node_type &#61; string&#10; initial_node_count &#61; number&#10; overrides &#61; object&#40;&#123;&#10; image_type &#61; string&#10; max_pods_per_node &#61; number&#10; node_locations &#61; list&#40;string&#41;&#10; node_tags &#61; list&#40;string&#41;&#10; node_taints &#61; list&#40;string&#41;&#10; &#125;&#41;&#10; spot &#61; bool&#10;&#125;&#41;&#41;&#41;">map&#40;map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;&#41;</code> | ✓ | | |
| [prefix](variables.tf#L231) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | | |
| [project_id](variables.tf#L236) | ID of the project that will contain all the clusters. | <code>string</code> | | | |
| [vpc_config](variables.tf#L248) | Shared VPC project and VPC details. | <code title="object&#40;&#123;&#10; host_project_id &#61; string&#10; vpc_self_link &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | |
| [authenticator_security_group](variables.tf#L17) | Optional group used for Groups for GKE. | <code>string</code> | | <code>null</code> | |
| [cluster_defaults](variables.tf#L28) | Default values for optional cluster configurations. | <code title="object&#40;&#123;&#10; cloudrun_config &#61; bool&#10; database_encryption_key &#61; string&#10; master_authorized_ranges &#61; map&#40;string&#41;&#10; max_pods_per_node &#61; number&#10; pod_security_policy &#61; bool&#10; release_channel &#61; string&#10; vertical_pod_autoscaling &#61; bool&#10; gcp_filestore_csi_driver_config &#61; bool&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; cloudrun_config &#61; false&#10; database_encryption_key &#61; null&#10; master_authorized_ranges &#61; &#123;&#10; rfc1918_1 &#61; &#34;10.0.0.0&#47;8&#34;&#10; rfc1918_2 &#61; &#34;172.16.0.0&#47;12&#34;&#10; rfc1918_3 &#61; &#34;192.168.0.0&#47;16&#34;&#10; &#125;&#10; max_pods_per_node &#61; 110&#10; pod_security_policy &#61; false&#10; release_channel &#61; &#34;STABLE&#34;&#10; vertical_pod_autoscaling &#61; false&#10; gcp_filestore_csi_driver_config &#61; false&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [dns_domain](variables.tf#L90) | Domain name used for clusters, prefixed by each cluster name. Leave null to disable Cloud DNS for GKE. | <code>string</code> | | <code>null</code> | |
| [fleet_configmanagement_clusters](variables.tf#L96) | Config management features enabled on specific sets of member clusters, in config name => [cluster name] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [fleet_configmanagement_templates](variables.tf#L103) | Sets of config management configurations that can be applied to member clusters, in config name => {options} format. | <code title="map&#40;object&#40;&#123;&#10; binauthz &#61; bool&#10; config_sync &#61; object&#40;&#123;&#10; git &#61; object&#40;&#123;&#10; gcp_service_account_email &#61; string&#10; https_proxy &#61; string&#10; policy_dir &#61; string&#10; secret_type &#61; string&#10; sync_branch &#61; string&#10; sync_repo &#61; string&#10; sync_rev &#61; string&#10; sync_wait_secs &#61; number&#10; &#125;&#41;&#10; prevent_drift &#61; string&#10; source_format &#61; string&#10; &#125;&#41;&#10; hierarchy_controller &#61; object&#40;&#123;&#10; enable_hierarchical_resource_quota &#61; bool&#10; enable_pod_tree_labels &#61; bool&#10; &#125;&#41;&#10; policy_controller &#61; object&#40;&#123;&#10; audit_interval_seconds &#61; number&#10; exemptable_namespaces &#61; list&#40;string&#41;&#10; log_denies_enabled &#61; bool&#10; referential_rules_enabled &#61; bool&#10; template_library_installed &#61; bool&#10; &#125;&#41;&#10; version &#61; string&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [fleet_features](variables.tf#L138) | Enable and configue fleet features. Set to null to disable GKE Hub if fleet workload identity is not used. | <code title="object&#40;&#123;&#10; appdevexperience &#61; bool&#10; configmanagement &#61; bool&#10; identityservice &#61; bool&#10; multiclusteringress &#61; string&#10; multiclusterservicediscovery &#61; bool&#10; servicemesh &#61; bool&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [fleet_workload_identity](variables.tf#L151) | Use Fleet Workload Identity for clusters. Enables GKE Hub if set to true. | <code>bool</code> | | <code>false</code> | |
| [group_iam](variables.tf#L163) | Project-level IAM bindings for groups. Use group emails as keys, list of roles as values. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [iam](variables.tf#L170) | Project-level authoritative IAM bindings for users and service accounts in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [labels](variables.tf#L177) | Project-level labels. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | |
| [nodepool_defaults](variables.tf#L183) | | <code title="object&#40;&#123;&#10; image_type &#61; string&#10; max_pods_per_node &#61; number&#10; node_locations &#61; list&#40;string&#41;&#10; node_tags &#61; list&#40;string&#41;&#10; node_taints &#61; list&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; image_type &#61; &#34;COS_CONTAINERD&#34;&#10; max_pods_per_node &#61; 110&#10; node_locations &#61; null&#10; node_tags &#61; null&#10; node_taints &#61; &#91;&#93;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [peering_config](variables.tf#L218) | Configure peering with the control plane VPC. Requires compute.networks.updatePeering. Set to null if you don't want to update the default peering configuration. | <code title="object&#40;&#123;&#10; export_routes &#61; bool&#10; import_routes &#61; bool&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; export_routes &#61; true&#10; &#47;&#47; TODO&#40;jccb&#41; is there any situation where the control plane VPC would export any routes&#63;&#10; import_routes &#61; false&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [project_services](variables.tf#L241) | Additional project services to enable. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> | |
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [billing_account_id](variables.tf#L17) | Billing account id. | <code>string</code> | ✓ | |
| [folder_id](variables.tf#L129) | Folder used for the GKE project in folders/nnnnnnnnnnn format. | <code>string</code> | ✓ | |
| [prefix](variables.tf#L176) | Prefix used for resources that need unique names. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L181) | ID of the project that will contain all the clusters. | <code>string</code> | ✓ | |
| [vpc_config](variables.tf#L193) | Shared VPC project and VPC details. | <code title="object&#40;&#123;&#10; host_project_id &#61; string&#10; vpc_self_link &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [clusters](variables.tf#L22) | Clusters configuration. Refer to the gke-cluster module for type details. | <code title="map&#40;object&#40;&#123;&#10; cluster_autoscaling &#61; optional&#40;any&#41;&#10; description &#61; optional&#40;string&#41;&#10; enable_addons &#61; optional&#40;any, &#123;&#10; horizontal_pod_autoscaling &#61; true, http_load_balancing &#61; true&#10; &#125;&#41;&#10; enable_features &#61; optional&#40;any, &#123;&#10; workload_identity &#61; true&#10; &#125;&#41;&#10; issue_client_certificate &#61; optional&#40;bool, false&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;&#41;&#10; location &#61; string&#10; logging_config &#61; optional&#40;list&#40;string&#41;, &#91;&#34;SYSTEM_COMPONENTS&#34;&#93;&#41;&#10; maintenance_config &#61; optional&#40;any, &#123;&#10; daily_window_start_time &#61; &#34;03:00&#34;&#10; recurring_window &#61; null&#10; maintenance_exclusion &#61; &#91;&#93;&#10; &#125;&#41;&#10; max_pods_per_node &#61; optional&#40;number, 110&#41;&#10; min_master_version &#61; optional&#40;string&#41;&#10; monitoring_config &#61; optional&#40;list&#40;string&#41;, &#91;&#34;SYSTEM_COMPONENTS&#34;&#93;&#41;&#10; node_locations &#61; optional&#40;list&#40;string&#41;&#41;&#10; private_cluster_config &#61; optional&#40;any&#41;&#10; release_channel &#61; optional&#40;string&#41;&#10; vpc_config &#61; object&#40;&#123;&#10; subnetwork &#61; string&#10; network &#61; optional&#40;string&#41;&#10; secondary_range_blocks &#61; optional&#40;object&#40;&#123;&#10; pods &#61; string&#10; services &#61; string&#10; &#125;&#41;&#41;&#10; secondary_range_names &#61; optional&#40;object&#40;&#123;&#10; pods &#61; string&#10; services &#61; string&#10; &#125;&#41;, &#123; pods &#61; &#34;pods&#34;, services &#61; &#34;services&#34; &#125;&#41;&#10; master_authorized_ranges &#61; optional&#40;map&#40;string&#41;&#41;&#10; master_ipv4_cidr_block &#61; optional&#40;string&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [fleet_configmanagement_clusters](variables.tf#L67) | Config management features enabled on specific sets of member clusters, in config name => [cluster name] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [fleet_configmanagement_templates](variables.tf#L74) | Sets of config management configurations that can be applied to member clusters, in config name => {options} format. | <code title="map&#40;object&#40;&#123;&#10; binauthz &#61; bool&#10; config_sync &#61; object&#40;&#123;&#10; git &#61; object&#40;&#123;&#10; gcp_service_account_email &#61; string&#10; https_proxy &#61; string&#10; policy_dir &#61; string&#10; secret_type &#61; string&#10; sync_branch &#61; string&#10; sync_repo &#61; string&#10; sync_rev &#61; string&#10; sync_wait_secs &#61; number&#10; &#125;&#41;&#10; prevent_drift &#61; string&#10; source_format &#61; string&#10; &#125;&#41;&#10; hierarchy_controller &#61; object&#40;&#123;&#10; enable_hierarchical_resource_quota &#61; bool&#10; enable_pod_tree_labels &#61; bool&#10; &#125;&#41;&#10; policy_controller &#61; object&#40;&#123;&#10; audit_interval_seconds &#61; number&#10; exemptable_namespaces &#61; list&#40;string&#41;&#10; log_denies_enabled &#61; bool&#10; referential_rules_enabled &#61; bool&#10; template_library_installed &#61; bool&#10; &#125;&#41;&#10; version &#61; string&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [fleet_features](variables.tf#L109) | Enable and configue fleet features. Set to null to disable GKE Hub if fleet workload identity is not used. | <code title="object&#40;&#123;&#10; appdevexperience &#61; bool&#10; configmanagement &#61; bool&#10; identityservice &#61; bool&#10; multiclusteringress &#61; string&#10; multiclusterservicediscovery &#61; bool&#10; servicemesh &#61; bool&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [fleet_workload_identity](variables.tf#L122) | Use Fleet Workload Identity for clusters. Enables GKE Hub if set to true. | <code>bool</code> | | <code>false</code> |
| [group_iam](variables.tf#L134) | Project-level IAM bindings for groups. Use group emails as keys, list of roles as values. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam](variables.tf#L141) | Project-level authoritative IAM bindings for users and service accounts in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [labels](variables.tf#L148) | Project-level labels. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [nodepools](variables.tf#L154) | Nodepools configuration. Refer to the gke-nodepool module for type details. | <code title="map&#40;map&#40;object&#40;&#123;&#10; gke_version &#61; optional&#40;string&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; max_pods_per_node &#61; optional&#40;number&#41;&#10; name &#61; optional&#40;string&#41;&#10; node_config &#61; optional&#40;any, &#123; disk_type &#61; &#34;pd-balanced&#34; &#125;&#41;&#10; node_count &#61; optional&#40;map&#40;number&#41;, &#123; initial &#61; 1 &#125;&#41;&#10; node_locations &#61; optional&#40;list&#40;string&#41;&#41;&#10; nodepool_config &#61; optional&#40;any&#41;&#10; pod_range &#61; optional&#40;any&#41;&#10; reservation_affinity &#61; optional&#40;any&#41;&#10; service_account &#61; optional&#40;any&#41;&#10; sole_tenant_nodegroup &#61; optional&#40;string&#41;&#10; tags &#61; optional&#40;list&#40;string&#41;&#41;&#10; taints &#61; optional&#40;list&#40;any&#41;&#41;&#10;&#125;&#41;&#41;&#41;">map&#40;map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [project_services](variables.tf#L186) | Additional project services to enable. | <code>list&#40;string&#41;</code> | | <code>&#91;&#93;</code> |
## Outputs
| name | description | sensitive | consumers |
|---|---|:---:|---|
| [cluster_ids](outputs.tf#L22) | Cluster ids. | | |
| [clusters](outputs.tf#L17) | Cluster resources. | | |
| [project_id](outputs.tf#L29) | GKE project id. | | |
| name | description | sensitive |
|---|---|:---:|
| [cluster_ids](outputs.tf#L22) | Cluster ids. | |
| [clusters](outputs.tf#L17) | Cluster resources. | |
| [project_id](outputs.tf#L29) | GKE project id. | |
<!-- END TFDOC -->

View File

@@ -14,79 +14,30 @@
* limitations under the License.
*/
locals {
clusters = {
for name, config in var.clusters :
name => merge(config, {
overrides = coalesce(config.overrides, var.cluster_defaults)
})
}
}
# tfdoc:file:description GKE clusters.
module "gke-cluster" {
source = "../../../modules/gke-cluster"
for_each = local.clusters
name = each.key
project_id = module.gke-project-0.project_id
description = each.value.description
location = each.value.location
vpc_config = {
network = var.vpc_config.vpc_self_link
subnetwork = each.value.net.subnet
secondary_range_names = {
pods = each.value.net.pods
services = each.value.net.services
}
master_authorized_ranges = each.value.overrides.master_authorized_ranges
}
labels = each.value.labels
enable_addons = {
cloudrun = each.value.overrides.cloudrun_config
config_connector = true
dns_cache = true
gce_persistent_disk_csi_driver = true
gcp_filestore_csi_driver = each.value.overrides.gcp_filestore_csi_driver_config
gke_backup_agent = false
horizontal_pod_autoscaling = true
http_load_balancing = true
}
enable_features = {
cloud_dns = var.dns_domain == null ? null : {
cluster_dns = "CLOUD_DNS"
cluster_dns_scope = "VPC_SCOPE"
cluster_dns_domain = "${each.key}.${var.dns_domain}"
}
database_encryption = (
each.value.overrides.database_encryption_key == null
? null
: {
state = "ENCRYPTED"
key_name = each.value.overrides.database_encryption_key
}
source = "../../../modules/gke-cluster"
for_each = var.clusters
name = each.key
project_id = module.gke-project-0.project_id
cluster_autoscaling = each.value.cluster_autoscaling
description = each.value.description
enable_features = each.value.enable_features
issue_client_certificate = each.value.issue_client_certificate
labels = each.value.labels
location = each.value.location
logging_config = each.value.logging_config
maintenance_config = each.value.maintenance_config
max_pods_per_node = each.value.max_pods_per_node
min_master_version = each.value.min_master_version
monitoring_config = each.value.monitoring_config
node_locations = each.value.node_locations
private_cluster_config = each.value.private_cluster_config
release_channel = each.value.release_channel
vpc_config = merge(each.value.vpc_config, {
network = coalesce(
each.value.vpc_config.network, var.vpc_config.vpc_self_link
)
dataplane_v2 = true
groups_for_rbac = var.authenticator_security_group
intranode_visibility = true
pod_security_policy = each.value.overrides.pod_security_policy
resource_usage_export = {
dataset = module.gke-dataset-resource-usage.dataset_id
}
shielded_nodes = true
vertical_pod_autoscaling = each.value.overrides.vertical_pod_autoscaling
workload_identity = true
}
private_cluster_config = {
enable_private_endpoint = true
master_ipv4_cidr_block = each.value.net.master_range
master_global_access = true
peering_config = var.peering_config == null ? null : {
export_routes = var.peering_config.export_routes
import_routes = var.peering_config.import_routes
project_id = var.vpc_config.host_project_id
}
}
logging_config = ["SYSTEM_COMPONENTS", "WORKLOADS"]
monitoring_config = ["SYSTEM_COMPONENTS", "WORKLOADS"]
max_pods_per_node = each.value.overrides.max_pods_per_node
release_channel = each.value.overrides.release_channel
})
}

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
# tfdoc:file:description GKE hub configuration.
locals {
fleet_enabled = (
var.fleet_features != null || var.fleet_workload_identity

View File

@@ -14,53 +14,38 @@
* limitations under the License.
*/
# tfdoc:file:description GKE nodepools.
locals {
nodepools = merge([
for cluster, nodepools in var.nodepools : {
for nodepool, config in nodepools :
"${cluster}/${nodepool}" => merge(config, {
name = nodepool
cluster = cluster
overrides = coalesce(config.overrides, var.nodepool_defaults)
name = nodepool
cluster = cluster
})
}
]...)
}
module "gke-nodepool" {
source = "../../../modules/gke-nodepool"
for_each = local.nodepools
name = each.value.name
project_id = module.gke-project-0.project_id
cluster_name = module.gke-cluster[each.value.cluster].name
location = module.gke-cluster[each.value.cluster].location
initial_node_count = each.value.initial_node_count
node_machine_type = each.value.node_type
node_spot = each.value.spot
node_count = each.value.node_count
# node_count = (
# each.value.autoscaling_config == null ? each.value.node_count : null
# )
# dynamic "autoscaling_config" {
# for_each = each.value.autoscaling_config == null ? {} : { 1 = 1 }
# content {
# min_node_count = each.value.autoscaling_config.min_node_count
# max_node_count = each.value.autoscaling_config.max_node_count
# }
# }
# overrides
node_locations = each.value.overrides.node_locations
max_pods_per_node = each.value.overrides.max_pods_per_node
node_image_type = each.value.overrides.image_type
node_tags = each.value.overrides.node_tags
node_taints = each.value.overrides.node_taints
management_config = {
auto_repair = true
auto_upgrade = true
}
node_service_account_create = true
source = "../../../modules/gke-nodepool"
for_each = local.nodepools
name = each.value.name
project_id = module.gke-project-0.project_id
cluster_name = module.gke-cluster[each.value.cluster].name
location = module.gke-cluster[each.value.cluster].location
gke_version = each.value.gke_version
labels = each.value.labels
max_pods_per_node = each.value.max_pods_per_node
node_config = each.value.node_config
node_count = each.value.node_count
node_locations = each.value.node_locations
nodepool_config = each.value.nodepool_config
pod_range = each.value.pod_range
reservation_affinity = each.value.reservation_affinity
service_account = each.value.service_account
sole_tenant_nodegroup = each.value.sole_tenant_nodegroup
tags = each.value.tags
taints = each.value.taints
}

View File

@@ -14,6 +14,8 @@
* limitations under the License.
*/
# tfdoc:file:description Project and usage dataset.
module "gke-project-0" {
source = "../../../modules/project"
billing_account = var.billing_account_id

View File

@@ -14,83 +14,54 @@
* limitations under the License.
*/
variable "authenticator_security_group" {
description = "Optional group used for Groups for GKE."
type = string
default = null
}
variable "billing_account_id" {
description = "Billing account id."
type = string
}
variable "cluster_defaults" {
description = "Default values for optional cluster configurations."
type = object({
cloudrun_config = bool
database_encryption_key = string
master_authorized_ranges = map(string)
max_pods_per_node = number
pod_security_policy = bool
release_channel = string
vertical_pod_autoscaling = bool
gcp_filestore_csi_driver_config = bool
})
default = {
# TODO: review defaults
cloudrun_config = false
database_encryption_key = null
master_authorized_ranges = {
rfc1918_1 = "10.0.0.0/8"
rfc1918_2 = "172.16.0.0/12"
rfc1918_3 = "192.168.0.0/16"
}
max_pods_per_node = 110
pod_security_policy = false
release_channel = "STABLE"
vertical_pod_autoscaling = false
gcp_filestore_csi_driver_config = false
}
}
variable "clusters" {
description = ""
description = "Clusters configuration. Refer to the gke-cluster module for type details."
type = map(object({
cluster_autoscaling = object({
cpu_min = number
cpu_max = number
memory_min = number
memory_max = number
cluster_autoscaling = optional(any)
description = optional(string)
enable_addons = optional(any, {
horizontal_pod_autoscaling = true, http_load_balancing = true
})
description = string
dns_domain = string
labels = map(string)
location = string
net = object({
master_range = string
pods = string
services = string
subnet = string
enable_features = optional(any, {
workload_identity = true
})
overrides = object({
cloudrun_config = bool
database_encryption_key = string
# binary_authorization = bool
master_authorized_ranges = map(string)
max_pods_per_node = number
pod_security_policy = bool
release_channel = string
vertical_pod_autoscaling = bool
gcp_filestore_csi_driver_config = bool
issue_client_certificate = optional(bool, false)
labels = optional(map(string))
location = string
logging_config = optional(list(string), ["SYSTEM_COMPONENTS"])
maintenance_config = optional(any, {
daily_window_start_time = "03:00"
recurring_window = null
maintenance_exclusion = []
})
max_pods_per_node = optional(number, 110)
min_master_version = optional(string)
monitoring_config = optional(list(string), ["SYSTEM_COMPONENTS"])
node_locations = optional(list(string))
private_cluster_config = optional(any)
release_channel = optional(string)
vpc_config = object({
subnetwork = string
network = optional(string)
secondary_range_blocks = optional(object({
pods = string
services = string
}))
secondary_range_names = optional(object({
pods = string
services = string
}), { pods = "pods", services = "services" })
master_authorized_ranges = optional(map(string))
master_ipv4_cidr_block = optional(string)
})
}))
}
variable "dns_domain" {
description = "Domain name used for clusters, prefixed by each cluster name. Leave null to disable Cloud DNS for GKE."
type = string
default = null
default = {}
nullable = false
}
variable "fleet_configmanagement_clusters" {
@@ -180,52 +151,26 @@ variable "labels" {
default = {}
}
variable "nodepool_defaults" {
description = ""
type = object({
image_type = string
max_pods_per_node = number
node_locations = list(string)
node_tags = list(string)
node_taints = list(string)
})
default = {
image_type = "COS_CONTAINERD"
max_pods_per_node = 110
node_locations = null
node_tags = null
node_taints = []
}
}
variable "nodepools" {
description = ""
description = "Nodepools configuration. Refer to the gke-nodepool module for type details."
type = map(map(object({
node_count = number
node_type = string
initial_node_count = number
overrides = object({
image_type = string
max_pods_per_node = number
node_locations = list(string)
node_tags = list(string)
node_taints = list(string)
})
spot = bool
gke_version = optional(string)
labels = optional(map(string), {})
max_pods_per_node = optional(number)
name = optional(string)
node_config = optional(any, { disk_type = "pd-balanced" })
node_count = optional(map(number), { initial = 1 })
node_locations = optional(list(string))
nodepool_config = optional(any)
pod_range = optional(any)
reservation_affinity = optional(any)
service_account = optional(any)
sole_tenant_nodegroup = optional(string)
tags = optional(list(string))
taints = optional(list(any))
})))
}
variable "peering_config" {
description = "Configure peering with the control plane VPC. Requires compute.networks.updatePeering. Set to null if you don't want to update the default peering configuration."
type = object({
export_routes = bool
import_routes = bool
})
default = {
export_routes = true
// TODO(jccb) is there any situation where the control plane VPC would export any routes?
import_routes = false
}
default = {}
nullable = false
}
variable "prefix" {

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -247,6 +247,7 @@ module "cluster-1" {
master_authorized_ranges = {
for name, range in var.ip_ranges : name => range
}
master_ipv4_cidr_block = var.private_service_ranges.spoke-2-cluster-1
}
max_pods_per_node = 32
labels = {
@@ -254,7 +255,6 @@ module "cluster-1" {
}
private_cluster_config = {
enable_private_endpoint = true
master_ipv4_cidr_block = var.private_service_ranges.spoke-2-cluster-1
master_global_access = true
peering_config = {
export_routes = true
@@ -264,12 +264,14 @@ module "cluster-1" {
}
module "cluster-1-nodepool-1" {
source = "../../../modules/gke-nodepool"
name = "${local.prefix}nodepool-1"
project_id = module.project.project_id
location = module.cluster-1.location
cluster_name = module.cluster-1.name
node_service_account = module.service-account-gke-node.email
source = "../../../modules/gke-nodepool"
name = "${local.prefix}nodepool-1"
project_id = module.project.project_id
location = module.cluster-1.location
cluster_name = module.cluster-1.name
service_account = {
email = module.service-account-gke-node.email
}
}
# roles assigned via this module use non-authoritative IAM bindings at the

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -207,11 +207,11 @@ module "cluster-1" {
master_authorized_ranges = {
internal-vms = var.ip_ranges.gce
}
master_ipv4_cidr_block = var.private_service_ranges.cluster-1
}
max_pods_per_node = 32
private_cluster_config = {
enable_private_endpoint = true
master_ipv4_cidr_block = var.private_service_ranges.cluster-1
master_global_access = true
}
labels = {
@@ -220,11 +220,11 @@ module "cluster-1" {
}
module "cluster-1-nodepool-1" {
source = "../../../modules/gke-nodepool"
count = var.cluster_create ? 1 : 0
name = "nodepool-1"
project_id = module.project-svc-gke.project_id
location = module.cluster-1.0.location
cluster_name = module.cluster-1.0.name
node_service_account_create = true
source = "../../../modules/gke-nodepool"
count = var.cluster_create ? 1 : 0
name = "nodepool-1"
project_id = module.project-svc-gke.project_id
location = module.cluster-1.0.location
cluster_name = module.cluster-1.0.name
service_account = {}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}

View File

@@ -17,11 +17,11 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 4.32.0" # tftest
version = ">= 4.36.0" # tftest
}
}
}