Deploy Kubernetes Apps with Terraform

Google Kubernetes Engine

Infrastructure As Code during the cloud age is to use source code to document, version, and control your infrastructure. Terraform is by far the most popular and intuitive tool for this process. There are numerous articles, blogs, how-tos, and source code repositories about using Terraform to craft cloud resources on AWS, Azure, and GCP.

But Terraform is a tool to create any resource that exposed through web api (RESTful), and not only can you create your infrastructure with Terraform, you can deploy applications on orchestration platforms like Kubernetes.

This article illustrates spinning up a Kubernetes cluster on Google Cloud using GKE, and then deploying the guestbook sample application (AngularJS, PHP, Redis), which google has made available in their container registry.

Installing the Tools

For this tutorial you need the following:

After installing Google Cloud SDK, you’ll want to initialize and authorize Google Cloud SDK for your account.

Install Tools on Mac OS X

With HomeBrew installed, you can do this to install the tools:

cat <<-"BREWFILE" > Brewfile
cask 'google-cloud-sdk'
brew 'kubectl'
brew 'terraform'
BREWFILE
brew bundle --verbose

Organizing into Modules

We’ll start by setting up this directory structure, and files referenced will use this:

.
├── gke
│ ├── cluster.tf
│ ├── gcp.tf
│ └── variables.tf
├── k8s
│ ├── k8s.tf
│ ├── pods.tf
│ ├── services.tf
│ └── variables.tf
└─── main.tf

We can create this structure and empty files:

mkdir terraform-gke
cd terraform-gke
mkdir gke k8s
touch main.tf
for f in cluster gcp variables; do touch gke/$f.tf; done
for f in k8s pods services variables; do touch k8s/$f.tf; done

Our top level, main.tf will reference two modules that we’ll create later. One module will create the GKE cluster, and the other module will use information from GKE to deploy software into the Kubernetes cluster.

main.tf

Cluster Specification

This is the module that will create a Kubernetes cluster on Google Cloud using GKE resource.

This first start by specifying all the variables this module will use in gke/variables.tf file:

variables.tf

We’ll need to specify a provider, which is Google Cloud in gke/gcp.tf file:

gcp.tf

With the variables specified and provider specified, we can now create our Kubernetes infrastructure. In Google Cloud this is one resource, but this encapsulates many components (managed instance group and template, persistence store, GCE instances for worker nodes, GKE master). This in done in gke/cluster.tf file:

cluster.tf

This creates a 3 worker node cluster. The output variables will be used later when we deploy applications. They are marked sensitive to avoid printing out to standard output.

Guestbook Application Specification

Kubernetes code repository has an example application called guestbook that uses Redis cluster to store information. This module is divided into four parts:

  1. Variables used in this module
  2. Kubernetes provider to connect to Kubernetes API
  3. Pods using Replication Controller
  4. Services creates permanent end point and connecting them to internal IP addresses as pods are added or removed.

The variables we’ll use are defined in variables.tf file:

variables.tf

Our Kubernetes provider is in the k8s.tf file:

k8s.tf

And now we create our minimum unit of deployment, the Kubernetes pods using Kubernetes Replication Controller in pods.tf file. These will be 1 redis master pod, 2 redis slave pods, and 1 frontend pod. The images for these components are available from Google’s Container Registry.

pods.tf

This will create the pods that we can now use to deploy services into them. We’ll create the services.tf for the services we wish to deploy (redis master, redis slave, frontend). One note about the frontend, as it uses the type LoadBalancer, this will create a google load balancer outside of the cluster to send traffic one of three pods.

services.tf

Launch the Application

Before we start, we need to initialize some variables that the GCP provider requires, which is the target project and the desired region to create the cluster. We’ll use our default project configured with gcloud:

export TF_VAR_project="$(gcloud config list \
--format 'value(core.project)'
)"
export TF_VAR_region="us-east1"

Now we’ll need to specify the administrative account and a random password for the cluster:

export TF_VAR_user="admin"
export TF_VAR_password="m8XBWrg2zt8R8JoH"

With these setup, we can initialize our environment, which includes both downloading plugins required google cloud provider and kubernetes provider, as well as references to our modules.

terraform init

Now we can see what we want to create and then create it:

terraform plan
terraform apply

After some time (10 to 20 minutes) we can test out our application. Run this to see the end points:

kubectl get service

Final Thoughts

This is an easy way to quickly test clusters, pods, services, and other components. Currently, Terraform only supports deploying Pods and ReplicationControllers as deployable units.

More popular now are ReplicaSets and Deployments objects as deployable units, which Terraform community doesn’t yet want to support as these are still in beta. If you need these other controllers, then you’ll have to use kubectl or helm for deployments.