From f76d8e8f4ad8b7180a44f7d01bd79000683c323f Mon Sep 17 00:00:00 2001 From: Marko Vlahovic Date: Fri, 9 Oct 2020 18:27:21 -0700 Subject: [PATCH] fix: promoting release_channel, database_encryption, workload_identity_config, and enable_shielded_nodes from beta to GA --- README.md | 7 +++ autogen/main/cluster.tf.tmpl | 15 ++---- autogen/main/main.tf.tmpl | 17 +++---- autogen/main/outputs.tf.tmpl | 26 +++++----- autogen/main/variables.tf.tmpl | 49 +++++++++---------- cluster.tf | 44 ++++++++++++++++- .../private_zonal_with_networking/main.tf | 2 +- examples/simple_zonal_with_asm/main.tf | 7 ++- examples/workload_identity/main.tf | 2 +- examples/workload_metadata_config/main.tf | 2 +- main.tf | 8 +++ .../README.md | 2 +- .../cluster.tf | 3 +- .../main.tf | 15 +++--- .../outputs.tf | 26 +++++----- .../variables.tf | 47 +++++++++--------- modules/beta-private-cluster/README.md | 2 +- modules/beta-private-cluster/cluster.tf | 3 +- modules/beta-private-cluster/main.tf | 15 +++--- modules/beta-private-cluster/outputs.tf | 26 +++++----- modules/beta-private-cluster/variables.tf | 47 +++++++++--------- .../README.md | 2 +- .../cluster.tf | 3 +- .../main.tf | 15 +++--- .../outputs.tf | 26 +++++----- .../variables.tf | 47 +++++++++--------- modules/beta-public-cluster/README.md | 2 +- modules/beta-public-cluster/cluster.tf | 3 +- modules/beta-public-cluster/main.tf | 15 +++--- modules/beta-public-cluster/outputs.tf | 26 +++++----- modules/beta-public-cluster/variables.tf | 47 +++++++++--------- .../private-cluster-update-variant/README.md | 7 +++ .../private-cluster-update-variant/cluster.tf | 44 ++++++++++++++++- .../private-cluster-update-variant/main.tf | 8 +++ .../private-cluster-update-variant/outputs.tf | 13 +++++ .../variables.tf | 33 +++++++++++++ modules/private-cluster/README.md | 7 +++ modules/private-cluster/cluster.tf | 44 ++++++++++++++++- modules/private-cluster/main.tf | 8 +++ modules/private-cluster/outputs.tf | 13 +++++ modules/private-cluster/variables.tf | 33 +++++++++++++ outputs.tf | 13 +++++ .../simple_regional/controls/gcloud.rb | 12 +++++ variables.tf | 33 +++++++++++++ 44 files changed, 561 insertions(+), 258 deletions(-) diff --git a/README.md b/README.md index 0a2535ebd9..b9b061dc0f 100644 --- a/README.md +++ b/README.md @@ -107,11 +107,13 @@ Then perform the following commands on the root folder: | cluster\_resource\_labels | The GCE resource labels (a map of key/value pairs) to be applied to the cluster | map(string) | `` | no | | configure\_ip\_masq | Enables the installation of ip masquerading, which is usually no longer required when using aliasied IP addresses. IP masquerading uses a kubectl call, so when you have a private cluster, you will need access to the API server. | string | `"false"` | no | | create\_service\_account | Defines if service account specified to run nodes should be created. | bool | `"true"` | no | +| database\_encryption | Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: "ENCRYPTED"; "DECRYPTED". key_name is the name of a CloudKMS key. | object | `` | no | | default\_max\_pods\_per\_node | The maximum number of pods to schedule per node | string | `"110"` | no | | description | The description of the cluster | string | `""` | no | | disable\_legacy\_metadata\_endpoints | Disable the /0.1/ and /v1beta1/ metadata server endpoints on the node. Changing this value will cause all node pools to be recreated. | bool | `"true"` | no | | enable\_network\_egress\_export | Whether to enable network egress metering for this cluster. If enabled, a daemonset will be created in the cluster to meter network egress traffic. | bool | `"false"` | no | | enable\_resource\_consumption\_export | Whether to enable resource consumption metering on this cluster. When enabled, a table will be created in the resource export BigQuery dataset to store resource consumption data. The resulting table can be joined with the resource usage table or with BigQuery billing export. | bool | `"true"` | no | +| enable\_shielded\_nodes | Enable Shielded Nodes features on all nodes in this cluster | bool | `"true"` | no | | firewall\_inbound\_ports | List of TCP ports for admission/webhook controllers | list(string) | `` | no | | firewall\_priority | Priority rule for firewall rules | number | `"1000"` | no | | gcloud\_skip\_download | Whether to skip downloading gcloud (assumes gcloud is already available outside the module) | bool | `"true"` | no | @@ -119,6 +121,7 @@ Then perform the following commands on the root folder: | grant\_registry\_access | Grants created cluster-specific service account storage.objectViewer role. | bool | `"false"` | no | | horizontal\_pod\_autoscaling | Enable horizontal pod autoscaling addon | bool | `"true"` | no | | http\_load\_balancing | Enable httpload balancer addon | bool | `"true"` | no | +| identity\_namespace | Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`) | string | `"enabled"` | no | | initial\_node\_count | The number of nodes to create in this cluster's default node pool. | number | `"0"` | no | | ip\_masq\_link\_local | Whether to masquerade traffic to the link-local prefix (169.254.0.0/16). | bool | `"false"` | no | | ip\_masq\_resync\_interval | The interval at which the agent attempts to sync its ConfigMap file from the disk. | string | `"60s"` | no | @@ -135,6 +138,7 @@ Then perform the following commands on the root folder: | network\_policy | Enable network policy addon | bool | `"true"` | no | | network\_policy\_provider | The network policy provider. | string | `"CALICO"` | no | | network\_project\_id | The project ID of the shared VPC's host (for shared vpc support) | string | `""` | no | +| node\_metadata | Specifies how node metadata is exposed to the workload running on the node | string | `"GKE_METADATA_SERVER"` | no | | node\_pools | List of maps containing node pools | list(map(string)) | `` | no | | node\_pools\_labels | Map of maps containing node labels by node-pool name | map(map(string)) | `` | no | | node\_pools\_metadata | Map of maps containing node metadata by node-pool name | map(map(string)) | `` | no | @@ -146,6 +150,7 @@ Then perform the following commands on the root folder: | region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no | | regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no | | registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no | +| release\_channel | The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | | remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no | | resource\_usage\_export\_dataset\_id | The ID of a BigQuery Dataset for using BigQuery as the destination of resource usage export. | string | `""` | no | | service\_account | The service account to run nodes as if not overridden in `node_pools`. The create_service_account variable default value (true) will cause a cluster-specific service account to be created. | string | `""` | no | @@ -163,6 +168,7 @@ Then perform the following commands on the root folder: | endpoint | Cluster endpoint | | horizontal\_pod\_autoscaling\_enabled | Whether horizontal pod autoscaling enabled | | http\_load\_balancing\_enabled | Whether http load balancing enabled | +| identity\_namespace | Workload Identity namespace | | location | Cluster location (region if regional cluster, zone if zonal cluster) | | logging\_service | Logging service used | | master\_authorized\_networks\_config | Networks from which access to master is permitted | @@ -174,6 +180,7 @@ Then perform the following commands on the root folder: | node\_pools\_names | List of node pools names | | node\_pools\_versions | List of node pools versions | | region | Cluster region | +| release\_channel | The release channel of this cluster | | service\_account | The service account to default running nodes as if not overridden in `node_pools`. | | type | Cluster type (regional / zonal) | | zones | List of zones in which the cluster resides | diff --git a/autogen/main/cluster.tf.tmpl b/autogen/main/cluster.tf.tmpl index 72b0f2bc2f..2226154a77 100644 --- a/autogen/main/cluster.tf.tmpl +++ b/autogen/main/cluster.tf.tmpl @@ -45,7 +45,6 @@ resource "google_container_cluster" "primary" { } } -{% if beta_cluster %} dynamic "release_channel" { for_each = local.release_channel @@ -53,7 +52,6 @@ resource "google_container_cluster" "primary" { channel = release_channel.value.channel } } -{% endif %} subnetwork = "projects/${local.network_project_id}/regions/${var.region}/subnetworks/${var.subnetwork}" @@ -62,11 +60,7 @@ resource "google_container_cluster" "primary" { disabled = var.disable_default_snat } {% endif %} -{% if beta_cluster %} min_master_version = var.release_channel != null ? null : local.master_version -{% else %} - min_master_version = local.master_version -{% endif %} logging_service = var.logging_service monitoring_service = var.monitoring_service @@ -88,10 +82,10 @@ resource "google_container_cluster" "primary" { default_max_pods_per_node = var.default_max_pods_per_node + enable_shielded_nodes = var.enable_shielded_nodes {% if beta_cluster %} enable_binary_authorization = var.enable_binary_authorization enable_intranode_visibility = var.enable_intranode_visibility - enable_shielded_nodes = var.enable_shielded_nodes enable_kubernetes_alpha = var.enable_kubernetes_alpha vertical_pod_autoscaling { @@ -224,7 +218,6 @@ resource "google_container_cluster" "primary" { node_config { service_account = lookup(var.node_pools[0], "service_account", local.service_account) - {% if beta_cluster %} dynamic "workload_metadata_config" { for_each = local.cluster_node_metadata_config @@ -233,7 +226,6 @@ resource "google_container_cluster" "primary" { node_metadata = workload_metadata_config.value.node_metadata } } - {% endif %} } } @@ -278,7 +270,6 @@ resource "google_container_cluster" "primary" { {% endif %} remove_default_node_pool = var.remove_default_node_pool -{% if beta_cluster %} dynamic "database_encryption" { for_each = var.database_encryption @@ -297,6 +288,7 @@ resource "google_container_cluster" "primary" { } } +{% if beta_cluster %} dynamic "authenticator_groups_config" { for_each = local.cluster_authenticator_security_group content { @@ -501,7 +493,6 @@ resource "google_container_node_pool" "pools" { count = guest_accelerator["count"] } ] - {% if beta_cluster %} dynamic "workload_metadata_config" { for_each = local.cluster_node_metadata_config @@ -510,7 +501,7 @@ resource "google_container_node_pool" "pools" { node_metadata = lookup(each.value, "node_metadata", workload_metadata_config.value.node_metadata) } } - + {% if beta_cluster %} dynamic "sandbox_config" { for_each = local.cluster_sandbox_enabled diff --git a/autogen/main/main.tf.tmpl b/autogen/main/main.tf.tmpl index 5d71830e3a..5bbaa04904 100644 --- a/autogen/main/main.tf.tmpl +++ b/autogen/main/main.tf.tmpl @@ -50,8 +50,8 @@ locals { node_pool_names = [for np in toset(var.node_pools) : np.name] node_pools = zipmap(local.node_pool_names, tolist(toset(var.node_pools))) -{% if beta_cluster %} release_channel = var.release_channel != null ? [{ channel : var.release_channel }] : [] +{% if beta_cluster %} autoscalling_resource_limits = var.cluster_autoscaling.enabled ? [{ resource_type = "cpu" @@ -95,10 +95,6 @@ locals { cluster_gce_pd_csi_config = var.gce_pd_csi_driver ? [{ enabled = true }] : [{ enabled = false }] - cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ - node_metadata = var.node_metadata - }] - cluster_authenticator_security_group = var.authenticator_security_group == null ? [] : [{ security_group = var.authenticator_security_group }] @@ -106,6 +102,9 @@ locals { cluster_sandbox_enabled = var.sandbox_enabled ? ["gvisor"] : [] {% endif %} + cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ + node_metadata = var.node_metadata + }] cluster_output_name = google_container_cluster.primary.name cluster_output_regional_zones = google_container_cluster.primary.node_locations @@ -167,6 +166,10 @@ locals { cluster_network_policy_enabled = ! local.cluster_output_network_policy_enabled cluster_http_load_balancing_enabled = ! local.cluster_output_http_load_balancing_enabled cluster_horizontal_pod_autoscaling_enabled = ! local.cluster_output_horizontal_pod_autoscaling_enabled + workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") + cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ + identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace + }] {% if beta_cluster %} # BETA features cluster_istio_enabled = ! local.cluster_output_istio_disabled @@ -176,10 +179,6 @@ locals { cluster_intranode_visibility_enabled = local.cluster_output_intranode_visbility_enabled cluster_vertical_pod_autoscaling_enabled = local.cluster_output_vertical_pod_autoscaling_enabled - workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") - cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ - identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace - }] # /BETA features {% endif %} diff --git a/autogen/main/outputs.tf.tmpl b/autogen/main/outputs.tf.tmpl index 3899ddfef3..0c9d4be53a 100644 --- a/autogen/main/outputs.tf.tmpl +++ b/autogen/main/outputs.tf.tmpl @@ -118,6 +118,19 @@ output "service_account" { description = "The service account to default running nodes as if not overridden in `node_pools`." value = local.service_account } + +output "release_channel" { + description = "The release channel of this cluster" + value = var.release_channel +} + +output "identity_namespace" { + description = "Workload Identity namespace" + value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null + depends_on = [ + google_container_cluster.primary + ] +} {% if private_cluster %} output "master_ipv4_cidr_block" { @@ -161,17 +174,4 @@ output "vertical_pod_autoscaling_enabled" { description = "Whether veritical pod autoscaling is enabled" value = local.cluster_vertical_pod_autoscaling_enabled } - -output "release_channel" { - description = "The release channel of this cluster" - value = var.release_channel -} - -output "identity_namespace" { - description = "Workload Identity namespace" - value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null - depends_on = [ - google_container_cluster.primary - ] -} {% endif %} diff --git a/autogen/main/variables.tf.tmpl b/autogen/main/variables.tf.tmpl index 2205321bbe..e7301358a4 100644 --- a/autogen/main/variables.tf.tmpl +++ b/autogen/main/variables.tf.tmpl @@ -445,16 +445,6 @@ variable "config_connector" { default = false } -variable "database_encryption" { - description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." - type = list(object({ state = string, key_name = string })) - - default = [{ - state = "DECRYPTED" - key_name = "" - }] -} - variable "cloudrun" { description = "(Beta) Enable CloudRun addon" default = false @@ -471,12 +461,6 @@ variable "enable_pod_security_policy" { default = false } -variable "node_metadata" { - description = "Specifies how node metadata is exposed to the workload running on the node" - default = "GKE_METADATA_SERVER" - type = string -} - variable "sandbox_enabled" { type = bool description = "(Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` to use it)." @@ -495,21 +479,38 @@ variable "enable_vertical_pod_autoscaling" { default = false } -variable "identity_namespace" { - description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" - type = string - default = "enabled" -} - variable "authenticator_security_group" { type = string description = "The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com" default = null } +{% endif %} + +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "GKE_METADATA_SERVER" + type = string +} + +variable "database_encryption" { + description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." + type = list(object({ state = string, key_name = string })) + + default = [{ + state = "DECRYPTED" + key_name = "" + }] +} + +variable "identity_namespace" { + description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" + type = string + default = "enabled" +} variable "release_channel" { type = string - description = "(Beta) The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." + description = "The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." default = null } @@ -518,8 +519,6 @@ variable "enable_shielded_nodes" { description = "Enable Shielded Nodes features on all nodes in this cluster" default = true } -{% endif %} - variable "add_cluster_firewall_rules" { type = bool diff --git a/cluster.tf b/cluster.tf index abcdbc0c89..88a2f02838 100644 --- a/cluster.tf +++ b/cluster.tf @@ -41,10 +41,17 @@ resource "google_container_cluster" "primary" { } } + dynamic "release_channel" { + for_each = local.release_channel + + content { + channel = release_channel.value.channel + } + } subnetwork = "projects/${local.network_project_id}/regions/${var.region}/subnetworks/${var.subnetwork}" - min_master_version = local.master_version + min_master_version = var.release_channel != null ? null : local.master_version logging_service = var.logging_service monitoring_service = var.monitoring_service @@ -52,6 +59,7 @@ resource "google_container_cluster" "primary" { default_max_pods_per_node = var.default_max_pods_per_node + enable_shielded_nodes = var.enable_shielded_nodes dynamic "master_authorized_networks_config" { for_each = local.master_authorized_networks_config content { @@ -115,6 +123,14 @@ resource "google_container_cluster" "primary" { node_config { service_account = lookup(var.node_pools[0], "service_account", local.service_account) + + dynamic "workload_metadata_config" { + for_each = local.cluster_node_metadata_config + + content { + node_metadata = workload_metadata_config.value.node_metadata + } + } } } @@ -136,6 +152,24 @@ resource "google_container_cluster" "primary" { remove_default_node_pool = var.remove_default_node_pool + + dynamic "database_encryption" { + for_each = var.database_encryption + + content { + key_name = database_encryption.value.key_name + state = database_encryption.value.state + } + } + + dynamic "workload_identity_config" { + for_each = local.cluster_workload_identity_config + + content { + identity_namespace = workload_identity_config.value.identity_namespace + } + } + } /****************************************** @@ -242,6 +276,14 @@ resource "google_container_node_pool" "pools" { } ] + dynamic "workload_metadata_config" { + for_each = local.cluster_node_metadata_config + + content { + node_metadata = lookup(each.value, "node_metadata", workload_metadata_config.value.node_metadata) + } + } + shielded_instance_config { enable_secure_boot = lookup(each.value, "enable_secure_boot", false) enable_integrity_monitoring = lookup(each.value, "enable_integrity_monitoring", true) diff --git a/examples/private_zonal_with_networking/main.tf b/examples/private_zonal_with_networking/main.tf index 75d13dd218..ec003f9ae0 100644 --- a/examples/private_zonal_with_networking/main.tf +++ b/examples/private_zonal_with_networking/main.tf @@ -51,7 +51,7 @@ data "google_compute_subnetwork" "subnetwork" { } module "gke" { - source = "../../modules/beta-private-cluster/" + source = "../../modules/private-cluster/" project_id = var.project_id name = var.cluster_name regional = false diff --git a/examples/simple_zonal_with_asm/main.tf b/examples/simple_zonal_with_asm/main.tf index 1ad1f5b68e..a07b312f55 100644 --- a/examples/simple_zonal_with_asm/main.tf +++ b/examples/simple_zonal_with_asm/main.tf @@ -23,12 +23,17 @@ provider "google-beta" { region = var.region } +provider "google" { + version = "~> 3.42.0" + region = var.region +} + data "google_project" "project" { project_id = var.project_id } module "gke" { - source = "../../modules/beta-public-cluster/" + source = "../../" project_id = var.project_id name = "${local.cluster_type}-cluster${var.cluster_name_suffix}" regional = false diff --git a/examples/workload_identity/main.tf b/examples/workload_identity/main.tf index 9579d090ab..2a1d891650 100644 --- a/examples/workload_identity/main.tf +++ b/examples/workload_identity/main.tf @@ -32,7 +32,7 @@ provider "kubernetes" { } module "gke" { - source = "../../modules/beta-public-cluster/" + source = "../../" project_id = var.project_id name = "${local.cluster_type}-cluster${var.cluster_name_suffix}" region = var.region diff --git a/examples/workload_metadata_config/main.tf b/examples/workload_metadata_config/main.tf index a861c2414d..df979482a6 100644 --- a/examples/workload_metadata_config/main.tf +++ b/examples/workload_metadata_config/main.tf @@ -30,7 +30,7 @@ data "google_compute_subnetwork" "subnetwork" { } module "gke" { - source = "../../modules/beta-private-cluster/" + source = "../../modules/private-cluster/" project_id = var.project_id name = "${local.cluster_type}-cluster${var.cluster_name_suffix}" regional = false diff --git a/main.tf b/main.tf index a27a97c0a2..aaa898afb3 100644 --- a/main.tf +++ b/main.tf @@ -46,6 +46,7 @@ locals { node_pool_names = [for np in toset(var.node_pools) : np.name] node_pools = zipmap(local.node_pool_names, tolist(toset(var.node_pools))) + release_channel = var.release_channel != null ? [{ channel : var.release_channel }] : [] custom_kube_dns_config = length(keys(var.stub_domains)) > 0 @@ -67,6 +68,9 @@ locals { provider = null }] + cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ + node_metadata = var.node_metadata + }] cluster_output_name = google_container_cluster.primary.name cluster_output_regional_zones = google_container_cluster.primary.node_locations @@ -113,6 +117,10 @@ locals { cluster_network_policy_enabled = ! local.cluster_output_network_policy_enabled cluster_http_load_balancing_enabled = ! local.cluster_output_http_load_balancing_enabled cluster_horizontal_pod_autoscaling_enabled = ! local.cluster_output_horizontal_pod_autoscaling_enabled + workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") + cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ + identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace + }] } diff --git a/modules/beta-private-cluster-update-variant/README.md b/modules/beta-private-cluster-update-variant/README.md index d8f1bddb65..9f0947241a 100644 --- a/modules/beta-private-cluster-update-variant/README.md +++ b/modules/beta-private-cluster-update-variant/README.md @@ -216,7 +216,7 @@ Then perform the following commands on the root folder: | region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no | | regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no | | registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no | -| release\_channel | (Beta) The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | +| release\_channel | The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | | remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no | | resource\_usage\_export\_dataset\_id | The ID of a BigQuery Dataset for using BigQuery as the destination of resource usage export. | string | `""` | no | | sandbox\_enabled | (Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` to use it). | bool | `"false"` | no | diff --git a/modules/beta-private-cluster-update-variant/cluster.tf b/modules/beta-private-cluster-update-variant/cluster.tf index 65b4ac56ef..e950f8ffbe 100644 --- a/modules/beta-private-cluster-update-variant/cluster.tf +++ b/modules/beta-private-cluster-update-variant/cluster.tf @@ -74,9 +74,9 @@ resource "google_container_cluster" "primary" { default_max_pods_per_node = var.default_max_pods_per_node + enable_shielded_nodes = var.enable_shielded_nodes enable_binary_authorization = var.enable_binary_authorization enable_intranode_visibility = var.enable_intranode_visibility - enable_shielded_nodes = var.enable_shielded_nodes enable_kubernetes_alpha = var.enable_kubernetes_alpha vertical_pod_autoscaling { @@ -461,7 +461,6 @@ resource "google_container_node_pool" "pools" { node_metadata = lookup(each.value, "node_metadata", workload_metadata_config.value.node_metadata) } } - dynamic "sandbox_config" { for_each = local.cluster_sandbox_enabled diff --git a/modules/beta-private-cluster-update-variant/main.tf b/modules/beta-private-cluster-update-variant/main.tf index 6f76486271..9184325783 100644 --- a/modules/beta-private-cluster-update-variant/main.tf +++ b/modules/beta-private-cluster-update-variant/main.tf @@ -84,16 +84,15 @@ locals { cluster_gce_pd_csi_config = var.gce_pd_csi_driver ? [{ enabled = true }] : [{ enabled = false }] - cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ - node_metadata = var.node_metadata - }] - cluster_authenticator_security_group = var.authenticator_security_group == null ? [] : [{ security_group = var.authenticator_security_group }] cluster_sandbox_enabled = var.sandbox_enabled ? ["gvisor"] : [] + cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ + node_metadata = var.node_metadata + }] cluster_output_name = google_container_cluster.primary.name cluster_output_regional_zones = google_container_cluster.primary.node_locations @@ -148,6 +147,10 @@ locals { cluster_network_policy_enabled = ! local.cluster_output_network_policy_enabled cluster_http_load_balancing_enabled = ! local.cluster_output_http_load_balancing_enabled cluster_horizontal_pod_autoscaling_enabled = ! local.cluster_output_horizontal_pod_autoscaling_enabled + workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") + cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ + identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace + }] # BETA features cluster_istio_enabled = ! local.cluster_output_istio_disabled cluster_cloudrun_enabled = var.cloudrun @@ -156,10 +159,6 @@ locals { cluster_intranode_visibility_enabled = local.cluster_output_intranode_visbility_enabled cluster_vertical_pod_autoscaling_enabled = local.cluster_output_vertical_pod_autoscaling_enabled - workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") - cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ - identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace - }] # /BETA features cluster_maintenance_window_is_recurring = var.maintenance_recurrence != "" && var.maintenance_end_time != "" ? [1] : [] diff --git a/modules/beta-private-cluster-update-variant/outputs.tf b/modules/beta-private-cluster-update-variant/outputs.tf index 4f7b9196c7..12084a72cc 100644 --- a/modules/beta-private-cluster-update-variant/outputs.tf +++ b/modules/beta-private-cluster-update-variant/outputs.tf @@ -119,6 +119,19 @@ output "service_account" { value = local.service_account } +output "release_channel" { + description = "The release channel of this cluster" + value = var.release_channel +} + +output "identity_namespace" { + description = "Workload Identity namespace" + value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null + depends_on = [ + google_container_cluster.primary + ] +} + output "master_ipv4_cidr_block" { description = "The IP range in CIDR notation used for the hosted master network" value = var.master_ipv4_cidr_block @@ -158,16 +171,3 @@ output "vertical_pod_autoscaling_enabled" { description = "Whether veritical pod autoscaling is enabled" value = local.cluster_vertical_pod_autoscaling_enabled } - -output "release_channel" { - description = "The release channel of this cluster" - value = var.release_channel -} - -output "identity_namespace" { - description = "Workload Identity namespace" - value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null - depends_on = [ - google_container_cluster.primary - ] -} diff --git a/modules/beta-private-cluster-update-variant/variables.tf b/modules/beta-private-cluster-update-variant/variables.tf index f092bb5d78..22b6e957b5 100644 --- a/modules/beta-private-cluster-update-variant/variables.tf +++ b/modules/beta-private-cluster-update-variant/variables.tf @@ -436,16 +436,6 @@ variable "config_connector" { default = false } -variable "database_encryption" { - description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." - type = list(object({ state = string, key_name = string })) - - default = [{ - state = "DECRYPTED" - key_name = "" - }] -} - variable "cloudrun" { description = "(Beta) Enable CloudRun addon" default = false @@ -462,12 +452,6 @@ variable "enable_pod_security_policy" { default = false } -variable "node_metadata" { - description = "Specifies how node metadata is exposed to the workload running on the node" - default = "GKE_METADATA_SERVER" - type = string -} - variable "sandbox_enabled" { type = bool description = "(Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` to use it)." @@ -486,21 +470,37 @@ variable "enable_vertical_pod_autoscaling" { default = false } -variable "identity_namespace" { - description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" - type = string - default = "enabled" -} - variable "authenticator_security_group" { type = string description = "The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com" default = null } +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "GKE_METADATA_SERVER" + type = string +} + +variable "database_encryption" { + description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." + type = list(object({ state = string, key_name = string })) + + default = [{ + state = "DECRYPTED" + key_name = "" + }] +} + +variable "identity_namespace" { + description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" + type = string + default = "enabled" +} + variable "release_channel" { type = string - description = "(Beta) The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." + description = "The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." default = null } @@ -510,7 +510,6 @@ variable "enable_shielded_nodes" { default = true } - variable "add_cluster_firewall_rules" { type = bool description = "Create additional firewall rules" diff --git a/modules/beta-private-cluster/README.md b/modules/beta-private-cluster/README.md index d81a0d95de..59cc354f7f 100644 --- a/modules/beta-private-cluster/README.md +++ b/modules/beta-private-cluster/README.md @@ -194,7 +194,7 @@ Then perform the following commands on the root folder: | region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no | | regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no | | registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no | -| release\_channel | (Beta) The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | +| release\_channel | The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | | remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no | | resource\_usage\_export\_dataset\_id | The ID of a BigQuery Dataset for using BigQuery as the destination of resource usage export. | string | `""` | no | | sandbox\_enabled | (Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` to use it). | bool | `"false"` | no | diff --git a/modules/beta-private-cluster/cluster.tf b/modules/beta-private-cluster/cluster.tf index 1a65d5922f..af8d38d86e 100644 --- a/modules/beta-private-cluster/cluster.tf +++ b/modules/beta-private-cluster/cluster.tf @@ -74,9 +74,9 @@ resource "google_container_cluster" "primary" { default_max_pods_per_node = var.default_max_pods_per_node + enable_shielded_nodes = var.enable_shielded_nodes enable_binary_authorization = var.enable_binary_authorization enable_intranode_visibility = var.enable_intranode_visibility - enable_shielded_nodes = var.enable_shielded_nodes enable_kubernetes_alpha = var.enable_kubernetes_alpha vertical_pod_autoscaling { @@ -389,7 +389,6 @@ resource "google_container_node_pool" "pools" { node_metadata = lookup(each.value, "node_metadata", workload_metadata_config.value.node_metadata) } } - dynamic "sandbox_config" { for_each = local.cluster_sandbox_enabled diff --git a/modules/beta-private-cluster/main.tf b/modules/beta-private-cluster/main.tf index 6f76486271..9184325783 100644 --- a/modules/beta-private-cluster/main.tf +++ b/modules/beta-private-cluster/main.tf @@ -84,16 +84,15 @@ locals { cluster_gce_pd_csi_config = var.gce_pd_csi_driver ? [{ enabled = true }] : [{ enabled = false }] - cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ - node_metadata = var.node_metadata - }] - cluster_authenticator_security_group = var.authenticator_security_group == null ? [] : [{ security_group = var.authenticator_security_group }] cluster_sandbox_enabled = var.sandbox_enabled ? ["gvisor"] : [] + cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ + node_metadata = var.node_metadata + }] cluster_output_name = google_container_cluster.primary.name cluster_output_regional_zones = google_container_cluster.primary.node_locations @@ -148,6 +147,10 @@ locals { cluster_network_policy_enabled = ! local.cluster_output_network_policy_enabled cluster_http_load_balancing_enabled = ! local.cluster_output_http_load_balancing_enabled cluster_horizontal_pod_autoscaling_enabled = ! local.cluster_output_horizontal_pod_autoscaling_enabled + workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") + cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ + identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace + }] # BETA features cluster_istio_enabled = ! local.cluster_output_istio_disabled cluster_cloudrun_enabled = var.cloudrun @@ -156,10 +159,6 @@ locals { cluster_intranode_visibility_enabled = local.cluster_output_intranode_visbility_enabled cluster_vertical_pod_autoscaling_enabled = local.cluster_output_vertical_pod_autoscaling_enabled - workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") - cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ - identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace - }] # /BETA features cluster_maintenance_window_is_recurring = var.maintenance_recurrence != "" && var.maintenance_end_time != "" ? [1] : [] diff --git a/modules/beta-private-cluster/outputs.tf b/modules/beta-private-cluster/outputs.tf index 4f7b9196c7..12084a72cc 100644 --- a/modules/beta-private-cluster/outputs.tf +++ b/modules/beta-private-cluster/outputs.tf @@ -119,6 +119,19 @@ output "service_account" { value = local.service_account } +output "release_channel" { + description = "The release channel of this cluster" + value = var.release_channel +} + +output "identity_namespace" { + description = "Workload Identity namespace" + value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null + depends_on = [ + google_container_cluster.primary + ] +} + output "master_ipv4_cidr_block" { description = "The IP range in CIDR notation used for the hosted master network" value = var.master_ipv4_cidr_block @@ -158,16 +171,3 @@ output "vertical_pod_autoscaling_enabled" { description = "Whether veritical pod autoscaling is enabled" value = local.cluster_vertical_pod_autoscaling_enabled } - -output "release_channel" { - description = "The release channel of this cluster" - value = var.release_channel -} - -output "identity_namespace" { - description = "Workload Identity namespace" - value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null - depends_on = [ - google_container_cluster.primary - ] -} diff --git a/modules/beta-private-cluster/variables.tf b/modules/beta-private-cluster/variables.tf index f092bb5d78..22b6e957b5 100644 --- a/modules/beta-private-cluster/variables.tf +++ b/modules/beta-private-cluster/variables.tf @@ -436,16 +436,6 @@ variable "config_connector" { default = false } -variable "database_encryption" { - description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." - type = list(object({ state = string, key_name = string })) - - default = [{ - state = "DECRYPTED" - key_name = "" - }] -} - variable "cloudrun" { description = "(Beta) Enable CloudRun addon" default = false @@ -462,12 +452,6 @@ variable "enable_pod_security_policy" { default = false } -variable "node_metadata" { - description = "Specifies how node metadata is exposed to the workload running on the node" - default = "GKE_METADATA_SERVER" - type = string -} - variable "sandbox_enabled" { type = bool description = "(Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` to use it)." @@ -486,21 +470,37 @@ variable "enable_vertical_pod_autoscaling" { default = false } -variable "identity_namespace" { - description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" - type = string - default = "enabled" -} - variable "authenticator_security_group" { type = string description = "The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com" default = null } +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "GKE_METADATA_SERVER" + type = string +} + +variable "database_encryption" { + description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." + type = list(object({ state = string, key_name = string })) + + default = [{ + state = "DECRYPTED" + key_name = "" + }] +} + +variable "identity_namespace" { + description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" + type = string + default = "enabled" +} + variable "release_channel" { type = string - description = "(Beta) The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." + description = "The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." default = null } @@ -510,7 +510,6 @@ variable "enable_shielded_nodes" { default = true } - variable "add_cluster_firewall_rules" { type = bool description = "Create additional firewall rules" diff --git a/modules/beta-public-cluster-update-variant/README.md b/modules/beta-public-cluster-update-variant/README.md index 66ddf588c3..b24b077079 100644 --- a/modules/beta-public-cluster-update-variant/README.md +++ b/modules/beta-public-cluster-update-variant/README.md @@ -205,7 +205,7 @@ Then perform the following commands on the root folder: | region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no | | regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no | | registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no | -| release\_channel | (Beta) The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | +| release\_channel | The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | | remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no | | resource\_usage\_export\_dataset\_id | The ID of a BigQuery Dataset for using BigQuery as the destination of resource usage export. | string | `""` | no | | sandbox\_enabled | (Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` to use it). | bool | `"false"` | no | diff --git a/modules/beta-public-cluster-update-variant/cluster.tf b/modules/beta-public-cluster-update-variant/cluster.tf index 525996978b..b1ea360ce2 100644 --- a/modules/beta-public-cluster-update-variant/cluster.tf +++ b/modules/beta-public-cluster-update-variant/cluster.tf @@ -74,9 +74,9 @@ resource "google_container_cluster" "primary" { default_max_pods_per_node = var.default_max_pods_per_node + enable_shielded_nodes = var.enable_shielded_nodes enable_binary_authorization = var.enable_binary_authorization enable_intranode_visibility = var.enable_intranode_visibility - enable_shielded_nodes = var.enable_shielded_nodes enable_kubernetes_alpha = var.enable_kubernetes_alpha vertical_pod_autoscaling { @@ -442,7 +442,6 @@ resource "google_container_node_pool" "pools" { node_metadata = lookup(each.value, "node_metadata", workload_metadata_config.value.node_metadata) } } - dynamic "sandbox_config" { for_each = local.cluster_sandbox_enabled diff --git a/modules/beta-public-cluster-update-variant/main.tf b/modules/beta-public-cluster-update-variant/main.tf index edabbc45b2..c4ed088e02 100644 --- a/modules/beta-public-cluster-update-variant/main.tf +++ b/modules/beta-public-cluster-update-variant/main.tf @@ -84,16 +84,15 @@ locals { cluster_gce_pd_csi_config = var.gce_pd_csi_driver ? [{ enabled = true }] : [{ enabled = false }] - cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ - node_metadata = var.node_metadata - }] - cluster_authenticator_security_group = var.authenticator_security_group == null ? [] : [{ security_group = var.authenticator_security_group }] cluster_sandbox_enabled = var.sandbox_enabled ? ["gvisor"] : [] + cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ + node_metadata = var.node_metadata + }] cluster_output_name = google_container_cluster.primary.name cluster_output_regional_zones = google_container_cluster.primary.node_locations @@ -147,6 +146,10 @@ locals { cluster_network_policy_enabled = ! local.cluster_output_network_policy_enabled cluster_http_load_balancing_enabled = ! local.cluster_output_http_load_balancing_enabled cluster_horizontal_pod_autoscaling_enabled = ! local.cluster_output_horizontal_pod_autoscaling_enabled + workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") + cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ + identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace + }] # BETA features cluster_istio_enabled = ! local.cluster_output_istio_disabled cluster_cloudrun_enabled = var.cloudrun @@ -155,10 +158,6 @@ locals { cluster_intranode_visibility_enabled = local.cluster_output_intranode_visbility_enabled cluster_vertical_pod_autoscaling_enabled = local.cluster_output_vertical_pod_autoscaling_enabled - workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") - cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ - identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace - }] # /BETA features cluster_maintenance_window_is_recurring = var.maintenance_recurrence != "" && var.maintenance_end_time != "" ? [1] : [] diff --git a/modules/beta-public-cluster-update-variant/outputs.tf b/modules/beta-public-cluster-update-variant/outputs.tf index 57172b1347..9a8ec345ec 100644 --- a/modules/beta-public-cluster-update-variant/outputs.tf +++ b/modules/beta-public-cluster-update-variant/outputs.tf @@ -119,6 +119,19 @@ output "service_account" { value = local.service_account } +output "release_channel" { + description = "The release channel of this cluster" + value = var.release_channel +} + +output "identity_namespace" { + description = "Workload Identity namespace" + value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null + depends_on = [ + google_container_cluster.primary + ] +} + output "istio_enabled" { description = "Whether Istio is enabled" value = local.cluster_istio_enabled @@ -148,16 +161,3 @@ output "vertical_pod_autoscaling_enabled" { description = "Whether veritical pod autoscaling is enabled" value = local.cluster_vertical_pod_autoscaling_enabled } - -output "release_channel" { - description = "The release channel of this cluster" - value = var.release_channel -} - -output "identity_namespace" { - description = "Workload Identity namespace" - value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null - depends_on = [ - google_container_cluster.primary - ] -} diff --git a/modules/beta-public-cluster-update-variant/variables.tf b/modules/beta-public-cluster-update-variant/variables.tf index a14d2c30b9..e373d59bef 100644 --- a/modules/beta-public-cluster-update-variant/variables.tf +++ b/modules/beta-public-cluster-update-variant/variables.tf @@ -405,16 +405,6 @@ variable "config_connector" { default = false } -variable "database_encryption" { - description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." - type = list(object({ state = string, key_name = string })) - - default = [{ - state = "DECRYPTED" - key_name = "" - }] -} - variable "cloudrun" { description = "(Beta) Enable CloudRun addon" default = false @@ -431,12 +421,6 @@ variable "enable_pod_security_policy" { default = false } -variable "node_metadata" { - description = "Specifies how node metadata is exposed to the workload running on the node" - default = "GKE_METADATA_SERVER" - type = string -} - variable "sandbox_enabled" { type = bool description = "(Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` to use it)." @@ -455,21 +439,37 @@ variable "enable_vertical_pod_autoscaling" { default = false } -variable "identity_namespace" { - description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" - type = string - default = "enabled" -} - variable "authenticator_security_group" { type = string description = "The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com" default = null } +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "GKE_METADATA_SERVER" + type = string +} + +variable "database_encryption" { + description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." + type = list(object({ state = string, key_name = string })) + + default = [{ + state = "DECRYPTED" + key_name = "" + }] +} + +variable "identity_namespace" { + description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" + type = string + default = "enabled" +} + variable "release_channel" { type = string - description = "(Beta) The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." + description = "The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." default = null } @@ -479,7 +479,6 @@ variable "enable_shielded_nodes" { default = true } - variable "add_cluster_firewall_rules" { type = bool description = "Create additional firewall rules" diff --git a/modules/beta-public-cluster/README.md b/modules/beta-public-cluster/README.md index 3c75ec6e7c..fd7adff0dd 100644 --- a/modules/beta-public-cluster/README.md +++ b/modules/beta-public-cluster/README.md @@ -183,7 +183,7 @@ Then perform the following commands on the root folder: | region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no | | regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no | | registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no | -| release\_channel | (Beta) The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | +| release\_channel | The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | | remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no | | resource\_usage\_export\_dataset\_id | The ID of a BigQuery Dataset for using BigQuery as the destination of resource usage export. | string | `""` | no | | sandbox\_enabled | (Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` to use it). | bool | `"false"` | no | diff --git a/modules/beta-public-cluster/cluster.tf b/modules/beta-public-cluster/cluster.tf index 5649483625..53139785b1 100644 --- a/modules/beta-public-cluster/cluster.tf +++ b/modules/beta-public-cluster/cluster.tf @@ -74,9 +74,9 @@ resource "google_container_cluster" "primary" { default_max_pods_per_node = var.default_max_pods_per_node + enable_shielded_nodes = var.enable_shielded_nodes enable_binary_authorization = var.enable_binary_authorization enable_intranode_visibility = var.enable_intranode_visibility - enable_shielded_nodes = var.enable_shielded_nodes enable_kubernetes_alpha = var.enable_kubernetes_alpha vertical_pod_autoscaling { @@ -370,7 +370,6 @@ resource "google_container_node_pool" "pools" { node_metadata = lookup(each.value, "node_metadata", workload_metadata_config.value.node_metadata) } } - dynamic "sandbox_config" { for_each = local.cluster_sandbox_enabled diff --git a/modules/beta-public-cluster/main.tf b/modules/beta-public-cluster/main.tf index edabbc45b2..c4ed088e02 100644 --- a/modules/beta-public-cluster/main.tf +++ b/modules/beta-public-cluster/main.tf @@ -84,16 +84,15 @@ locals { cluster_gce_pd_csi_config = var.gce_pd_csi_driver ? [{ enabled = true }] : [{ enabled = false }] - cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ - node_metadata = var.node_metadata - }] - cluster_authenticator_security_group = var.authenticator_security_group == null ? [] : [{ security_group = var.authenticator_security_group }] cluster_sandbox_enabled = var.sandbox_enabled ? ["gvisor"] : [] + cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ + node_metadata = var.node_metadata + }] cluster_output_name = google_container_cluster.primary.name cluster_output_regional_zones = google_container_cluster.primary.node_locations @@ -147,6 +146,10 @@ locals { cluster_network_policy_enabled = ! local.cluster_output_network_policy_enabled cluster_http_load_balancing_enabled = ! local.cluster_output_http_load_balancing_enabled cluster_horizontal_pod_autoscaling_enabled = ! local.cluster_output_horizontal_pod_autoscaling_enabled + workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") + cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ + identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace + }] # BETA features cluster_istio_enabled = ! local.cluster_output_istio_disabled cluster_cloudrun_enabled = var.cloudrun @@ -155,10 +158,6 @@ locals { cluster_intranode_visibility_enabled = local.cluster_output_intranode_visbility_enabled cluster_vertical_pod_autoscaling_enabled = local.cluster_output_vertical_pod_autoscaling_enabled - workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") - cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ - identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace - }] # /BETA features cluster_maintenance_window_is_recurring = var.maintenance_recurrence != "" && var.maintenance_end_time != "" ? [1] : [] diff --git a/modules/beta-public-cluster/outputs.tf b/modules/beta-public-cluster/outputs.tf index 57172b1347..9a8ec345ec 100644 --- a/modules/beta-public-cluster/outputs.tf +++ b/modules/beta-public-cluster/outputs.tf @@ -119,6 +119,19 @@ output "service_account" { value = local.service_account } +output "release_channel" { + description = "The release channel of this cluster" + value = var.release_channel +} + +output "identity_namespace" { + description = "Workload Identity namespace" + value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null + depends_on = [ + google_container_cluster.primary + ] +} + output "istio_enabled" { description = "Whether Istio is enabled" value = local.cluster_istio_enabled @@ -148,16 +161,3 @@ output "vertical_pod_autoscaling_enabled" { description = "Whether veritical pod autoscaling is enabled" value = local.cluster_vertical_pod_autoscaling_enabled } - -output "release_channel" { - description = "The release channel of this cluster" - value = var.release_channel -} - -output "identity_namespace" { - description = "Workload Identity namespace" - value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null - depends_on = [ - google_container_cluster.primary - ] -} diff --git a/modules/beta-public-cluster/variables.tf b/modules/beta-public-cluster/variables.tf index a14d2c30b9..e373d59bef 100644 --- a/modules/beta-public-cluster/variables.tf +++ b/modules/beta-public-cluster/variables.tf @@ -405,16 +405,6 @@ variable "config_connector" { default = false } -variable "database_encryption" { - description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." - type = list(object({ state = string, key_name = string })) - - default = [{ - state = "DECRYPTED" - key_name = "" - }] -} - variable "cloudrun" { description = "(Beta) Enable CloudRun addon" default = false @@ -431,12 +421,6 @@ variable "enable_pod_security_policy" { default = false } -variable "node_metadata" { - description = "Specifies how node metadata is exposed to the workload running on the node" - default = "GKE_METADATA_SERVER" - type = string -} - variable "sandbox_enabled" { type = bool description = "(Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` to use it)." @@ -455,21 +439,37 @@ variable "enable_vertical_pod_autoscaling" { default = false } -variable "identity_namespace" { - description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" - type = string - default = "enabled" -} - variable "authenticator_security_group" { type = string description = "The name of the RBAC security group for use with Google security groups in Kubernetes RBAC. Group name must be in format gke-security-groups@yourdomain.com" default = null } +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "GKE_METADATA_SERVER" + type = string +} + +variable "database_encryption" { + description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." + type = list(object({ state = string, key_name = string })) + + default = [{ + state = "DECRYPTED" + key_name = "" + }] +} + +variable "identity_namespace" { + description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" + type = string + default = "enabled" +} + variable "release_channel" { type = string - description = "(Beta) The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." + description = "The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." default = null } @@ -479,7 +479,6 @@ variable "enable_shielded_nodes" { default = true } - variable "add_cluster_firewall_rules" { type = bool description = "Create additional firewall rules" diff --git a/modules/private-cluster-update-variant/README.md b/modules/private-cluster-update-variant/README.md index c0b64b2613..2e7e8338e4 100644 --- a/modules/private-cluster-update-variant/README.md +++ b/modules/private-cluster-update-variant/README.md @@ -135,6 +135,7 @@ Then perform the following commands on the root folder: | cluster\_resource\_labels | The GCE resource labels (a map of key/value pairs) to be applied to the cluster | map(string) | `` | no | | configure\_ip\_masq | Enables the installation of ip masquerading, which is usually no longer required when using aliasied IP addresses. IP masquerading uses a kubectl call, so when you have a private cluster, you will need access to the API server. | string | `"false"` | no | | create\_service\_account | Defines if service account specified to run nodes should be created. | bool | `"true"` | no | +| database\_encryption | Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: "ENCRYPTED"; "DECRYPTED". key_name is the name of a CloudKMS key. | object | `` | no | | default\_max\_pods\_per\_node | The maximum number of pods to schedule per node | string | `"110"` | no | | deploy\_using\_private\_endpoint | (Beta) A toggle for Terraform and kubectl to connect to the master's internal IP address during deployment. | bool | `"false"` | no | | description | The description of the cluster | string | `""` | no | @@ -143,6 +144,7 @@ Then perform the following commands on the root folder: | enable\_private\_endpoint | (Beta) Whether the master's internal IP address is used as the cluster endpoint | bool | `"false"` | no | | enable\_private\_nodes | (Beta) Whether nodes have internal IP addresses only | bool | `"false"` | no | | enable\_resource\_consumption\_export | Whether to enable resource consumption metering on this cluster. When enabled, a table will be created in the resource export BigQuery dataset to store resource consumption data. The resulting table can be joined with the resource usage table or with BigQuery billing export. | bool | `"true"` | no | +| enable\_shielded\_nodes | Enable Shielded Nodes features on all nodes in this cluster | bool | `"true"` | no | | firewall\_inbound\_ports | List of TCP ports for admission/webhook controllers | list(string) | `` | no | | firewall\_priority | Priority rule for firewall rules | number | `"1000"` | no | | gcloud\_skip\_download | Whether to skip downloading gcloud (assumes gcloud is already available outside the module) | bool | `"true"` | no | @@ -150,6 +152,7 @@ Then perform the following commands on the root folder: | grant\_registry\_access | Grants created cluster-specific service account storage.objectViewer role. | bool | `"false"` | no | | horizontal\_pod\_autoscaling | Enable horizontal pod autoscaling addon | bool | `"true"` | no | | http\_load\_balancing | Enable httpload balancer addon | bool | `"true"` | no | +| identity\_namespace | Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`) | string | `"enabled"` | no | | initial\_node\_count | The number of nodes to create in this cluster's default node pool. | number | `"0"` | no | | ip\_masq\_link\_local | Whether to masquerade traffic to the link-local prefix (169.254.0.0/16). | bool | `"false"` | no | | ip\_masq\_resync\_interval | The interval at which the agent attempts to sync its ConfigMap file from the disk. | string | `"60s"` | no | @@ -167,6 +170,7 @@ Then perform the following commands on the root folder: | network\_policy | Enable network policy addon | bool | `"true"` | no | | network\_policy\_provider | The network policy provider. | string | `"CALICO"` | no | | network\_project\_id | The project ID of the shared VPC's host (for shared vpc support) | string | `""` | no | +| node\_metadata | Specifies how node metadata is exposed to the workload running on the node | string | `"GKE_METADATA_SERVER"` | no | | node\_pools | List of maps containing node pools | list(map(string)) | `` | no | | node\_pools\_labels | Map of maps containing node labels by node-pool name | map(map(string)) | `` | no | | node\_pools\_metadata | Map of maps containing node metadata by node-pool name | map(map(string)) | `` | no | @@ -178,6 +182,7 @@ Then perform the following commands on the root folder: | region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no | | regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no | | registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no | +| release\_channel | The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | | remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no | | resource\_usage\_export\_dataset\_id | The ID of a BigQuery Dataset for using BigQuery as the destination of resource usage export. | string | `""` | no | | service\_account | The service account to run nodes as if not overridden in `node_pools`. The create_service_account variable default value (true) will cause a cluster-specific service account to be created. | string | `""` | no | @@ -195,6 +200,7 @@ Then perform the following commands on the root folder: | endpoint | Cluster endpoint | | horizontal\_pod\_autoscaling\_enabled | Whether horizontal pod autoscaling enabled | | http\_load\_balancing\_enabled | Whether http load balancing enabled | +| identity\_namespace | Workload Identity namespace | | location | Cluster location (region if regional cluster, zone if zonal cluster) | | logging\_service | Logging service used | | master\_authorized\_networks\_config | Networks from which access to master is permitted | @@ -208,6 +214,7 @@ Then perform the following commands on the root folder: | node\_pools\_versions | List of node pools versions | | peering\_name | The name of the peering between this cluster and the Google owned VPC. | | region | Cluster region | +| release\_channel | The release channel of this cluster | | service\_account | The service account to default running nodes as if not overridden in `node_pools`. | | type | Cluster type (regional / zonal) | | zones | List of zones in which the cluster resides | diff --git a/modules/private-cluster-update-variant/cluster.tf b/modules/private-cluster-update-variant/cluster.tf index f624fe1e7b..ac086b350b 100644 --- a/modules/private-cluster-update-variant/cluster.tf +++ b/modules/private-cluster-update-variant/cluster.tf @@ -41,10 +41,17 @@ resource "google_container_cluster" "primary" { } } + dynamic "release_channel" { + for_each = local.release_channel + + content { + channel = release_channel.value.channel + } + } subnetwork = "projects/${local.network_project_id}/regions/${var.region}/subnetworks/${var.subnetwork}" - min_master_version = local.master_version + min_master_version = var.release_channel != null ? null : local.master_version logging_service = var.logging_service monitoring_service = var.monitoring_service @@ -52,6 +59,7 @@ resource "google_container_cluster" "primary" { default_max_pods_per_node = var.default_max_pods_per_node + enable_shielded_nodes = var.enable_shielded_nodes dynamic "master_authorized_networks_config" { for_each = local.master_authorized_networks_config content { @@ -115,6 +123,14 @@ resource "google_container_cluster" "primary" { node_config { service_account = lookup(var.node_pools[0], "service_account", local.service_account) + + dynamic "workload_metadata_config" { + for_each = local.cluster_node_metadata_config + + content { + node_metadata = workload_metadata_config.value.node_metadata + } + } } } @@ -149,6 +165,24 @@ resource "google_container_cluster" "primary" { } remove_default_node_pool = var.remove_default_node_pool + + dynamic "database_encryption" { + for_each = var.database_encryption + + content { + key_name = database_encryption.value.key_name + state = database_encryption.value.state + } + } + + dynamic "workload_identity_config" { + for_each = local.cluster_workload_identity_config + + content { + identity_namespace = workload_identity_config.value.identity_namespace + } + } + } /****************************************** @@ -327,6 +361,14 @@ resource "google_container_node_pool" "pools" { } ] + dynamic "workload_metadata_config" { + for_each = local.cluster_node_metadata_config + + content { + node_metadata = lookup(each.value, "node_metadata", workload_metadata_config.value.node_metadata) + } + } + shielded_instance_config { enable_secure_boot = lookup(each.value, "enable_secure_boot", false) enable_integrity_monitoring = lookup(each.value, "enable_integrity_monitoring", true) diff --git a/modules/private-cluster-update-variant/main.tf b/modules/private-cluster-update-variant/main.tf index 87bd0f47a6..26a0f718aa 100644 --- a/modules/private-cluster-update-variant/main.tf +++ b/modules/private-cluster-update-variant/main.tf @@ -46,6 +46,7 @@ locals { node_pool_names = [for np in toset(var.node_pools) : np.name] node_pools = zipmap(local.node_pool_names, tolist(toset(var.node_pools))) + release_channel = var.release_channel != null ? [{ channel : var.release_channel }] : [] custom_kube_dns_config = length(keys(var.stub_domains)) > 0 @@ -67,6 +68,9 @@ locals { provider = null }] + cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ + node_metadata = var.node_metadata + }] cluster_output_name = google_container_cluster.primary.name cluster_output_regional_zones = google_container_cluster.primary.node_locations @@ -114,6 +118,10 @@ locals { cluster_network_policy_enabled = ! local.cluster_output_network_policy_enabled cluster_http_load_balancing_enabled = ! local.cluster_output_http_load_balancing_enabled cluster_horizontal_pod_autoscaling_enabled = ! local.cluster_output_horizontal_pod_autoscaling_enabled + workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") + cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ + identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace + }] } diff --git a/modules/private-cluster-update-variant/outputs.tf b/modules/private-cluster-update-variant/outputs.tf index e88ca49e3a..434ef2f36f 100644 --- a/modules/private-cluster-update-variant/outputs.tf +++ b/modules/private-cluster-update-variant/outputs.tf @@ -119,6 +119,19 @@ output "service_account" { value = local.service_account } +output "release_channel" { + description = "The release channel of this cluster" + value = var.release_channel +} + +output "identity_namespace" { + description = "Workload Identity namespace" + value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null + depends_on = [ + google_container_cluster.primary + ] +} + output "master_ipv4_cidr_block" { description = "The IP range in CIDR notation used for the hosted master network" value = var.master_ipv4_cidr_block diff --git a/modules/private-cluster-update-variant/variables.tf b/modules/private-cluster-update-variant/variables.tf index 5df2c4afc1..e0303b6250 100644 --- a/modules/private-cluster-update-variant/variables.tf +++ b/modules/private-cluster-update-variant/variables.tf @@ -356,6 +356,39 @@ variable "master_ipv4_cidr_block" { default = "10.0.0.0/28" } +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "GKE_METADATA_SERVER" + type = string +} + +variable "database_encryption" { + description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." + type = list(object({ state = string, key_name = string })) + + default = [{ + state = "DECRYPTED" + key_name = "" + }] +} + +variable "identity_namespace" { + description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" + type = string + default = "enabled" +} + +variable "release_channel" { + type = string + description = "The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." + default = null +} + +variable "enable_shielded_nodes" { + type = bool + description = "Enable Shielded Nodes features on all nodes in this cluster" + default = true +} variable "add_cluster_firewall_rules" { type = bool diff --git a/modules/private-cluster/README.md b/modules/private-cluster/README.md index fe4eca1406..cbfc4284ad 100644 --- a/modules/private-cluster/README.md +++ b/modules/private-cluster/README.md @@ -113,6 +113,7 @@ Then perform the following commands on the root folder: | cluster\_resource\_labels | The GCE resource labels (a map of key/value pairs) to be applied to the cluster | map(string) | `` | no | | configure\_ip\_masq | Enables the installation of ip masquerading, which is usually no longer required when using aliasied IP addresses. IP masquerading uses a kubectl call, so when you have a private cluster, you will need access to the API server. | string | `"false"` | no | | create\_service\_account | Defines if service account specified to run nodes should be created. | bool | `"true"` | no | +| database\_encryption | Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: "ENCRYPTED"; "DECRYPTED". key_name is the name of a CloudKMS key. | object | `` | no | | default\_max\_pods\_per\_node | The maximum number of pods to schedule per node | string | `"110"` | no | | deploy\_using\_private\_endpoint | (Beta) A toggle for Terraform and kubectl to connect to the master's internal IP address during deployment. | bool | `"false"` | no | | description | The description of the cluster | string | `""` | no | @@ -121,6 +122,7 @@ Then perform the following commands on the root folder: | enable\_private\_endpoint | (Beta) Whether the master's internal IP address is used as the cluster endpoint | bool | `"false"` | no | | enable\_private\_nodes | (Beta) Whether nodes have internal IP addresses only | bool | `"false"` | no | | enable\_resource\_consumption\_export | Whether to enable resource consumption metering on this cluster. When enabled, a table will be created in the resource export BigQuery dataset to store resource consumption data. The resulting table can be joined with the resource usage table or with BigQuery billing export. | bool | `"true"` | no | +| enable\_shielded\_nodes | Enable Shielded Nodes features on all nodes in this cluster | bool | `"true"` | no | | firewall\_inbound\_ports | List of TCP ports for admission/webhook controllers | list(string) | `` | no | | firewall\_priority | Priority rule for firewall rules | number | `"1000"` | no | | gcloud\_skip\_download | Whether to skip downloading gcloud (assumes gcloud is already available outside the module) | bool | `"true"` | no | @@ -128,6 +130,7 @@ Then perform the following commands on the root folder: | grant\_registry\_access | Grants created cluster-specific service account storage.objectViewer role. | bool | `"false"` | no | | horizontal\_pod\_autoscaling | Enable horizontal pod autoscaling addon | bool | `"true"` | no | | http\_load\_balancing | Enable httpload balancer addon | bool | `"true"` | no | +| identity\_namespace | Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`) | string | `"enabled"` | no | | initial\_node\_count | The number of nodes to create in this cluster's default node pool. | number | `"0"` | no | | ip\_masq\_link\_local | Whether to masquerade traffic to the link-local prefix (169.254.0.0/16). | bool | `"false"` | no | | ip\_masq\_resync\_interval | The interval at which the agent attempts to sync its ConfigMap file from the disk. | string | `"60s"` | no | @@ -145,6 +148,7 @@ Then perform the following commands on the root folder: | network\_policy | Enable network policy addon | bool | `"true"` | no | | network\_policy\_provider | The network policy provider. | string | `"CALICO"` | no | | network\_project\_id | The project ID of the shared VPC's host (for shared vpc support) | string | `""` | no | +| node\_metadata | Specifies how node metadata is exposed to the workload running on the node | string | `"GKE_METADATA_SERVER"` | no | | node\_pools | List of maps containing node pools | list(map(string)) | `` | no | | node\_pools\_labels | Map of maps containing node labels by node-pool name | map(map(string)) | `` | no | | node\_pools\_metadata | Map of maps containing node metadata by node-pool name | map(map(string)) | `` | no | @@ -156,6 +160,7 @@ Then perform the following commands on the root folder: | region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no | | regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no | | registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no | +| release\_channel | The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`. | string | `"null"` | no | | remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no | | resource\_usage\_export\_dataset\_id | The ID of a BigQuery Dataset for using BigQuery as the destination of resource usage export. | string | `""` | no | | service\_account | The service account to run nodes as if not overridden in `node_pools`. The create_service_account variable default value (true) will cause a cluster-specific service account to be created. | string | `""` | no | @@ -173,6 +178,7 @@ Then perform the following commands on the root folder: | endpoint | Cluster endpoint | | horizontal\_pod\_autoscaling\_enabled | Whether horizontal pod autoscaling enabled | | http\_load\_balancing\_enabled | Whether http load balancing enabled | +| identity\_namespace | Workload Identity namespace | | location | Cluster location (region if regional cluster, zone if zonal cluster) | | logging\_service | Logging service used | | master\_authorized\_networks\_config | Networks from which access to master is permitted | @@ -186,6 +192,7 @@ Then perform the following commands on the root folder: | node\_pools\_versions | List of node pools versions | | peering\_name | The name of the peering between this cluster and the Google owned VPC. | | region | Cluster region | +| release\_channel | The release channel of this cluster | | service\_account | The service account to default running nodes as if not overridden in `node_pools`. | | type | Cluster type (regional / zonal) | | zones | List of zones in which the cluster resides | diff --git a/modules/private-cluster/cluster.tf b/modules/private-cluster/cluster.tf index a0ed848c90..4d63a4e562 100644 --- a/modules/private-cluster/cluster.tf +++ b/modules/private-cluster/cluster.tf @@ -41,10 +41,17 @@ resource "google_container_cluster" "primary" { } } + dynamic "release_channel" { + for_each = local.release_channel + + content { + channel = release_channel.value.channel + } + } subnetwork = "projects/${local.network_project_id}/regions/${var.region}/subnetworks/${var.subnetwork}" - min_master_version = local.master_version + min_master_version = var.release_channel != null ? null : local.master_version logging_service = var.logging_service monitoring_service = var.monitoring_service @@ -52,6 +59,7 @@ resource "google_container_cluster" "primary" { default_max_pods_per_node = var.default_max_pods_per_node + enable_shielded_nodes = var.enable_shielded_nodes dynamic "master_authorized_networks_config" { for_each = local.master_authorized_networks_config content { @@ -115,6 +123,14 @@ resource "google_container_cluster" "primary" { node_config { service_account = lookup(var.node_pools[0], "service_account", local.service_account) + + dynamic "workload_metadata_config" { + for_each = local.cluster_node_metadata_config + + content { + node_metadata = workload_metadata_config.value.node_metadata + } + } } } @@ -149,6 +165,24 @@ resource "google_container_cluster" "primary" { } remove_default_node_pool = var.remove_default_node_pool + + dynamic "database_encryption" { + for_each = var.database_encryption + + content { + key_name = database_encryption.value.key_name + state = database_encryption.value.state + } + } + + dynamic "workload_identity_config" { + for_each = local.cluster_workload_identity_config + + content { + identity_namespace = workload_identity_config.value.identity_namespace + } + } + } /****************************************** @@ -255,6 +289,14 @@ resource "google_container_node_pool" "pools" { } ] + dynamic "workload_metadata_config" { + for_each = local.cluster_node_metadata_config + + content { + node_metadata = lookup(each.value, "node_metadata", workload_metadata_config.value.node_metadata) + } + } + shielded_instance_config { enable_secure_boot = lookup(each.value, "enable_secure_boot", false) enable_integrity_monitoring = lookup(each.value, "enable_integrity_monitoring", true) diff --git a/modules/private-cluster/main.tf b/modules/private-cluster/main.tf index 87bd0f47a6..26a0f718aa 100644 --- a/modules/private-cluster/main.tf +++ b/modules/private-cluster/main.tf @@ -46,6 +46,7 @@ locals { node_pool_names = [for np in toset(var.node_pools) : np.name] node_pools = zipmap(local.node_pool_names, tolist(toset(var.node_pools))) + release_channel = var.release_channel != null ? [{ channel : var.release_channel }] : [] custom_kube_dns_config = length(keys(var.stub_domains)) > 0 @@ -67,6 +68,9 @@ locals { provider = null }] + cluster_node_metadata_config = var.node_metadata == "UNSPECIFIED" ? [] : [{ + node_metadata = var.node_metadata + }] cluster_output_name = google_container_cluster.primary.name cluster_output_regional_zones = google_container_cluster.primary.node_locations @@ -114,6 +118,10 @@ locals { cluster_network_policy_enabled = ! local.cluster_output_network_policy_enabled cluster_http_load_balancing_enabled = ! local.cluster_output_http_load_balancing_enabled cluster_horizontal_pod_autoscaling_enabled = ! local.cluster_output_horizontal_pod_autoscaling_enabled + workload_identity_enabled = ! (var.identity_namespace == null || var.identity_namespace == "null") + cluster_workload_identity_config = ! local.workload_identity_enabled ? [] : var.identity_namespace == "enabled" ? [{ + identity_namespace = "${var.project_id}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace + }] } diff --git a/modules/private-cluster/outputs.tf b/modules/private-cluster/outputs.tf index e88ca49e3a..434ef2f36f 100644 --- a/modules/private-cluster/outputs.tf +++ b/modules/private-cluster/outputs.tf @@ -119,6 +119,19 @@ output "service_account" { value = local.service_account } +output "release_channel" { + description = "The release channel of this cluster" + value = var.release_channel +} + +output "identity_namespace" { + description = "Workload Identity namespace" + value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null + depends_on = [ + google_container_cluster.primary + ] +} + output "master_ipv4_cidr_block" { description = "The IP range in CIDR notation used for the hosted master network" value = var.master_ipv4_cidr_block diff --git a/modules/private-cluster/variables.tf b/modules/private-cluster/variables.tf index 5df2c4afc1..e0303b6250 100644 --- a/modules/private-cluster/variables.tf +++ b/modules/private-cluster/variables.tf @@ -356,6 +356,39 @@ variable "master_ipv4_cidr_block" { default = "10.0.0.0/28" } +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "GKE_METADATA_SERVER" + type = string +} + +variable "database_encryption" { + description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." + type = list(object({ state = string, key_name = string })) + + default = [{ + state = "DECRYPTED" + key_name = "" + }] +} + +variable "identity_namespace" { + description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" + type = string + default = "enabled" +} + +variable "release_channel" { + type = string + description = "The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." + default = null +} + +variable "enable_shielded_nodes" { + type = bool + description = "Enable Shielded Nodes features on all nodes in this cluster" + default = true +} variable "add_cluster_firewall_rules" { type = bool diff --git a/outputs.tf b/outputs.tf index 64263516bd..9677c7c4cb 100644 --- a/outputs.tf +++ b/outputs.tf @@ -118,3 +118,16 @@ output "service_account" { description = "The service account to default running nodes as if not overridden in `node_pools`." value = local.service_account } + +output "release_channel" { + description = "The release channel of this cluster" + value = var.release_channel +} + +output "identity_namespace" { + description = "Workload Identity namespace" + value = length(local.cluster_workload_identity_config) > 0 ? local.cluster_workload_identity_config[0].identity_namespace : null + depends_on = [ + google_container_cluster.primary + ] +} diff --git a/test/integration/simple_regional/controls/gcloud.rb b/test/integration/simple_regional/controls/gcloud.rb index bc92583e82..adab9feec3 100644 --- a/test/integration/simple_regional/controls/gcloud.rb +++ b/test/integration/simple_regional/controls/gcloud.rb @@ -53,6 +53,18 @@ "networkPolicyConfig" => {}, ) end + + it "has the expected databaseEncryption config" do + expect(data['databaseEncryption']).to eq({ + "state" => 'DECRYPTED', + }) + end + + it "has the expected shieldedNodes config" do + expect(data['shieldedNodes']).to eq({ + "enabled" => true, + }) + end end describe "default node pool" do diff --git a/variables.tf b/variables.tf index e197d422ef..88fcc545d1 100644 --- a/variables.tf +++ b/variables.tf @@ -332,6 +332,39 @@ variable "default_max_pods_per_node" { default = 110 } +variable "node_metadata" { + description = "Specifies how node metadata is exposed to the workload running on the node" + default = "GKE_METADATA_SERVER" + type = string +} + +variable "database_encryption" { + description = "Application-layer Secrets Encryption settings. The object format is {state = string, key_name = string}. Valid values of state are: \"ENCRYPTED\"; \"DECRYPTED\". key_name is the name of a CloudKMS key." + type = list(object({ state = string, key_name = string })) + + default = [{ + state = "DECRYPTED" + key_name = "" + }] +} + +variable "identity_namespace" { + description = "Workload Identity namespace. (Default value of `enabled` automatically sets project based namespace `[project_id].svc.id.goog`)" + type = string + default = "enabled" +} + +variable "release_channel" { + type = string + description = "The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `UNSPECIFIED`." + default = null +} + +variable "enable_shielded_nodes" { + type = bool + description = "Enable Shielded Nodes features on all nodes in this cluster" + default = true +} variable "add_cluster_firewall_rules" { type = bool