Deploying a GKE cluster through the Cloud Console is fine for experimentation, but for production you want it in code. Terraform gives you repeatable, version-controlled GKE deployments that you can review, test, and roll back. GKE clusters have a lot of configuration options, and getting them right matters. A misconfigured cluster can be insecure, expensive, or both. This guide walks through deploying a production-ready GKE cluster with Terraform, focusing on the decisions that actually matter. The operational reality of running Kubernetes in Google Cloud shifts when infrastructure is defined declaratively. Manual console clicks produce clusters that are hard to audit, hard to reproduce, and hard to recover. Infrastructure as Code closes that gap by making the entire control plane, network, node pools, and supporting services describeable as a single source of truth. The approach described across the reference materials centers on Terraform as the orchestration layer, with Google Cloud as the execution target, and GKE as the workload platform. The emphasis is on repeatability, collaboration, and security boundaries that are enforced before the first node is provisioned. The materials highlight VPC creation, private subnets, Cloud Router and Cloud NAT, firewall rules for SSH access, remote state in Google Cloud Storage, provider declaration, control plane configuration, and multiple node pools created with best practices for security and scalability. The resulting system is a fully functional GKE cluster deployed on GCP, orchestrated with Terraform, following industry best practices.
Prerequisites and API Enablement
Before starting, make sure you have:
- Terraform 1.5 or later installed
- The Google Cloud Terraform provider configured
- The Kubernetes Engine API enabled in your project
- A service account with at least the Kubernetes Engine Admin role
The prerequisites are not ceremonial. Terraform 1.5 or later installed ensures compatibility with modern provider schemas and state handling. The Google Cloud Terraform provider configured means authentication, project selection, and region defaults are resolvable without interactive prompts. The Kubernetes Engine API enabled in your project is a hard gate; without it the google_container_cluster resource fails at plan time. A service account with at least the Kubernetes Engine Admin role provides the permissions necessary to create clusters, node pools, and associated Compute Engine resources.
Enable the required APIs:
bash
gcloud services enable \
container.googleapis.com \
compute.googleapis.com \
binaryauthorization.googleapis.com
Enabling container.googleapis.com activates the GKE control plane APIs. compute.googleapis.com is required for VPC, subnets, node VMs, and Cloud Router/NAT. binaryauthorization.googleapis.com is referenced in the enablement command and relates to workload attestation and deployment policy enforcement. The impact of missing any of these APIs is a failed Terraform apply with opaque permission errors. The contextual layer is that API enablement is a project-level change, not a resource-level change, so it precedes any Terraform run and must be performed once per project.
VPC Network Foundations
GKE clusters need a VPC network
The VPC is the foundation for all network traffic inside the cluster. A VPC network provides isolation, IP address management, and routing control for node-to-node and pod-to-service communication. Creating a VPC network with Terraform ensures the network exists before the cluster is attempted, avoiding race conditions and implicit network creation with default settings. The reference materials walk through the process of creating a Virtual Private Cloud using Terraform, ensuring that the infrastructure is ready for the subsequent deployment of a GKE cluster.
In practice, the VPC definition interacts directly with node pool placement, private node configuration, and firewall rules. A misconfigured VPC can expose nodes to the internet unintentionally or prevent nodes from reaching Google APIs. The contextual connection is that VPC creation precedes subnet creation, which precedes node pool creation, which precedes cluster creation.
Remote State Management and Collaboration
Managing infrastructure manually can be error-prone, challenging to collaborate on, and lacks the scalability needed for modern cloud environments. Deploying a Kubernetes cluster requires a systematic approach, and using Terraform for Infrastructure as Code is the solution. This tutorial addresses the challenges of:
- Local State Management: Avoiding the pitfalls of managing Terraform state locally on individual machines.
- Collaboration: Enabling effective collaboration among team members by utilizing remote storage for Terraform state.
- Best Practices: Demonstrating the best practices for setting up GCP infrastructure, from VPC creation to GKE clusters, while ensuring security and scalability.
To ensure seamless collaboration, we'll configure Terraform to use Google Cloud Storage as a backend for storing state
This approach provides a centralized location for managing Terraform state, making it easier to collaborate and avoid accidental infrastructure destruction.
Remote state in GCS eliminates the classic local state problem where two engineers run terraform apply with divergent state files. The impact is reduced drift and fewer accidental destroys. Collaboration is enabled because state locking and versioning are provided by GCS. The best practices layer extends to naming conventions, variable isolation, and module reuse for VPC, subnet, router, NAT, and firewall.
Provider Declaration and Infrastructure as Code
Declare the Terraform provider for GCP, which acts as the library for creating and managing infrastructure in the Google Cloud Platform environment.
The provider declaration is the bridge between Terraform configurations and Google Cloud APIs, letting you declaratively define infrastructure resources, such as virtual machines and networks. It serves as the contract for resource schemas, authentication, and API versioning. Without a correct provider block, no google_container_cluster or google_compute_network can be interpreted.
The impact for operators is that provider pinning prevents surprise breaking changes. The contextual layer is that provider configuration sits at the top of every configuration, and all downstream resources depend on it.
Private Networking Components
Step-by-step guide on creating a private subnet for Kubernetes nodes, setting up a Cloud Router for route advertisement, implementing Cloud NAT for internet access, and creating a firewall to control SSH access.
A private subnet for Kubernetes nodes ensures nodes do not receive public IPs by default, reducing attack surface. Cloud Router for route advertisement propagates routes to VPC and enables hybrid connectivity. Cloud NAT for internet access allows private nodes to reach external package repositories and APIs without public IPs. A firewall to control SSH access restricts administrative access to a narrow set of CIDRs or bastion hosts.
The real-world consequence is a cluster that can be operated securely in a zero-trust model. The contextual connection is that these network primitives are created before the GKE cluster, and the cluster references them via network and subnetwork arguments.
Control Plane and Node Pool Configuration
Configure the GKE cluster's control plane and create multiple node pools using Terraform, adhering to best practices for security and scalability.
Control plane configuration includes location type, autopilot versus standard, release channel, and authentication settings. Node pool creation involves machine type, disk size, autoscaling, preemptible settings, taints, labels, and node metadata. Multiple node pools enable workload segregation, for example system-critical pods on one pool and user workloads on another.
By the end of this tutorial, you'll have a fully functional GKE cluster deployed on GCP, orchestrated with Terraform, following industry best practices.
The impact is workload isolation and cost control. The contextual layer is that node pools are independent from the control plane, allowing rolling upgrades without control plane downtime.
Terraform Resource Catalog for GKE
Each resource block describes one or more infrastructure objects, such as virtual networks or compute instances.
The following table lists the Terraform resources available for GKE:
The table is referenced in the documentation as a catalog of resources. The existence of a formal catalog signals that GKE coverage in Terraform is broad, spanning networks, clusters, node pools, and IAM bindings.
Terraform-Based Guides for GKE
The following table lists Terraform-based how-to guides and tutorials for GKE:
| Guide | Details |
|---|---|
| Create a GKE cluster and deploy a workload by using Terraform | Explains how to create a Google Kubernetes Engine (GKE) Autopilot cluster and deploy a workload by using Terraform. |
| Create an Autopilot cluster | Explains how to create a GKE cluster in Autopilot. |
| Creating a zonal cluster | Explains shows you how to create a Standard zonal cluster with the default features enabled in GKE. |
| Creating a regional cluster | Explains how to create a Standard regional cluster in GKE. |
| Create a multi-tenant cluster by using Terraform | Explains how to create a multi-tenant cluster and deploy a workload by using Terraform. |
| Add and manage node pools | Explains how to add and perform operations on node pools running your GKE Standard clusters. |
| Create clusters and node pools with Arm nodes | Explains how to create a GKE Standard cluster or node pool with Arm nodes, so that you can run Arm workloads on GKE. |
| Consuming reserved zonal resources | Explains how to consume reserved Compute Engine resources in GKE. |
| Specify a node image | Explains how to specify a node image for nodes in GKE Standard clusters |
The table provides a navigable map of learning paths. The impact for practitioners is choice clarity between zonal vs regional, standard vs autopilot, and arm vs x86. The contextual layer ties back to node pool configuration decisions and workload requirements.
Cluster Provisioning Behavior and Zone Distribution
You are now signed in to the dashboard for your Kubernetes cluster.
On the Dashboard UI, click Nodes on the left hand menu.
Notice there are 6 nodes in your cluster, even though
gke_num_nodes
in your
gke.tf
file
was set to 2. This is because a node pool was provisioned in each of the three zones
within the region to provide high availability. To see the zones that the cluster deployed each node pool to, run the following
in the
learn-terraform-provision-gke-cluster
directory.
bash
$ gcloud container clusters describe $(terraform output -raw kubernetes_cluster_name) --region us-central1 --format='default(locations)'
locations:
- us-central1-b
- us-central1-f
- us-central1-c
Congratulations, you have provisioned a GKE cluster with a separated node pool,
configured kubectl
, and deployed the Kubernetes dashboard.
If you'd like to learn how to manage your GKE cluster using the Terraform Kubernetes Provider, leave your cluster running and continue to the Kubernetes provider tutorial.
If not, remember to destroy any resources you create once you are done with this
tutorial
The observation that 6 nodes appear when 2 was requested illustrates regional node pool expansion. The requested node count is per zone. With three zones in us-central1, 2 nodes per zone yields 6 nodes total. The impact is high availability by default. The contextual connection is that Terraform outputs the cluster name, which is then used by gcloud to describe locations, confirming zonal distribution.
Cluster and Workload Terraform Files
Create a cluster and deploy a workload using Terraform
A Kubernetes cluster provides compute, storage, networking, and other services for applications, similar to a virtual data center. Apps and their associated services that run in Kubernetes are called workloads.
This tutorial lets you quickly see a running Google Kubernetes Engine cluster and sample workload, all set up using Terraform. You can then explore the workload in the Google Cloud console before going on to our more in-depth learning path, or to start planning and creating your own production-ready cluster. This tutorial assumes that you are already familiar with Terraform.
If you'd prefer to set up your sample cluster and workload in the Google Cloud console, see Create a cluster in the Google Cloud console.
Before you begin
Take the following steps to enable the Kubernetes Engine API:
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios
It serves as a bridge between Terraform configurations and Google Cloud APIs, letting you declaratively define infrastructure resources, such as virtual machines and networks.
The cluster and sample app for this tutorial are specified in two Terraform files that use the Google Cloud and Kubernetes providers.
Review the
cluster.tf
file:
bash
cat cluster.tf
The output is similar to the following
This file describes the following resources:
google_compute_network
: a VPC network with internal IPv6 enabled.
google_compute_subnetwork
: a dual-stack subnetwork.
google_container_cluster
: a dual-stack Autopilot mode cluster located in
us-central1
. The
deletion_protection
setting controls whether you can use Terraform to delete this cluster. If you set the value in the
deletion_protection
field to
false
, Terraform can delete the cluster. For details, see the
google_container_cluster
reference.
Review the
app.tf
file:
bash
cat app.tf
The output is similar to the following
This file describes the following resources:
(Optional) Expose the application to the internet
The Terraform files for the example describe an application with an internal IP address, which can only be accessed from the same Virtual Private Cloud (VPC) as the sample app. If you want to access the running demo app's web interface from the internet (for example, from your laptop), modify the Terraform files to create a public IP address instead before you create the cluster
The cluster.tf file demonstrates a dual-stack VPC and subnet with an Autopilot cluster in us-central1. Deletion protection is a safety guard. The impact of deletion_protection set to false is that terraform destroy will remove the cluster. The contextual layer is that app.tf then builds on the network and cluster outputs to deploy a workload, illustrating separation of infrastructure and application concerns.
Conclusion
The reference materials collectively argue that GKE cluster deployment belongs in code. Terraform provides repeatable, version-controlled deployments that can be reviewed, tested, and rolled back. The production-ready path starts with prerequisites and API enablement, moves through VPC and private networking, establishes remote state for collaboration, declares the GCP provider, and then builds control plane and node pools with security and scalability in mind. The observation that node counts multiply by zones reinforces the need to understand regional distribution. The file-based examples with cluster.tf and app.tf show how network, cluster, and workload concerns are separated while remaining declaratively linked. The guides catalog provides a menu of patterns from Autopilot to multi-tenant to Arm nodes. The overall consequence for teams is infrastructure that is auditable, reproducible, and safe to change, with network boundaries enforced by Terraform and state secured in GCS. The long-term operational impact is reduced manual error, improved collaboration, and a clear path from experimentation to production.