GKE Cluster Module - Reference Guide

Overview

The Kosmos GKE Cluster module creates a production-ready GKE cluster using the Kosmos Provider, conforming to Samsung Security Checklist requirements (GCP Security Checklist v2.0.2).

Requirements

NameVersion
terraform>= 1.9
kosmos>= 0.9.3

Artifacts

Download the Terraform module from the Terraform Artifacts page:

ArtifactVersion
GKE (Google Cloud Platform) Modulev4.1.2

Prerequisites

See full guide prerequisites for required setup (GCP APIs, credentials, Kosmos provider, and platform IP whitelist).

Quick Start

module "gke_cluster" {
  source = "https://srin-s3-terraform-modules.s3.ap-southeast-1.amazonaws.com/terraform-kosmos-gke-vX.Y.Z.tar.gz"

  fleet_name                        = "my-fleet"
  kosmos_user                       = "kosmosuser"
  gcp_region                        = "asia-southeast1"
  cluster_name                      = "my-gke-cluster"
  gcp_project_id                    = "your-gcp-project-id"
  bastion_authorized_networks       = ["YOUR_IP/32"]
  network_name                      = "kosmos-gke-network"
  gcp_workload_identity_pool_id     = "ksms-pool"
  gcp_workload_identity_provider_id = "ksms-prov"
  workload_sa_name_prefix           = "kosmos"
  gke_version_major                 = "1.31"

  # Kosmos platform IPs required for cluster management
  gke_master_authorized_networks = [
    { cidr_block = "3.208.49.242/32", display_name = "kosmos-1" },
    { cidr_block = "35.172.72.171/32", display_name = "kosmos-2" },
    { cidr_block = "34.214.188.139/32", display_name = "kosmos-3" },
    { cidr_block = "35.165.241.214/32", display_name = "kosmos-4" },
    { cidr_block = "13.209.31.187/32", display_name = "kosmos-5" },
    { cidr_block = "15.165.61.114/32", display_name = "kosmos-6" },
    { cidr_block = "YOUR_IP/32", display_name = "your-access" },
  ]

  node_pools = [
    {
      name               = "default-pool"
      initial_node_count = 1
      config             = {}
      autoscaling        = { enabled = false }
      max_pods_constraint = 110
      management         = {}
    }
  ]
}

Inputs

NameTypeRequiredDefaultDescription
fleet_namestring-Kosmos fleet name where the GKE cluster will be registered
cluster_namestring-Name of the GKE cluster to be created
kosmos_userstring-Kosmos user ID to be registered as the owner of the GKE cluster
gcp_regionstring-GCP region where the resources will be created
gcp_project_idstring-GCP project where the GKE cluster will be created
gcp_workload_identity_pool_idstring-Workload Identity Pool ID for Kosmos assumed role
gcp_workload_identity_provider_idstring-Workload Identity Provider ID for Kosmos assumed role
gke_version_majorstring-Major version to be used as GKE cluster’s version
bastion_authorized_networkslist(string)-CIDR blocks where the bastion host is accessible from
network_namestring-Name of the VPC network to be created and used
gke_master_authorized_networkslist(object)[]CIDR blocks where the GKE cluster is accessible from
node_poolslist(object)[]Node pools to be added to the cluster
create_new_workload_identity_poolbool-trueCreates a new workload identity pool if true
bastion_subnet_range_ipstring-"10.1.0.0/16"IP range for the bastion instance’s subnet
bastion_ssh_portnumber-10910Port used to SSH into the bastion host
bastion_os_imagestring-"ubuntu-os-cloud/ubuntu-2004-lts"GCP OS image used for the bastion host
bastion_machine_typestring-"e2-micro"Bastion instance’s GCP VM size
bastion_network_tagstring-"bastion-server"Bastion instance’s attached network tag
gke_cluster_ipv4cidrstring-"172.16.0.0/16"IP range for the GKE’s internal K8s networking
gke_subnet_range_ipstring-"10.2.0.0/16"IP range for the GKE nodes' subnet
gke_release_channelstring-"REGULAR"GKE Release channel for K8s minor version selection
kosmos_tierstring-nullKosmos environment tier (dev, stg, or null for PRD)
enable_cloud_natbool-trueDecides on whether to create a Cloud NAT for the GKE subnet
cloud_nat_ip_address_namestring-"kosmos-whitelisted-ip"Name of the reserved IP for Cloud NAT
create_vpcbool-trueWhether to create a new VPC alongside subnets
gke_subnet_namestring-"gke-subnet-1"Existing subnet name (required if create_vpc = false)
bastion_subnet_namestring-"bastion-subnet-1"Existing bastion subnet name (required if create_vpc = false)
add_suffix_on_workload_id_namesbool-falseWhether to add a suffix to workload ID pool and provider names
additional_node_firewall_rulesany-{}Map of additional firewall rules for GKE node pool network tag
bastion_desired_statusstring-"TERMINATED"Decides the Bastion VM’s state such as running or shut-down
bastion_static_ip_namestring-nullName of the reserved static IP for the Bastion host instance
enable_network_policybool-falseEnables network policy support from GKE for the cluster
gke_maintenance_windowstring-""Start time for 4-hour window where GKE can do maintenance
workload_sa_name_prefixstring-"kosmos-operator"Prefix for the created Service Account used by Kosmos

