Press "Enter" to skip to content

Simple templating engine in Bash

TL;DR: Checkout the template engine at github.

When working with pods in Kubernetes I had the need to define environment variables for the pod from a file. This is currently not supported in the currently released version of Kubernetes (1.1). What I wanted to do was to have a template file, for example pod-template.yaml, that looked like this:

and be able to replace things inside the double brackets (placeholders) with values defined externally to the pod-template.yaml. This is of course nothing new and there’s a gazillion of various templating engines out there for various programming languages. But after quite a lot of googling and looking through stackoverflow I couldn’t find anything that worked the way I wanted to in bash.

What made this particular use case a bit tricky was that some of the placeholder values were defined in a file while others had to be passed as parameters to the template engine on usage. For example the value of the {{VERSION}} placeholder is generated by our continuous integration server while all others ({{TIMEOUT}}, {{URL}} etc) are defined in an (encrypted) configuration file checked into our code repository. So I needed a template engine that could handle both of these cases at the same time. The closest thing I found was the bash-templater projected created by Sébastien Lavoie which allowed me to do like this:

I.e. it takes environment variables and replaces the placeholders defined in the template file with these values. The outcome looks like this:

The problem (again) was that our configuration was defined in a file (config.properties) that looked something like this:

So I ended up forking bash-templater to my github repository and added support for passing in values as parameters as well as reading values from a file. Usage:

Volia, all requirements fulfilled! The result of the transformation is stored in the pod.yaml file.

I also added some other tweaks, for example suppression of warning messages (that will otherwise be included in the resulting file and mess up the outcome) if you define entries in config.properties that are not found as placeholders in template. Just add the -s (silent) argument to ignore these warnings:

I hope that this will come to use for someone else as well.

7 Comments

    • johanhaleby johanhaleby March 4, 2016

      I’m not familiar with envsubst, could you please elaborate?

  1. […] resides in the app-config.properties file. I’ve described this workaround in more detail here. Kubernetes 1.2 will give us ConfigMaps that’ll probably address the need for this […]

  2. James James March 10, 2016

    export var1=”test”
    envsubst generated.yaml

    $var1 in template.yaml, and will substituted as “test” in generated.yaml

    But, i cannot find a way to escape if using envsubst.
    e.g. i want to keep ${var_to_keep} not substituted by envsubst

  3. Luis Luis April 15, 2016

    Johan, hello. Once again, thanks.

    I’ve run into an issue where supplying a template with no variables (ie: {{}}) throws a warning and an error:

    Warning: No variable was found in services/portal.yml, syntax is {{VAR}}
    sed: 1: “services/portal.yml”: unterminated substitute in regular expression

    I meant to open an issue in the repo but they’re disabled. This is just a heads up. I’ll try to submit a PR asap.

    • johanhaleby johanhaleby April 17, 2016

      Hi Luis,

      Thanks for your comment. I actually didn’t know that issues were disabled, I’ll fix this. Also a PR would be great 🙂

      Regards,
      /Johan

Leave a Reply

Your email address will not be published. Required fields are marked *