Terraform + Helm = ❤️

souzaxx

Lucas de Souza

Posted on September 20, 2020

Terraform + Helm = ❤️

If you ever tried to manage IaC with Terraform you might end up with “Well, the cloud resources are fine, but how am I going to deal with my Kubernetes cluster???”

In this post, I want to share a simple and functional example of how you can integrate Helm with Terraform using the best of each tool.

The setup of this integration became much easier after Helm v3 was released. Now, you can simply pass your Kubernetes credentials to the Helm Provider and start deploying your charts using Terraform!

provider "helm" {
  kubernetes {
    config_path = "/path/to/kube_cluster.yaml"
  }
}
Enter fullscreen mode Exit fullscreen mode

You can now deploy Charts using the helm_release resource 🎉.

resource "helm_release" "example" {
  name       = "my-redis-release"
  repository = "https://kubernetes-charts.storage.googleapis.com" 
  chart      = "redis"
  version    = "6.0.1"

  values = [
    "${file("values.yaml")}"
  ]

  set {
    name  = "cluster.enabled"
    value = "true"
  }

  set {
    name  = "metrics.enabled"
    value = "true"
  }

  set_string {
    name  = "service.annotations.prometheus\\.io/port"
    value = "9127"
  }
}
Enter fullscreen mode Exit fullscreen mode

Ok, that's fine Lucas, but you have basically shown the Helm provider page... Am I wasting my time here?

hold-up

In this post, I want to deal with all this excessive set {} parameters in the helm_relase resource. There must be an easier way to manage these variables.

thinking

Actually, the tutorial has already shown us how! We can use the values parameter and pass all our variables in a YAML format.

values = [
  "${file("values.yaml")}"
]
Enter fullscreen mode Exit fullscreen mode

Instead of using the file function, we can also pass in EOF format:

Lucas...

am-i-joke-to-you?

Okay, okay, I'm sorry! I'm getting into the point, wait a little longer!

templatefile

In terraform, we can create dynamic templates using the templatefile function. Combe this function with the values parameter in the helm_release resource and we get a lot of flexibility!

The templatefile function has a slite different syntax than Terraform, but you can easily adapt to it.

An example would be:

backends.tmpl

%{ for addr in ip_addrs ~}
backend ${addr}:${port}
%{ endfor ~}
Enter fullscreen mode Exit fullscreen mode

And to render this template:

templatefile("${path.module}/backends.tmpl", { port = 8080, ip_addrs = ["10.0.0.1", "10.0.0.2"] })
Enter fullscreen mode Exit fullscreen mode

Giving the output:

backend 10.0.0.1:8080
backend 10.0.0.2:8080
Enter fullscreen mode Exit fullscreen mode

And yes, we can also use if statements if you wondered.

We can use all this flexibility right into the values parameter, and here is an example of how to create a dynamic values.yaml:

Templatefile also accept terraform objects making our life easier

If you want to follow the complete example:

thats-all

In my next post, I'll explain in more detail about this project and how it can help eks clusters running out IPs address.

Thank you for your reading,

Stay safe; stay well.

Lucas.

💖 💪 🙅 🚩
souzaxx
Lucas de Souza

Posted on September 20, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related