Outputs

NameTypeDescription
cluster_namestringName of the created GKE cluster
network_idstringID of the created VPC network
workload_identity_pool_idstringID of the created workload identity pool containing Kosmos' OIDC details
workload_identity_pool_provider_idstringID of the created workload identity provider containing Kosmos' OIDC details
service_account_emailstringEmail of the service account assumed by Kosmos for the GKE cluster creation
bastion_instance_internal_ipstringInternal IP address of the Bastion instance
bastion_instance_external_ipstringExternal IP address of the Bastion instance
kms_key_ring_idstringKMS key ring ID used by the created GKE cluster
kms_crypto_key_idstringKMS crypto key ID used by the created GKE cluster
gke_nodes_network_tagstringNetwork tag assigned to the nodes of the created cluster, can be used for additional firewall rules
bastion_server_network_tagstringNetwork tag assigned to the created bastion instance, can be used for allowing access to other instances

Examples

Basic Usage

module "gke_cluster" {
  source = "https://srin-s3-terraform-modules.s3.ap-southeast-1.amazonaws.com/terraform-kosmos-gke-vX.Y.Z.tar.gz"

  fleet_name                        = "production-fleet"
  kosmos_user                       = "admin-user"
  gcp_region                        = "asia-southeast1"
  cluster_name                      = "prod-gke-cluster"
  gcp_project_id                    = "your-gcp-project-id"
  bastion_authorized_networks       = ["YOUR_IP/32"]
  network_name                      = "kosmos-gke-network"
  gcp_workload_identity_pool_id     = "ksms-pool"
  gcp_workload_identity_provider_id = "ksms-prov"
  workload_sa_name_prefix           = "kosmos"
  gke_version_major                 = "1.31"
  gke_release_channel               = "REGULAR"

  # Include Kosmos platform IPs - see Quick Start example above
  gke_master_authorized_networks    = [...]

  node_pools = [...]
}

Custom VPC Usage

module "gke_cluster" {
  source = "https://srin-s3-terraform-modules.s3.ap-southeast-1.amazonaws.com/terraform-kosmos-gke-vX.Y.Z.tar.gz"

  # Use existing VPC instead of creating new one
  create_vpc          = false
  gke_subnet_name     = "existing-gke-subnet"
  bastion_subnet_name = "existing-bastion-subnet"
  network_name        = "existing-vpc"

  fleet_name                        = "staging-fleet"
  kosmos_user                       = "dev-team"
  gcp_region                        = "asia-southeast1"
  cluster_name                      = "staging-gke-cluster"
  gcp_project_id                    = "your-gcp-project-id"
  bastion_authorized_networks       = ["YOUR_IP/32"]
  gcp_workload_identity_pool_id     = "ksms-pool"
  gcp_workload_identity_provider_id = "ksms-prov"
  workload_sa_name_prefix           = "kosmos"
  gke_version_major                 = "1.31"

  # Include Kosmos platform IPs - see Quick Start example above
  gke_master_authorized_networks    = [...]

  node_pools = [...]
}

Advanced Configuration

module "gke_cluster" {
  source = "https://srin-s3-terraform-modules.s3.ap-southeast-1.amazonaws.com/terraform-kosmos-gke-vX.Y.Z.tar.gz"

  fleet_name                        = "advanced-fleet"
  kosmos_user                       = "platform-team"
  gcp_region                        = "asia-southeast1"
  cluster_name                      = "advanced-gke-cluster"
  gcp_project_id                    = "your-gcp-project-id"
  bastion_authorized_networks       = ["YOUR_IP/32"]
  network_name                      = "kosmos-gke-network"
  gcp_workload_identity_pool_id     = "ksms-pool"
  gcp_workload_identity_provider_id = "ksms-prov"
  workload_sa_name_prefix           = "kosmos"
  gke_version_major                 = "1.31"

  # Include Kosmos platform IPs - see Quick Start example above
  gke_master_authorized_networks    = [...]

  # Custom node pools with autoscaling
  node_pools = [
    {
      name               = "worker-nodes"
      initial_node_count = 2
      config             = {}
      autoscaling = {
        enabled        = true
        min_node_count = 2
        max_node_count = 10
      }
      max_pods_constraint = 110
      management         = {}
    }
  ]

  # Custom bastion configuration
  bastion_machine_type = "e2-small"
  bastion_ssh_port     = 2222
  bastion_os_image     = "ubuntu-os-cloud/ubuntu-2004-lts"

  # Custom networking
  gke_cluster_ipv4cidr    = "172.20.0.0/16"
  gke_subnet_range_ip     = "10.20.0.0/16"
  bastion_subnet_range_ip = "10.21.0.0/16"

