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
| Name | Version |
|---|---|
| terraform | >= 1.9 |
| kosmos | >= 0.9.3 |
Artifacts
Download the Terraform module from the Terraform Artifacts page:
| Artifact | Version |
|---|---|
| GKE (Google Cloud Platform) Module | v4.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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| fleet_name | string | ✓ | - | Kosmos fleet name where the GKE cluster will be registered |
| cluster_name | string | ✓ | - | Name of the GKE cluster to be created |
| kosmos_user | string | ✓ | - | Kosmos user ID to be registered as the owner of the GKE cluster |
| gcp_region | string | ✓ | - | GCP region where the resources will be created |
| gcp_project_id | string | ✓ | - | GCP project where the GKE cluster will be created |
| gcp_workload_identity_pool_id | string | ✓ | - | Workload Identity Pool ID for Kosmos assumed role |
| gcp_workload_identity_provider_id | string | ✓ | - | Workload Identity Provider ID for Kosmos assumed role |
| gke_version_major | string | ✓ | - | Major version to be used as GKE cluster’s version |
| bastion_authorized_networks | list(string) | ✓ | - | CIDR blocks where the bastion host is accessible from |
| network_name | string | ✓ | - | Name of the VPC network to be created and used |
| gke_master_authorized_networks | list(object) | ✓ | [] | CIDR blocks where the GKE cluster is accessible from |
| node_pools | list(object) | ✓ | [] | Node pools to be added to the cluster |
| create_new_workload_identity_pool | bool | - | true | Creates a new workload identity pool if true |
| bastion_subnet_range_ip | string | - | "10.1.0.0/16" | IP range for the bastion instance’s subnet |
| bastion_ssh_port | number | - | 10910 | Port used to SSH into the bastion host |
| bastion_os_image | string | - | "ubuntu-os-cloud/ubuntu-2004-lts" | GCP OS image used for the bastion host |
| bastion_machine_type | string | - | "e2-micro" | Bastion instance’s GCP VM size |
| bastion_network_tag | string | - | "bastion-server" | Bastion instance’s attached network tag |
| gke_cluster_ipv4cidr | string | - | "172.16.0.0/16" | IP range for the GKE’s internal K8s networking |
| gke_subnet_range_ip | string | - | "10.2.0.0/16" | IP range for the GKE nodes' subnet |
| gke_release_channel | string | - | "REGULAR" | GKE Release channel for K8s minor version selection |
| kosmos_tier | string | - | null | Kosmos environment tier (dev, stg, or null for PRD) |
| enable_cloud_nat | bool | - | true | Decides on whether to create a Cloud NAT for the GKE subnet |
| cloud_nat_ip_address_name | string | - | "kosmos-whitelisted-ip" | Name of the reserved IP for Cloud NAT |
| create_vpc | bool | - | true | Whether to create a new VPC alongside subnets |
| gke_subnet_name | string | - | "gke-subnet-1" | Existing subnet name (required if create_vpc = false) |
| bastion_subnet_name | string | - | "bastion-subnet-1" | Existing bastion subnet name (required if create_vpc = false) |
| add_suffix_on_workload_id_names | bool | - | false | Whether to add a suffix to workload ID pool and provider names |
| additional_node_firewall_rules | any | - | {} | Map of additional firewall rules for GKE node pool network tag |
| bastion_desired_status | string | - | "TERMINATED" | Decides the Bastion VM’s state such as running or shut-down |
| bastion_static_ip_name | string | - | null | Name of the reserved static IP for the Bastion host instance |
| enable_network_policy | bool | - | false | Enables network policy support from GKE for the cluster |
| gke_maintenance_window | string | - | "" | Start time for 4-hour window where GKE can do maintenance |
| workload_sa_name_prefix | string | - | "kosmos-operator" | Prefix for the created Service Account used by Kosmos |
Outputs
| Name | Type | Description |
|---|---|---|
| cluster_name | string | Name of the created GKE cluster |
| network_id | string | ID of the created VPC network |
| workload_identity_pool_id | string | ID of the created workload identity pool containing Kosmos' OIDC details |
| workload_identity_pool_provider_id | string | ID of the created workload identity provider containing Kosmos' OIDC details |
| service_account_email | string | Email of the service account assumed by Kosmos for the GKE cluster creation |
| bastion_instance_internal_ip | string | Internal IP address of the Bastion instance |
| bastion_instance_external_ip | string | External IP address of the Bastion instance |
| kms_key_ring_id | string | KMS key ring ID used by the created GKE cluster |
| kms_crypto_key_id | string | KMS crypto key ID used by the created GKE cluster |
| gke_nodes_network_tag | string | Network tag assigned to the nodes of the created cluster, can be used for additional firewall rules |
| bastion_server_network_tag | string | Network 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
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
- Service Account Management
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)
- Bastion Host Management
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
- Secret Encryption
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
- Separation of Key
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
- Ensure that check whether NAT is not connected to the private subnet
- NAT Association Management
- 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
- Ensure that Descriptions of all Firewall Ingress / Egress rules are set.
violation is due to GKE’s automatically created firewall rules , the created rules don’t have any description
- Ensure that Descriptions of all Firewall Ingress / Egress rules are set.
- Ingress/Egress Rule Management
- VPC Management
Required Permissions
The following GCP permissions are required to use this module:
Compute Engine
compute.disks.create,compute.disks.deletecompute.firewalls.create,compute.firewalls.deletecompute.images.get,compute.images.usecompute.instances.create,compute.instances.deletecompute.networks.create,compute.networks.deletecompute.networks.get,compute.networks.usecompute.routes.create,compute.routes.deletecompute.routers.create,compute.routers.deletecompute.routers.get,compute.routers.updatecompute.subnetworks.create,compute.subnetworks.deletecompute.subnetworks.get,compute.subnetworks.use
KMS
cloudkms.cryptoKeys.create,cloudkms.cryptoKeys.deletecloudkms.cryptoKeys.get,cloudkms.cryptoKeys.setIamPolicycloudkms.cryptoKeys.usecloudkms.keyRings.create,cloudkms.keyRings.deletecloudkms.keyRings.get,cloudkms.keyRings.use
GKE (Kubernetes Engine)
container.clusters.create,container.clusters.deletecontainer.clusters.getcontainer.nodePools.create,container.nodePools.deletecontainer.operations.get,container.versions.get
IAM
iam.serviceAccounts.create,iam.serviceAccounts.deleteiam.serviceAccounts.get,iam.serviceAccounts.setIamPolicyiam.workloadIdentityPoolProviders.createiam.workloadIdentityPoolProviders.deleteiam.workloadIdentityPoolProviders.getiam.workloadIdentityPools.createiam.workloadIdentityPools.deleteiam.workloadIdentityPools.get
Resource Manager
resourcemanager.projects.getresourcemanager.projects.getIamPolicyresourcemanager.projects.setIamPolicy