Node pools are the primary mechanism for shaping compute behavior inside a Google Kubernetes Engine cluster provisioned with Terraform. The reference material describes node pools as groups of nodes within a GKE cluster that share the same configuration. This grouping allows creation of heterogeneous clusters with varying machine types, capabilities, and settings to better accommodate different workload requirements within the same cluster. The practical impact for operators is that a single logical cluster can host system-critical components on stable, large machines while running bursty application workloads on smaller or preemptible instances without cross-contamination of settings.
The Terraform Google Kubernetes Engine module documents how to configure node pools and covers available configuration options, best practices, and considerations when designing and managing node pools for GKE clusters. Cluster-level configuration is referenced separately under Cluster Types. The module provides extensive options for node pool configuration, ranging from basic settings to advanced features. The module supports two types of node pools: googlecontainercluster resource and googlecontainernodepool resources. To define node pools, use the nodepools variable, which is a list of maps. This variable structure gives full control over node configuration.
The relationship between the variable definition and the underlying resources is central to repeatable infrastructure. Because node_pools is a list of maps, each map entry can specify machine type, disk size, labels, taints, and autoscaling parameters independently. The impact for teams is isolation of change risk; modifying one entry does not force a recreation of the entire cluster. Contextually this design ties directly to the recommendation to use separate node pools for different workload types - system, application, and spot - and to the ability to provision a node pool per zone for high availability.
Node Pool Fundamentals in the Terraform GKE Module
Node pools are groups of nodes within a GKE cluster that share the same configuration. They allow you to create heterogeneous clusters with varying machine types, capabilities, and settings to better accommodate different workload requirements within the same cluster.
The direct fact is the definition of a node pool as a homogeneous grouping. The impact layer is workload isolation and cost control. Teams can place monitoring and control plane components on a dedicated pool with guaranteed capacity while scaling user workloads on a separate pool with autoscaling enabled. This separation reduces blast radius when upgrades or node configuration changes occur.
The module provides extensive options for node pool configuration, ranging from basic settings to advanced features. Basic settings include machine type, disk size, and initial node count. Advanced features include autoscaling, node labels, taints, and maintenance windows. The contextual layer connects this breadth of options to production readiness. A cluster that works in development typically uses a single default pool. A production-ready cluster uses multiple pools with distinct settings for security, availability, and cost.
The module supports two types of node pools: googlecontainercluster resource and googlecontainernodepool resources. This distinction matters for dependency ordering. When a node pool is defined as part of the cluster resource, it is created together with the cluster. When defined as a separate googlecontainernodepool resource, Terraform can create the pool after the cluster exists. The impact is operational safety. If you require a separately managed node pool, Terraform won't attempt to create the node pool if the GKE cluster failed to create. This prevents orphaned resources and partial deployments.
To define node pools, use the nodepools variable, which is a list of maps. The list of maps pattern allows multiple pools to be declared in a single variable block. Each map can contain name, initialnodecount, autoscaling, and nodeconfig. The impact is declarative clarity. Reviewers can see all pool intents in one place. The contextual layer connects this to Terraform module patterns where variables drive reusable configurations across environments.
Separately Managed Node Pools and High Availability Behavior
Separately managed node pools allow you to customize your Kubernetes cluster profile. This is useful if some Pods require more resources than others. You can learn more here. The number of nodes in the node pool is defined also defined here.
The gke.tf file provisions a GKE cluster and a separately managed node pool, recommended. The tutorial assumes some basic familiarity with Kubernetes and kubectl but does not assume any pre-existing deployment. It also assumes that you are familiar with the usual Terraform plan/apply workflow. If you're new to Terraform itself, refer first to the Getting Started tutorial.
High availability behavior is demonstrated in the HashiCorp tutorial. 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 gkenumnodes 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.
The direct fact is the multiplication of node count by zones. The impact layer is resilience. A regional cluster spreads nodes across zones so a zone failure does not take down the workload. The contextual layer connects this to user expectations. Setting gkenumnodes to 2 does not mean two nodes total; it means two nodes per zone.
To see the zones that the cluster deployed each node pool to, run the following in the learn-terraform-provision-gke-cluster directory.
$ gcloud container clusters describe $(terraform output -raw kubernetes_cluster_name) --region us-central1 --format='default(locations)'
Output shows:
locations:
- us-central1-b
- us-central1-f
- us-central1-c
The three locations correspond to the three zones used for node pool placement. The impact for monitoring is that node distribution can be verified post-apply. The contextual layer ties this command to Terraform outputs. The kubernetesclustername output is produced by the module and consumed by gcloud for inspection.
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.
Tutorial Workflow and Repository Files
The HashiCorp tutorial provides a concrete workflow for provisioning with Terraform. For this tutorial, you will need to install and configure the gcloud SDK tool. To install the gcloud SDK, follow these instructions or choose a package manager based on your operating system.
You can also use the package manager homebrew to install the gcloud SDK.
$ brew install --cask google-cloud-sdk
After you've installed the gcloud SDK, initialize it by running the following command.
$ gcloud init
This will authorize the SDK to access GCP using your user account credentials and add the SDK to your PATH. This steps requires you to login and select the project you want to work in. Finally, add your account to the Application Default Credentials (ADC). This will allow Terraform to access these credentials to provision resources on GCloud.
$ gcloud auth application-default login
In your terminal, clone the following repository. It contains the example configuration used in this tutorial.
$ git clone https://github.com/hashicorp-education/learn-terraform-provision-gke-cluster
You can explore this repository by changing directories or navigating in your UI.
$ cd learn-terraform-provision-gke-cluster
In here, you will find four files used to provision a VPC, subnets and a GKE cluster.
vpc.tf provisions a VPC and subnet. A new VPC is created for this tutorial so it doesn't impact your existing cloud environment and resources. This file outputs region.
gke.tf provisions a GKE cluster and a separately managed node pool (recommended). Separately managed node pools allows you to customize your Kubernetes cluster profile — this is useful if some Pods require more resources than others. You can learn more here. The number of nodes in the node pool is defined also defined here.
terraform.tfvars is a template for the project_id and region variables.
versions.tf sets the Terraform version to at least 0.14.
Replace the values in your terraform.tfvars file with your project_id and region. Terraform will use these values to target your project when provisioning your resources.
The impact of this file layout is isolation of concerns. Networking lives in vpc.tf, cluster intent lives in gke.tf, and variable values live in terraform.tfvars. The contextual layer connects this to team workflows where vpc.tf may be owned by a platform team and gke.tf by an application team.
In order for Terraform to run operations on your behalf, you must install and configure the gcloud SDK tool. The initialization steps ensure authentication credentials are available to the Terraform Google provider. Without ADC login, plan and apply will fail with authentication errors.
Best Practices for Production Node Pool Configuration
Deploying GKE with Terraform gives you a repeatable, auditable cluster setup that you can confidently run across environments. The configuration above covers the core decisions - networking, node pools, security, and autoscaling - that make the difference between a cluster that works in development and one that is ready for production traffic. Start with this foundation and customize based on your workload requirements.
The reference material lists explicit best practices:
- Use private clusters. Nodes should not have public IP addresses.
- Enable Workload Identity. It is the most secure way for pods to access GCP services.
- Set up autoscaling on every node pool. Fixed-size pools waste money during low traffic and cannot handle spikes.
- Use separate node pools for different workload types - system, application, and spot.
- Enable auto-repair and auto-upgrade on all node pools.
- Set maintenance windows to control when upgrades happen.
The direct fact is each recommendation. The impact layer is security and cost. Private clusters reduce attack surface by removing public IPs from nodes. Workload Identity eliminates long-lived service account keys for pod-to-GCP access. Autoscaling prevents overprovisioning during low traffic and enables handling of spikes.
The contextual layer connects these practices to node pool design. Separate node pools for system, application, and spot workloads allow different autoscaling policies and upgrade windows. System pools can have conservative maintenance windows, while application pools can use broader windows. Spot pools can be configured with lower priority and separate node taints.
This gives you full control over node configuration. The combination of Terraform variables and module options makes it possible to codify these best practices and enforce them across environments.
Terraform Resources and Guides 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 documentation provides 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 impact of this guide catalog is discoverability. Teams can select a guide matching their cluster type. The contextual layer links Add and manage node pools to the nodepools variable and googlecontainernodepool resource, showing that node pools can be added post-creation.
Module Variables and Common Operations
The Terraform Google Kubernetes Engine module exposes variables for firewall and node pool behavior. The configuration snippet shows:
= {
all = []
default-node-pool = [
"default-node-pool",
]
}
}
Then perform the following commands on the root folder:
terraform init
to get the plugins
terraform plan
to see the infrastructure plan
terraform apply
to apply the infrastructure build
terraform destroy
to destroy the built infrastructure
The standard Terraform lifecycle commands provide predictability. Init downloads providers, plan shows diffs, apply creates resources, destroy cleans up.
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| addclusterfirewall_rules | Create additional firewall rules | bool | false | no |
| addmasterwebhookfirewallrules | Create masterwebhook firewall rules for ports defined in firewallinbound_ports | bool | false | no |
| addshadowfirewall_rules | Create GKE shadow firewall (the same as default firewall rules with firewall logs enabled) |
These boolean flags control extra firewall creation. The impact is security compliance. Enabling addshadowfirewall_rules provides logging parity with default rules. The contextual layer connects firewall rules to private clusters where nodes should not have public IP addresses and where master access must be tightly controlled.
Conclusion
The Terraform Google Kubernetes Engine module treats node pools as first-class configuration objects defined via the nodepools variable as a list of maps. This design enables heterogeneous clusters where each pool can have distinct machine types, autoscaling settings, and maintenance policies. The HashiCorp tutorial demonstrates the practical effect of regional deployment where a node pool defined with gkenum_nodes = 2 results in six nodes across three zones, illustrating automatic high availability placement.
The workflow for adoption involves installing the gcloud SDK, initializing credentials with gcloud init and gcloud auth application-default login, cloning the learn-terraform-provision-gke-cluster repository, and configuring vpc.tf, gke.tf, terraform.tfvars, and versions.tf. The separately managed node pool pattern ensures Terraform will not attempt to create a node pool if the GKE cluster failed to create, protecting against partial failures.
Production readiness is achieved by applying best practices codified in Terraform: private clusters with no public node IPs, Workload Identity for secure GCP access, autoscaling on every node pool, separate pools for system, application, and spot workloads, auto-repair and auto-upgrade enabled, and maintenance windows set to control upgrade timing. These decisions transform a development cluster into production traffic ready infrastructure.
The module's resource model and the catalog of Terraform-based guides for GKE provide a path from initial cluster creation to advanced scenarios such as Arm nodes, reserved zonal resources, and node image specification. Combined with standard Terraform operations init, plan, apply, and destroy, node pool configuration becomes repeatable, auditable, and environment consistent.