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:

kind: "ReplicationController"
apiVersion: "v1"
metadata:
  name: "my-pod-{{VERSION}}"
  labels:
    name: "my-pod"
    version: "{{VERSION}}"
spec:
  replicas: 2
  selector:
    name: "my-pod"
    version: "{{VERSION}}"
  template:
    metadata:
      labels:
        name: "my-pod"
        version: "{{VERSION}}"
    spec:
      containers:
        - name: "my-pod"
          image: "gcr.io/my-project/my-pod:{{VERSION}}"
          env:
            - name: "TIMEOUT"
              value: {{TIMEOUT}}
            - name: "URL"
              value: "{{URL}}"
          ports:
            - containerPort: {{API_PORT}}
              name: "api"
              protocol: "TCP"
            - containerPort: {{ADMIN_PORT}}
              name: "admin"
              protocol: "TCP"

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:

$ VERSION=1.2.3 TIMEOUT=1000 URL="http://www.google.com" API_PORT=8080 ADMIN_PORT=8081 \ 
  ./templater.sh pod-template.yaml

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

kind: "ReplicationController"
apiVersion: "v1"
metadata:
  name: "my-pod-1.2.3"
  labels:
    name: "my-pod"
    version: "1.2.3"
spec:
  replicas: 2
  selector:
    name: "my-pod"
    version: "1.2.3"
  template:
    metadata:
      labels:
        name: "my-pod"
        version: "1.2.3"
    spec:
      containers:
        - name: "my-pod"
          image: "gcr.io/my-project/my-pod:1.2.3"
          env:
            - name: "TIMEOUT"
              value: 1000
            - name: "URL"
              value: "http://www.google.se"
          ports:
            - containerPort: 8080
              name: "api"
              protocol: "TCP"
            - containerPort: 8081
              name: "admin"
              protocol: "TCP"

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

# The timeout in milliseconds
TIMEOUT=1000 
# The URL
URL="http://www.google.com" 
# External API port
API_PORT=8080 
# Internal admin port
ADMIN_PORT=8081

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:

$ VERSION=1.2.3 ./templater.sh pod-template.yaml -f config.properties > pod.yaml

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:

$ VERSION=1.2.3 ./templater.sh pod-template.yaml -f config.properties -s > pod.yaml

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

31 thoughts on “Simple templating engine in Bash

  1. 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

  2. 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.

    1. 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

  3. organic cbd gummies present a expedient and enjoyable disposition to acquaintance the effects of this compound. These gummies check in in various flavors, potencies, and formulations, providing users with controlled dosing and long-lasting effects. Divers consumers cherish them for the purpose relaxation’, anguish relief. In any way, it’s vital to digest them responsibly, as effects may take longer to kick in compared to smoking or vaping. Usually voucher dosage guidelines and effect compliance with nearby laws before purchasing or consuming.

  4. The person treating you will make sure you’re on the lowest possible dose to keep your condition under
    control. You might also be given a drug called
    a proton pump inhibitor or another medicine to protect your stomach.
    Steroids are taken in different ways, and the
    dosage may vary depending on the condition you have.

    The table below gives an idea of how often you might need to take steroids.

    It’s also associated with both athletic performance and general endurance.
    You might be able to start consuming steroids if you have any infections related to use and skins.
    If you have any wound and catch all your body, asteroids might delete these things, and you can feel better
    and easily cover-up ups the symptoms.
    These include increased nitrogen retention and protein synthesis, increased IGF-1 production, inhibition of glucocorticoids,
    increased red blood cell production, increase collagen synthesis, etc.
    Much like prohormones, basic steroid use entails a series of bulking and cutting campaigns.

    During bulking cycles, people are taking supplements or steroids that enhance their overall muscle building abilities.

    Contact your doctor or health care provider right away if any
    of these apply to you. Anabolic steroids, together with Anavar, can increase the activity and sensitivity of oral anticoagulants .
    The most frequent side effect of all Anabolic Androgenic Steroids
    is liver toxicity and cholestatic jaundice, among others.
    Such adverse results on the liver are seen in sufferers
    utilizing high dosages of Oxandrolone or Anavar for more than one year and concomitant use with other anabolic
    agents. No evidence has shown that the use
    of Oxandrolone for a short time period had led to the development of liver feature impairment.
    The products are safe and legal thus no more worrying
    about doping bans and visit from authorities. Crazy bulk is a
    well-known company for producing alternative legal steroids.

    The appendix bursts or tears if appendicitis is not diagnosed quickly
    and goes untreated. Peritonitis is a dangerous infection that happens when bacteria and other
    contents of the torn appendix leak into the abdomen. In people with appendicitis, an abscess
    usually takes the form of a swollen mass filled with
    fluid and bacteria.
    Bulking Stack- Costs $179.99 (instead of 229.99),the stack will help boost recovery times,
    spur massive growth, and also boost your strength. The stack is a combination of Decaduro, Testo-max,D-Bal, and Trenorol.
    HGH-X2 works well with other crucial amino acids in the
    body, improving the production and release of HGH hormones.
    These products work with the pituitary gland which releases this compound.
    Its main ingredients include L-citrulline, L-arginine, acetyl-L-carnitine, all of which
    are amino-acids supplements. The product also contains ginseng, wild yam, and Tribulus Terrestris.

    Between the high rates of obesity and the amount of sugars and preservatives
    in our food, it’s important to be proactive by leading
    a lifestyle that promotes heart health. That starts with your
    diet—knowing what you’re putting into your body and the effect it has on you is crucial.
    There was also no relevant benefit for other endpoints including mortality rate by day 29 and time to recovery.

    While NPP is used more for bulking, it can be used in a cutting cycle to protect an existing
    lean muscle.
    The elderly often experience less fever and less severe abdominal pain than other patients do
    with appendicitis. Many older adults do not know that they have a serious problem until
    the appendix is close to rupturing. A slight fever and abdominal
    pain on one’s right side are reasons to call a doctor right away.
    The use of testosterone therapy is increasingly common in the United States, with more
    than 2 million men receiving the therapy. Testosterone is
    available in different forms, including topicals such
    as gels, creams, and patches; injections; and
    pellets that are surgically placed directly beneath the skin. Yes absolutely, a crazy
    bulk range of products is safer made from natural ingredients
    that will boost and enhance your muscles and strength with no side
    effects.

    Here is my webpage; what are roids – https://learning.quill.com.au/blog/index.php?entryid=4889,

Leave a Reply

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