Using Templates in Terraform to generate Kubernetes YAML

CJ Hewett
4 min readDec 9, 2022

The tricky thing with YAML files in Kubernetes, is that it’s not so easy to use variables within the files to inject values into them. Kustomize also doesn’t solve thing problem very well, so I will show a way to use Terraform to take a bunch of YAML files with variables, inject values into those variables to generate “rendered” YAML files, that can then be applied to a Kubernetes cluster.

Note: I would recommend using something like Helm or FluxCD over this, but sometimes needs must. ¯\_(ツ)_/¯

(This doesn’t have to be for Kubernetes YAML files, you could use this for a range of use cases where you need to inject some values into template files.)

Code for this example can be found here:

This is what the templates folder structure looks like:

So for starters, we will deal with all files within the first directory, ignoring the app-template/ directory. We will replace instances of the image_repo and image_tag variable in the 2048.yaml file with values. The lb.yaml
file doesn’t happen to have any variables in it, so will just be copied as is. Rendered files will be created in a sub-directory of files/ called rendered.

2048-game.yaml

Using the local_file resource, we will use a for_each to loop through every file in the files/templates/ directory that does not have app-template in the path. For each file, we will attempt to replace the variables image_repo and image_tag if they are in the file. This will not throw any errors if they don’t happen to be in the template file. We then generate a path for the new file by taking the path for the template and replacing the directory templates that is in the path, with a new directory called rendered.

We’ve just used individual files as templates, but what if we want to reuse a set of templates multiple times to generate a set of apps that vary slightly? Well, we can do that too…

First we will define some local variables:

  • apps — This is a list of the ‘apps’ we want to generate templates for from the app-templates folder. Key values set here will be used as unique variables in the templates. We are only defining name here, so any template file that has ${name} will have the apps unique value injected into it.
  • resources — This is a list of the YAML files we rendered previously, plus the names of the apps we are about to render. Each file/directory is prefixed with a - as we will be adding all of this to the resources: section in the kustomization.yaml file we will create in the last gist.
  • app_files — For each app in the apps variable, we will generate a flat list of objects, representing every file we need to create. So since we have 2 apps and 5 template files in the apps-templates folder, we will have 10 objects in this variable. Each object stores the; name of the app, the path to the existing template, and the path that the new rendered file will exist at.

With all the variables defined, we can use the local_file resource to loop through every object in apps_files , injecting the apps unique values ( each.value on line 43) and common values, version and repo in this example.

app-template/deployment.yaml

Finally, we will generate a root level Kustomize file with a list of all the YAML files and folders that will be created under the files/rendered/ directory.

The rendered kustomication.yaml file

If this helped you in any way, please consider giving me a follow. I’m trying to get to 100 followers, so it would mean a lot!

Cheers 🤙

--

--

CJ Hewett

🛹 Skateboarder. 🏂 Snowboarder. 🏄 Websurfer. I write monthly* about Cloud/DevOps/IoT. AWS Certified DevOps Engineer and Terraform Associate