  # Extra node pool firewall rule
  additional_node_firewall_rules = {
    "allow-all-egress-temp" = {
      direction          = "EGRESS"
      description        = "Allow outbound traffic"
      destination_ranges = ["0.0.0.0/0"]
      allow = {
        "allow-all-ports" = {
          protocol = "all"
        }
      }
    }
  }
}

Resources Created

kosmos-gke

GCP Resources

  • VPC: Custom network with subnets for GKE and bastion
  • Bastion Host: Compute Engine instance for secure cluster access
  • KMS: Keyring and crypto key for encryption
  • GKE Cluster: Kubernetes cluster with private configuration
  • Service Account: IAM service account for cluster management
  • Workload Identity: Pool and provider for Kosmos integration

Kosmos Resources

  • GKE Cluster: Kubernetes cluster registered with Kosmos
  • Security Configuration: Bastion and network security groups

Security Features

This module implements the following security measures:

  • Private Cluster: GKE cluster with private nodes and control plane
  • Bastion Access: Secure SSH access through bastion host only
  • Network Security: VPC with restricted access and firewall rules
  • Encryption: KMS-based encryption for cluster secrets
  • Access Control: Workload Identity for secure service-to-service communication
  • Compliance: Samsung Security Checklist v2.0.2 compliance

Security Checklist

List of checklist that conform the Samsung Security Checklist

  • IAM

    • Service Account Management
      • Mandatory Description for purpose of use
  • Computing

    • Bastion Host Management
      • Mandatory Label (Ensure that the required labels are set for bastion host)
      • Prohibition of use other than SSH/RDP services (Disable default SSH port 22 and use another port)
      • Restriction of SSH/RDP Network Path (Ensure that all instances in the GCP are configured for SSH connection only through the Bastion Host)
      • Ingress Restriction (Ensure that the Bastion Host are restricted to connect only from the corporate network)
  • Serverless

    • Secret Encryption
      • Check that Application Layer secrets encryption is enabled
    • Kubernetes Management
      • Enable Private Cluster
      • Cluster API endpoint (Ensure that whether access control for Cluster Endpoint is set and managed)
      • Dedicated GKE subnet
  • KMS

    • Separation of Key
      • Mandatory label (Key: “Sec_assets_kms”, Value: Descriptions for key usages)
    • Key Rotation
      • Check that Key Rotation Period is set to 90 days

List of checklist that does not conform to the Samsung Security Checklist

  • Network
    • VPC Management
      • NAT Association Management
        • Ensure that check whether NAT is not connected to the private subnet

          violation is due to NAT gateway being needed for GKE cluster to connect towards Kosmos' control plane & to pull container images

    • Firewall Management
      • Ingress/Egress Rule Management
        • “0.0.0.0/0” or “::/0” is registered in the IP (SourceRanges or DestinationRanges) value.
        • IP (SourceRanges or DestinationRanges) values cannot exceed a 24-bit mask.

          both violations are due to firewall rules created by GKE automatically , and firewall rule that allows outbound access towards Kosmos & the internet to pull container images

      • Descriptions for Firewall rule

Required Permissions

The following GCP permissions are required to use this module:

Compute Engine

  • compute.disks.create, compute.disks.delete
  • compute.firewalls.create, compute.firewalls.delete
  • compute.images.get, compute.images.use
  • compute.instances.create, compute.instances.delete
  • compute.networks.create, compute.networks.delete
  • compute.networks.get, compute.networks.use
  • compute.routes.create, compute.routes.delete
  • compute.routers.create, compute.routers.delete
  • compute.routers.get, compute.routers.update
  • compute.subnetworks.create, compute.subnetworks.delete
  • compute.subnetworks.get, compute.subnetworks.use

KMS

  • cloudkms.cryptoKeys.create, cloudkms.cryptoKeys.delete
  • cloudkms.cryptoKeys.get, cloudkms.cryptoKeys.setIamPolicy
  • cloudkms.cryptoKeys.use
  • cloudkms.keyRings.create, cloudkms.keyRings.delete
  • cloudkms.keyRings.get, cloudkms.keyRings.use

GKE (Kubernetes Engine)

  • container.clusters.create, container.clusters.delete
  • container.clusters.get
  • container.nodePools.create, container.nodePools.delete
  • container.operations.get, container.versions.get

IAM

  • iam.serviceAccounts.create, iam.serviceAccounts.delete
  • iam.serviceAccounts.get, iam.serviceAccounts.setIamPolicy
  • iam.workloadIdentityPoolProviders.create
  • iam.workloadIdentityPoolProviders.delete
  • iam.workloadIdentityPoolProviders.get
  • iam.workloadIdentityPools.create
  • iam.workloadIdentityPools.delete
  • iam.workloadIdentityPools.get

Resource Manager

  • resourcemanager.projects.get
  • resourcemanager.projects.getIamPolicy
  • resourcemanager.projects.setIamPolicy

Download the full example

Edit this page on GitHub