TerraformPilot

Terraform

GCP GKE Kubernetes Cluster with Terraform

Deploy Google Kubernetes Engine (GKE) clusters with Terraform. Autopilot and Standard modes, node pools, networking, and workload identity.

LLuca Berton1 min read

Quick Answer

#
resource "google_container_cluster" "main" {
  name     = "my-cluster"
  location = "us-central1"
  enable_autopilot = true
  network    = google_compute_network.main.id
  subnetwork = google_compute_subnetwork.main.id
}
#
resource "google_container_cluster" "autopilot" {
  name     = "${var.project}-cluster"
  location = var.region
 
  enable_autopilot = true
 
  network    = google_compute_network.main.id
  subnetwork = google_compute_subnetwork.main.id
 
  ip_allocation_policy {
    cluster_secondary_range_name  = "pods"
    services_secondary_range_name = "services"
  }
 
  private_cluster_config {
    enable_private_nodes    = true
    enable_private_endpoint = false
    master_ipv4_cidr_block  = "172.16.0.0/28"
  }
 
  release_channel {
    channel = "REGULAR"
  }
 
  deletion_protection = false  # Set true in production
}

GKE Standard with Node Pools

#
resource "google_container_cluster" "standard" {
  name     = "${var.project}-cluster"
  location = var.region
 
  # Remove default node pool and manage separately
  remove_default_node_pool = true
  initial_node_count       = 1
 
  network    = google_compute_network.main.id
  subnetwork = google_compute_subnetwork.main.id
 
  ip_allocation_policy {
    cluster_secondary_range_name  = "pods"
    services_secondary_range_name = "services"
  }
 
  private_cluster_config {
    enable_private_nodes    = true
    enable_private_endpoint = false
    master_ipv4_cidr_block  = "172.16.0.0/28"
  }
 
  workload_identity_config {
    workload_pool = "${var.gcp_project}.svc.id.goog"
  }
 
  release_channel {
    channel = "REGULAR"
  }
 
  deletion_protection = false
}
 
resource "google_container_node_pool" "general" {
  name       = "general"
  cluster    = google_container_cluster.standard.name
  location   = var.region
  node_count = 2
 
  autoscaling {
    min_node_count = 1
    max_node_count = 5
  }
 
  node_config {
    machine_type = "e2-standard-4"
    disk_size_gb = 50
    disk_type    = "pd-standard"
 
    oauth_scopes = [
      "https://www.googleapis.com/auth/cloud-platform",
    ]
 
    labels = {
      environment = var.environment
      pool        = "general"
    }
 
    workload_metadata_config {
      mode = "GKE_METADATA"
    }
  }
 
  management {
    auto_repair  = true
    auto_upgrade = true
  }
}
 
resource "google_container_node_pool" "spot" {
  name     = "spot"
  cluster  = google_container_cluster.standard.name
  location = var.region
 
  autoscaling {
    min_node_count = 0
    max_node_count = 10
  }
 
  node_config {
    machine_type = "e2-standard-4"
    spot         = true
    disk_size_gb = 50
 
    labels = { pool = "spot" }
    taint {
      key    = "spot"
      value  = "true"
      effect = "NO_SCHEDULE"
    }
  }
}

Networking

#
resource "google_compute_network" "main" {
  name                    = "${var.project}-vpc"
  auto_create_subnetworks = false
}
 
resource "google_compute_subnetwork" "main" {
  name          = "${var.project}-subnet"
  ip_cidr_range = "10.0.0.0/20"
  region        = var.region
  network       = google_compute_network.main.id
 
  secondary_ip_range {
    range_name    = "pods"
    ip_cidr_range = "10.4.0.0/14"
  }
 
  secondary_ip_range {
    range_name    = "services"
    ip_cidr_range = "10.8.0.0/20"
  }
}

Connect kubectl

#
gcloud container clusters get-credentials $(terraform output -raw cluster_name) \
  --region $(terraform output -raw region) \
  --project $(terraform output -raw project)

Autopilot vs Standard

#
FeatureAutopilotStandard
Node managementGoogle-managedYou manage
PricingPer pod resourcesPer node
Node poolsAutomaticManual
GPU/TPUSupportedFull control
Best forMost workloadsCustom requirements
#

Conclusion

#

Use Autopilot for most workloads — Google manages nodes, scaling, and security. Use Standard mode when you need GPUs, spot instances, or custom node configurations. Always use private clusters, Workload Identity, and VPC-native networking.

#Terraform#GCP#GKE#Kubernetes#Infrastructure as Code

Share this article