Skip to content

Instantly share code, notes, and snippets.

@soeirosantos
Last active April 8, 2021 04:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soeirosantos/3aee78d4c21d6f14bf7f50ca2fffd5c6 to your computer and use it in GitHub Desktop.
Save soeirosantos/3aee78d4c21d6f14bf7f50ca2fffd5c6 to your computer and use it in GitHub Desktop.
This is an example of how to create a GKE cluster with some sensible defaults and best practices for security.

Terraform GKE example / security best practices

This is an example of how to create a GKE cluster with some sensible defaults and best practices for security.

Please, notice that this example contains the minimum security configuration that you can get without impacting other features, requiring additional network config, or the installation of third-party tools.

Security items covered in this example:

  • Auto upgrades using regular release channel
  • Shielded GKE Nodes
  • Hardened node image with the containerd runtime
  • Workload Identity
  • Least privileged Google service account

If you are looking for a more thorough approach to secure your GKE cluster take a look at the Hardening your cluster's security GKE doc.

provider "google" {
project = var.project_id
region = var.region
version = "~> 3.50"
}
provider "google-beta" {
project = var.project_id
region = var.region
version = "~> 3.50"
}
data "google_project" "project" {}
data "google_compute_network" "network" {
name = var.network
}
data "google_compute_subnetwork" "subnetwork" {
name = var.subnetwork
region = var.region
}
resource "random_id" "id" {
byte_length = 4
}
resource "google_container_cluster" "cluster" {
# required for the gce_persistent_disk_csi_driver_config addon
provider = google-beta
name = "${var.cluster_name}-${random_id.id.hex}"
network = data.google_compute_network.network.name
subnetwork = data.google_compute_subnetwork.subnetwork.name
location = var.region
master_auth {
username = ""
password = ""
client_certificate_config {
issue_client_certificate = false
}
}
initial_node_count = 1
logging_service = "logging.googleapis.com/kubernetes"
monitoring_service = "monitoring.googleapis.com/kubernetes"
ip_allocation_policy {
services_ipv4_cidr_block = "/16"
cluster_ipv4_cidr_block = "/14"
}
release_channel {
channel = "REGULAR"
}
maintenance_policy {
recurring_window {
start_time = "2000-01-01T10:00:00-05:00"
end_time = "2000-01-01T16:00:00-05:00"
recurrence = "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH"
}
}
resource_labels = {
managed = "1"
managed_by = "terraform"
}
remove_default_node_pool = true
workload_identity_config {
identity_namespace = "${var.project_id}.svc.id.goog"
}
enable_shielded_nodes = true
addons_config {
horizontal_pod_autoscaling {
disabled = false
}
http_load_balancing {
disabled = false
}
gce_persistent_disk_csi_driver_config {
enabled = true
}
}
}
resource "google_container_node_pool" "node-pool" {
name = "default-pool"
location = var.region
cluster = google_container_cluster.cluster.name
initial_node_count = 1
node_config {
machine_type = var.machine_type
image_type = "cos_containerd"
preemptible = false
disk_size_gb = 100
service_account = google_service_account.gke-cluster.email
workload_metadata_config {
node_metadata = "GKE_METADATA_SERVER"
}
metadata = {
disable-legacy-endpoints = "true"
}
}
management {
auto_repair = true
auto_upgrade = true
}
upgrade_settings {
max_surge = 2
max_unavailable = 0
}
autoscaling {
min_node_count = 1
max_node_count = 5
}
}
resource "google_service_account" "gke-cluster" {
account_id = "gke-cluster-sa-${random_id.id.hex}"
display_name = "gke-cluster-sa"
}
resource "google_project_iam_member" "log-writer" {
member = "serviceAccount:${google_service_account.gke-cluster.email}"
role = "roles/logging.logWriter"
}
resource "google_project_iam_member" "metric-writer" {
member = "serviceAccount:${google_service_account.gke-cluster.email}"
role = "roles/monitoring.metricWriter"
}
resource "google_project_iam_member" "monitoring-viewer" {
member = "serviceAccount:${google_service_account.gke-cluster.email}"
role = "roles/monitoring.viewer"
}
resource "google_project_iam_member" "storage-object-viewer" {
member = "serviceAccount:${google_service_account.gke-cluster.email}"
role = "roles/storage.objectViewer"
}
resource "google_project_iam_member" "stackdriver-resource-metadata-writer" {
member = "serviceAccount:${google_service_account.gke-cluster.email}"
role = "roles/stackdriver.resourceMetadata.writer"
}
resource "google_project_iam_member" "cloudtrace-agent" {
member = "serviceAccount:${google_service_account.gke-cluster.email}"
role = "roles/cloudtrace.agent"
}
resource "google_project_iam_member" "cloudprofiler-agent" {
member = "serviceAccount:${google_service_account.gke-cluster.email}"
role = "roles/cloudprofiler.agent"
}
resource "google_project_iam_member" "service-controller" {
member = "serviceAccount:${google_service_account.gke-cluster.email}"
role = "roles/servicemanagement.serviceController"
}
variable "project_id" {
type = string
default = "changeme"
}
variable "region" {
type = string
description = "region"
default = "us-east1"
}
variable "subnetwork" {
type = string
description = "subnetwork"
default = "changeme"
}
variable "network" {
type = string
description = "network"
default = "changeme"
}
variable "cluster_name" {
type = string
description = " Cluster name"
default = "changeme"
}
variable "machine_type" {
type = string
description = "Machine type"
default = "changeme"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment