DEV Community

Cover image for Terraform + Helm = ❤️
Lucas de Souza
Lucas de Souza

Posted on

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"
  }
}

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"
  }
}

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")}"
]

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 ~}

And to render this template:

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

Giving the output:

backend 10.0.0.1:8080
backend 10.0.0.2:8080

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.

Top comments (6)

Collapse
 
amaurybsouza profile image
Amaury Borges Souza

Nice article, congrats Lucas!

Collapse
 
japm94 profile image
Júlio Pedrosa

Parabéns mano, muito bom!!!

Collapse
 
jhonatancmorais profile image
Jhonatan Morais

Thanks for sharing!!

Collapse
 
souzaxx profile image
Lucas de Souza

Yes! Sorry for that!

I'm finishing the post right now!

Collapse
 
smartinov profile image
Stefan Martinov

Great post! Love the memes!