Using Terraform to Deploy a Helm Chart With Helm Test Execution
A quick google search for how to deploy Kubernetes workloads to a Kubernetes cluster will likely point you to various GitOps solutions such as FluxCD or ArgoCD. GitOps is an excellent practice to follow that, in my opinion, essentially means using git to perform your operations tasks. FluxCD and ArgoCD are simply tools that facilitate the implementation of the GitOps workflow. There is a great post here that demonstrates how a GitOps workflow can be implemented with Terraform. Whether or not FluxCD, ArgoCD, or Terraform is the right tool for the job ultimately depends on your requirements. One reason to choose Terraform over the others is that you can define both a k8s workload and the cloud resources that the workload depends on in one place (i.e. you may have a k8s workload that depends on an AWS SQS Queue). For the sake of this article, we will ignore why you would choose one tool over the other and simply describe one way of how to use Terraform. We will be reviewing specifically how to use Terraform to deploy a Helm chart and automatically execute the tests defined within that helm chart after the helm release has succeeded.
- Install Terraform: https://www.terraform.io/downloads.html
- Install Helm: https://helm.sh/docs/intro/install/
- Create a Kubernetes cluster
In this example I will be demonstrating how to deploy a simple go web server application called gocolor using a helm chart that was previously defined. The helm chart will install a Kubernetes Deployment and a Kubernetes Service and has a single naive helm test defined which can be used to validate the gocolor web server after it has been installed into a Kubernetes Cluster.
We will start by creating a main.tf file to define our Terraform code. This file will contain all of our terraform code except our variables and outputs. You can skip down to the bottom of this section if you just want to see the full main.tf file.
In this main.tf file we will configure Terraform to make use of the hashicorp/helm and hashicorp/null providers. If you’re not familiar with what a Terraform provider is then you can read about that here. The helm provider gives us the ability to define helm releases as terraform and the null provider gives us the ability to run arbitrary commands, which we will use to run the ‘helm test’ command.
Next we will define a data resource to import some information about our Kubernetes cluster to which we will be deploying. In my case, I am using an AWS EKS cluster. We will also specify some configuration for how Terraform should instantiate the aws and helm providers.
Next we will define the deployment of a helm release. This helm release will install the ‘gocolor’ helm chart that exists in the helm repository: https://jwenz723.github.io/gocolor . The version of the helm chart which will be installed will be specified by a Terraform variable. There are various Terraform variables being referenced here that we will define shortly. This block of code also includes a ‘null_resource’ which is basically a Terraform resource which doesn’t have a particular defined behavior. We are using this resource to wrap the execution of the ‘helm test’ command. Because the null_resource is not able to directly integrate with the helm provider we have to download and install the helm cli and configure the kubeconfig before we can execute ‘helm test’. The final block of code here is a ‘kubeconfig’ local which is generating a kubeconfig string based upon a template file which we will define shortly.
Here is the full main.tf file:
Now we will define a variables.tf file. This file will contain all of our variables used to configure the resources within main.tf. Not much to explain here.
We will now define a template which will be used for generating a kubeconfig file. This template contains the basic structure of a kubeconfig file with a few values that can be specified using variables.
With all of this defined all that is left to do is execute it. You will need to execute ‘terraform init’ to initialize all of the providers and the backend. Then you will execute ‘terraform apply’ to run the deploy of the defined resources.
The goal of this short article is to describe how to deploy a helm chart using terraform and how to automatically execute the tests defined within that helm chart after the chart has been deployed. Hopefully at some future point the execution of ‘helm test’ can be integrated directly into the helm provider, but for now this will have to do.