/** * Copyright 2024 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. */ locals { _image = coalesce(var.node_config.image_type, "-") image = { is_cos = length(regexall("COS", local._image)) > 0 is_cos_containerd = ( var.node_config.image_type == null || length(regexall("COS_CONTAINERD", local._image)) > 0 ) is_win = length(regexall("WIN", local._image)) > 0 } node_metadata = var.node_config.metadata == null ? null : merge( var.node_config.metadata, { disable-legacy-endpoints = "true" } ) # if no attributes passed for service account, use the GCE default # if no email specified, create service account service_account_email = ( var.service_account.create ? google_service_account.service_account[0].email : var.service_account.email ) service_account_scopes = ( var.service_account.oauth_scopes != null ? var.service_account.oauth_scopes : [ "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/monitoring", "https://www.googleapis.com/auth/monitoring.write", "https://www.googleapis.com/auth/userinfo.email" ] ) service_account_display_name = ( var.service_account.display_name != null ? var.service_account.display_name : "Terraform GKE ${var.cluster_name} ${var.name}." ) taints = merge(var.taints, !local.image.is_win ? {} : { "node.kubernetes.io/os" = { value = "windows" effect = "NO_EXECUTE" } }) } resource "google_service_account" "service_account" { count = var.service_account.create ? 1 : 0 project = var.project_id account_id = ( var.service_account.email != null ? split("@", var.service_account.email)[0] : "tf-gke-${var.name}" ) display_name = local.service_account_display_name } resource "google_container_node_pool" "nodepool" { provider = google-beta project = var.project_id cluster = coalesce(var.cluster_id, var.cluster_name) location = var.location name = var.name version = var.gke_version max_pods_per_node = var.max_pods_per_node initial_node_count = var.node_count.initial node_count = var.node_count.current node_locations = var.node_locations dynamic "autoscaling" { for_each = ( try(var.nodepool_config.autoscaling, null) != null && !try(var.nodepool_config.autoscaling.use_total_nodes, false) ? [""] : [] ) content { location_policy = try(var.nodepool_config.autoscaling.location_policy, null) max_node_count = try(var.nodepool_config.autoscaling.max_node_count, null) min_node_count = try(var.nodepool_config.autoscaling.min_node_count, null) } } dynamic "autoscaling" { for_each = ( try(var.nodepool_config.autoscaling.use_total_nodes, false) ? [""] : [] ) content { location_policy = try(var.nodepool_config.autoscaling.location_policy, null) total_max_node_count = try(var.nodepool_config.autoscaling.max_node_count, null) total_min_node_count = try(var.nodepool_config.autoscaling.min_node_count, null) } } dynamic "management" { for_each = try(var.nodepool_config.management, null) != null ? [""] : [] content { auto_repair = try(var.nodepool_config.management.auto_repair, null) auto_upgrade = try(var.nodepool_config.management.auto_upgrade, null) } } dynamic "network_config" { for_each = var.network_config != null ? [""] : [] content { create_pod_range = var.network_config.pod_range.create enable_private_nodes = var.network_config.enable_private_nodes pod_ipv4_cidr_block = var.network_config.pod_range.cidr pod_range = var.network_config.pod_range.name dynamic "additional_node_network_configs" { for_each = try(var.network_config.additional_node_network_configs, []) content { network = additional_node_network_configs.value.network subnetwork = additional_node_network_configs.value.subnetwork } } dynamic "additional_pod_network_configs" { for_each = try(var.network_config.additional_pod_network_configs, []) content { subnetwork = additional_pod_network_configs.value.subnetwork secondary_pod_range = additional_pod_network_configs.value.secondary_pod_range max_pods_per_node = additional_pod_network_configs.value.max_pods_per_node } } dynamic "network_performance_config" { for_each = try(var.network_config.total_egress_bandwidth_tier, null) != null ? [""] : [] content { total_egress_bandwidth_tier = var.network_config.total_egress_bandwidth_tier } } dynamic "pod_cidr_overprovision_config" { for_each = var.network_config.pod_cidr_overprovisioning_disabled ? [""] : [] content { disabled = true } } } } dynamic "upgrade_settings" { for_each = try(var.nodepool_config.upgrade_settings, null) != null ? [""] : [] content { max_surge = try(var.nodepool_config.upgrade_settings.max_surge, null) max_unavailable = try(var.nodepool_config.upgrade_settings.max_unavailable, null) strategy = try(var.nodepool_config.upgrade_settings.strategy, null) dynamic "blue_green_settings" { for_each = try(var.nodepool_config.upgrade_settings.blue_green_settings, null) != null ? [""] : [] content { node_pool_soak_duration = var.nodepool_config.upgrade_settings.blue_green_settings.node_pool_soak_duration dynamic "standard_rollout_policy" { for_each = try(var.nodepool_config.upgrade_settings.blue_green_settings.standard_rollout_policy, null) != null ? [""] : [] content { batch_percentage = var.nodepool_config.upgrade_settings.blue_green_settings.standard_rollout_policy.batch_percentage batch_node_count = var.nodepool_config.upgrade_settings.blue_green_settings.standard_rollout_policy.batch_node_count batch_soak_duration = var.nodepool_config.upgrade_settings.blue_green_settings.standard_rollout_policy.batch_soak_duration } } } } } } dynamic "placement_policy" { for_each = try(var.nodepool_config.placement_policy, null) != null ? [""] : [] content { type = var.nodepool_config.placement_policy.type policy_name = var.nodepool_config.placement_policy.policy_name tpu_topology = var.nodepool_config.placement_policy.tpu_topology } } dynamic "queued_provisioning" { for_each = try(var.nodepool_config.queued_provisioning, false) ? [""] : [] content { enabled = var.nodepool_config.queued_provisioning } } node_config { boot_disk_kms_key = try(var.node_config.boot_disk.kms_key, var.node_config.boot_disk_kms_key) boot_disk { size_gb = try(var.node_config.boot_disk.size_gb, var.node_config.disk_size_gb) disk_type = try(var.node_config.boot_disk.type, var.node_config.disk_type) provisioned_iops = try( var.node_config.boot_disk.provisioned_iops, null ) provisioned_throughput = try( var.node_config.boot_disk.provisioned_throughput, null ) } image_type = var.node_config.image_type labels = var.k8s_labels resource_labels = var.labels local_ssd_count = var.node_config.local_ssd_count machine_type = var.node_config.machine_type metadata = local.node_metadata min_cpu_platform = var.node_config.min_cpu_platform node_group = var.sole_tenant_nodegroup oauth_scopes = local.service_account_scopes preemptible = var.node_config.preemptible service_account = local.service_account_email spot = ( var.node_config.spot == true && var.node_config.preemptible != true ) flex_start = var.node_config.flex_start tags = var.tags resource_manager_tags = var.resource_manager_tags dynamic "ephemeral_storage_config" { for_each = var.node_config.ephemeral_ssd_count != null ? [""] : [] content { local_ssd_count = var.node_config.ephemeral_ssd_count } } dynamic "ephemeral_storage_local_ssd_config" { for_each = var.node_config.ephemeral_storage_local_ssd_count != null ? [""] : [] content { local_ssd_count = var.node_config.ephemeral_storage_local_ssd_count } } dynamic "gcfs_config" { for_each = var.node_config.gcfs && local.image.is_cos_containerd ? [""] : [] content { enabled = true } } dynamic "guest_accelerator" { for_each = var.node_config.guest_accelerator != null ? [""] : [] content { count = var.node_config.guest_accelerator.count type = var.node_config.guest_accelerator.type gpu_partition_size = var.node_config.guest_accelerator.gpu_driver == null ? null : var.node_config.guest_accelerator.gpu_driver.partition_size dynamic "gpu_sharing_config" { for_each = try(var.node_config.guest_accelerator.gpu_driver.max_shared_clients_per_gpu, null) != null ? [""] : [] content { gpu_sharing_strategy = var.node_config.guest_accelerator.gpu_driver.max_shared_clients_per_gpu != null ? "TIME_SHARING" : null max_shared_clients_per_gpu = var.node_config.guest_accelerator.gpu_driver.max_shared_clients_per_gpu } } dynamic "gpu_driver_installation_config" { for_each = var.node_config.guest_accelerator.gpu_driver != null ? [""] : [] content { gpu_driver_version = var.node_config.guest_accelerator.gpu_driver.version } } } } dynamic "local_nvme_ssd_block_config" { for_each = coalesce(var.node_config.local_nvme_ssd_count, 0) > 0 ? [""] : [] content { local_ssd_count = var.node_config.local_nvme_ssd_count } } dynamic "gvnic" { for_each = var.node_config.gvnic && local.image.is_cos ? [""] : [] content { enabled = true } } dynamic "kubelet_config" { for_each = var.node_config.kubelet_config != null ? [""] : [] content { cpu_manager_policy = var.node_config.kubelet_config.cpu_manager_policy cpu_cfs_quota = var.node_config.kubelet_config.cpu_cfs_quota cpu_cfs_quota_period = var.node_config.kubelet_config.cpu_cfs_quota_period insecure_kubelet_readonly_port_enabled = var.node_config.kubelet_config.insecure_kubelet_readonly_port_enabled pod_pids_limit = var.node_config.kubelet_config.pod_pids_limit container_log_max_size = var.node_config.kubelet_config.container_log_max_size container_log_max_files = var.node_config.kubelet_config.container_log_max_files image_gc_low_threshold_percent = var.node_config.kubelet_config.image_gc_low_threshold_percent image_gc_high_threshold_percent = var.node_config.kubelet_config.image_gc_high_threshold_percent image_minimum_gc_age = var.node_config.kubelet_config.image_minimum_gc_age image_maximum_gc_age = var.node_config.kubelet_config.image_maximum_gc_age allowed_unsafe_sysctls = var.node_config.kubelet_config.allowed_unsafe_sysctls } } dynamic "linux_node_config" { for_each = var.node_config.linux_node_config != null ? [""] : [] content { sysctls = var.node_config.linux_node_config.sysctls cgroup_mode = try(var.node_config.linux_node_config.cgroup_mode, "CGROUP_MODE_UNSPECIFIED") } } dynamic "reservation_affinity" { for_each = var.reservation_affinity != null ? [""] : [] content { consume_reservation_type = var.reservation_affinity.consume_reservation_type key = var.reservation_affinity.key values = var.reservation_affinity.values } } dynamic "sandbox_config" { for_each = ( var.node_config.sandbox_config_gvisor == true && local.image.is_cos_containerd != null ? [""] : [] ) content { sandbox_type = "gvisor" } } dynamic "shielded_instance_config" { for_each = var.node_config.shielded_instance_config != null ? [""] : [] content { enable_secure_boot = var.node_config.shielded_instance_config.enable_secure_boot enable_integrity_monitoring = var.node_config.shielded_instance_config.enable_integrity_monitoring } } dynamic "taint" { for_each = local.taints content { key = taint.key value = taint.value.value effect = taint.value.effect } } dynamic "workload_metadata_config" { for_each = var.node_config.workload_metadata_config_mode != null ? [""] : [] content { mode = var.node_config.workload_metadata_config_mode } } dynamic "advanced_machine_features" { for_each = var.node_config.advanced_machine_features != null ? [""] : [] content { enable_nested_virtualization = var.node_config.advanced_machine_features.enable_nested_virtualization threads_per_core = var.node_config.advanced_machine_features.threads_per_core } } dynamic "containerd_config" { for_each = var.node_config.containerd_config != null ? [""] : [] content { dynamic "private_registry_access_config" { for_each = try(var.node_config.containerd_config.private_registry_access_config, null) != null ? [""] : [] content { enabled = ( length(try( var.node_config.containerd_config .private_registry_access_config .certificate_authority_domain_config, [] )) > 0 ) dynamic "certificate_authority_domain_config" { for_each = try( var.node_config.containerd_config .private_registry_access_config .certificate_authority_domain_config, [] ) content { fqdns = certificate_authority_domain_config.value.fqdns gcp_secret_manager_certificate_config { secret_uri = ( certificate_authority_domain_config.value .gcp_secret_manager_certificate_config_secret_uri ) } } } } } dynamic "writable_cgroups" { for_each = var.node_config.containerd_config.writable_cgroups != null ? [""] : [] content { enabled = var.node_config.containerd_config.writable_cgroups } } dynamic "registry_hosts" { for_each = try(var.node_config.containerd_config.registry_hosts, {}) content { server = registry_hosts.key dynamic "hosts" { for_each = registry_hosts.value.hosts content { host = hosts.key capabilities = hosts.value.capabilities override_path = hosts.value.override_path dial_timeout = hosts.value.dial_timeout dynamic "header" { for_each = coalesce(hosts.value.header, {}) content { key = header.key value = header.value } } dynamic "ca" { for_each = ( hosts.value.ca_gcp_secret_manager_secret_uri != null ? [hosts.value.ca_gcp_secret_manager_secret_uri] : [] ) content { gcp_secret_manager_secret_uri = ca.value } } dynamic "client" { for_each = ( hosts.value.client != null ? [hosts.value.client] : [] ) content { cert { gcp_secret_manager_secret_uri = ( client.value.cert_gcp_secret_manager_secret_uri ) } dynamic "key" { for_each = ( client.value.key_gcp_secret_manager_secret_uri != null ? [client.value.key_gcp_secret_manager_secret_uri] : [] ) content { gcp_secret_manager_secret_uri = key.value } } } } } } } } } } } }