In this article, we will use Terraform to show how to deploy applications using the Helm provider to provision applications inside your Kubernetes (K8S) cluster.
This can be a nice solution to enable end-to-end provisioning of your K8S infrastructure and application using Terraform, especially when combined with your cloud and Kubernetes Terraform provider. We will briefly discuss the role of Helm, the Helm Terraform provider, before moving on to some practical examples. Enjoy!
We will cover:
Helm is quite simply a package manager for K8S. Helm simplifies the deployment and management of applications on K8S by abstracting away the complexities of configuring and managing individual K8S resources.
It enables users to share, version, and reuse application components easily. Helm allows you to package your applications into charts, distribute them via repositories, and deploy them consistently across different environments.
Read more in our Kustomize vs Helm article.
You can install Helm on your machine for experimentation by following the instructions provided in the official Helm documentation.
In Terraform, a provider is a plugin that allows Terraform to interact with a specific infrastructure or service provider. It acts as an interface between Terraform and the target provider, enabling Terraform to create, modify, and manage resources on that platform. Thousands of providers are available for use with Terraform, popular cloud services, K8S, and of course, Helm.
Check out also Terraform Kubernetes provider overview.
The Helm provider is used to deploy software packages in K8S. The provider needs to be configured with the proper credentials before it can be used.
Terraform providers are typically distributed as separate plugins that need to be installed and configured in the Terraform environment before they can be used. The provider
block in a Terraform configuration file specifies the provider and its required version.
To get started, you’ll need to declare the Helm provider in your Terraform configuration file:
main.tf
terraform {
required_providers {
helm = {
source = "hashicorp/helm"
version = "2.9.0"
}
}
}
provider "helm" {
kubernetes {
config_path = "~/.kube/config" # Path to your Kubernetes config file
}
}
Notice the config_path
option should point to your K8S config file (by default ~/.kube/config
) .
You can also add options to connect to a specified localhost or private registry to pull packages from if required, if these are not specified, then the public repository source will be used:
provider "helm" {
kubernetes {
config_path = "~/.kube/config" # Path to your Kubernetes config file
# localhost registry with password protection
registry {
url = "oci://localhost:5000"
username = "username"
password = "password"
}
# private registry
registry {
url = "oci://private.registry"
username = "username"
password = "password"
}
}
}
In your Terraform configuration files, you can now specify the release of the Helm chart you want to deploy using the helm_release
resource.
- A chart is a collection of files that describe a set of Kubernetes resources. It includes templates, which define the structure and content of the resources, and a values file that allows for parameterization and configuration customization.
- A release is an instance of a chart running in a Kubernetes cluster. Each release has a unique name and version.
You can find the repository of publically available Helm packages over on the Artifact hub.
The below example specifies a Helm release for an NGINX controller:
resource "helm_release" "nginx" {
name = "my-nginx"
repository = "https://charts.bitnami.com/bitnami"
chart = "nginx-ingress-controller"
version = "8.0.1"
set {
name = "service.type"
value = "ClusterIP"
}
}
Example for a Redis cache deployment:
resource "helm_release" "redis" {
name = "my-redis"
repository = "https://charts.bitnami.com/bitnami"
chart = "redis"
version = "15.0.10"
}
Example for Prometheus using the official Prometheus chart from the Prometheus Community Helm chart repository:
resource "helm_release" "prometheus" {
name = "my-prometheus"
repository = "https://prometheus-community.github.io/helm-charts"
chart = "prometheus"
version = "15.0.0"
}
You can further customize the deployments by adding supported parameters to the helm_release
resource blocks as required.
Note that the only other available component in the Helm Terraform provider is the helm_template
data source, for rendering chart templates locally and exposing the rendered manifests in the data source attributes. helm_template
mimics the functionality of the helm template
command.
Read more: Using ArgoCD with Helm charts.
Using Terraform to deploy resources to your K8S cluster using the Helm provider is a powerful way to use Terraform to deploy your infrastructure and applications. You can avoid using YAML, which can be thought of as hard to manage and read, HCL aims to solve some of those issues.
We encourage you also to explore how Spacelift makes it easy to work with Terraform. If you need any help managing your Terraform infrastructure, building more complex workflows based on Terraform, and managing AWS credentials per run, instead of using a static pair on your local machine, Spacelift is a fantastic tool for this. It supports Git workflows, policy as code, programmatic configuration, context sharing, drift detection, and many more great features right out of the box. You can check it for free, by creating a trial account.
Note: New versions of Terraform are placed under the BUSL license, but everything created before version 1.5.x stays open-source. OpenTofu is an open-source version of Terraform that expands on Terraform’s existing concepts and offerings. It is a viable alternative to HashiCorp’s Terraform, being forked from Terraform version 1.5.6.
Manage Terraform Better and Faster
If you are struggling with Terraform automation and management, check out Spacelift. It helps you manage Terraform state, build more complex workflows, and adds several must-have capabilities for end-to-end infrastructure management.