Create a private GCP Kubernetes cluster using Terraform

In this article, I want to share how I approached creating a private Kubernetes (GKE) cluster in Google Cloud Platform (GCP).

This post is also available on my blog.

Target infrastructure

To get an overview - this is the target infrastructure we’re aiming for:

  • A GKE cluster with Linux Worker Nodes.
  • Load Balancer that routes external traffic to the Worker Nodes.
  • A NAT router that allows all our instances inside the VPC to access the internet.
  • A Bastion Instance that allows us to access the Kubernetes Control Plane to run CLI commands.
    This is basically just a Linux machine with a proxy installed on it. That is exposed to the internet via an external IP address.
CGP infrastructure with a private GKE cluster
CGP infrastructure with a private GKE cluster, created with

Introduction to Terraform

To get started with Terraform, I found the HashiCorp tutorials useful:

There’s also lots of other resources available.

Local setup

Google Cloud Platform access

To be able to create resources in the Google cloud, a Google account is needed first. GCP offers a $300 credit with a trial period of a month (at time of writing). You can sign up for this at

GCP Service account (or gcloud CLI as alternative)

We need to authenticate with GCP. Go to and create a service account. This will grant access to the GCP APIs.

After creating the service account. Create a JSON key for it and download it locally.

Install Cloud SDK & Terraform CLI

To be able to run Terraform locally. The GCP & Terraform CLI needs to be installed.

Create infrastructure with Terraform

You can find all the files on GitHub.

Setup repository

Clone the Git repository

Move the service account JSON key to infrastructure/service-account-credentials.json

Configure variables:

Change the & values to the GCP project & service account mail address.

Alternative to using Service Account key

Alternatively to the Service Account. You can use the gcloud CLI tool.
You can find the installation instructions for it here.

Then you can log in using .
After that. Store the OAuth access token that Terraform uses in the required environment variable:

Keep in mind that this token is only valid for 1 hour (default).

Now let’s get to the actual Terraform code:



The and blocks are needed to configure the GCP Terraform provider.

The module is a local module located inside the directory. This module defines the network resources we need:


This creates a VPC and subnet. And the NAT router that allows the instances inside our VPC to communicate with the internet.

Note: The IP ranges defined in the block that will be used for the GKE cluster may not overlap with the subnet’s CIDR range.
I defined these in the networking module to have all the networking related things in one place. They’ll be exposed as output variables and used by the module.

Bastion instance

This module creates a virtual machine that runs a proxy. This will allow us to access the Kubernetes Control Plane from outside the GCP network, and run commands.



This will also output two commands.

The content of the output can be used to open an SSH tunnel to the Bastion instance.

can be used to run and use the Bastion instance as proxy.


Kubernetes Cluster

Creates a GKE Kubernetes cluster and Linux nodes inside the previously created network.



Creating the infrastructure

This will initialize Terraform.

Next- create the infrastructure using the Terraform configuration.

The command will list all the GCP components Terraform will create. Accept by typing in the terminal. This will create all the infrastructure inside GCP, and take a few minutes.

Additional resources

Some resources that were useful to me:

PHP Software & DevOps Engineer. Moved to

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store