Dynamic Templating

Overview

Context

Oddly, though I’ve configured and worked with SaltStack across several organizations at this point, I had not come across this type of scenario before now. At most, I’ve only had a handful of config files for an application and so this problem wasn’t really a problem. At my new company though, the CTO had already come up against this problem, and then put the time in to figure out a very elegant solution.

Setup

The Conventional Method

Conventionally, this would be accomplished with three separate declarations. On our Salt Master, we would need to create a state file along with the static and template files we will need to go with it. The directory structure in our file_roots may look something like:

nginx
├── files
│ ├── bacon.conf.jinja
│ ├── eggs.conf.jinja
│ └── nginx.conf
└── init.sls

And then our state file would look like:

{{ sls }} - manage the nginx config file:
file.managed:
- name: /etc/nginx/nginx.conf
- source: salt://nginx/files/nginx.conf

{{ sls }} - managed the eggs config file:
file.managed:
- name: /etc/nginx/conf.d/eggs.conf
- source: salt://nginx/files/eggs.conf.jinja

{{ sls }} - managed the bacon config file:
file.managed:
- name: /etc/nginx/conf.d/bacon.conf
- source: salt://nginx/files/bacon.conf.jinja

Add Jinja Magic

nginx
├── files
│ └── etc
│ └── nginx
│ ├── conf.d
│ │ ├── bacon.conf.jinja
│ │ └── eggs.conf.jinja
│ └── nginx.conf
└── init.sls

As can be seen, in our state’s files directory, we’ve added the directory path where the nginx config files will be when rendered to the minion. This is important because it provides the hint our jinja code will need to know where on the minion filesystem to put the files.

Now, we revise the state:

Given the files and state above, the output of a render is:

nginx/init.sls - manage the config file /etc/nginx/nginx.conf: 
file.managed:
- source: salt://nginx/files/etc/nginx/nginx.conf
- name: /etc/nginx/nginx.conf
- makedirs: True

nginx/init.sls - manage the template file /etc/nginx/conf.d/bacon.conf:
file.managed:
- source: salt://nginx/files/etc/nginx/conf.d/bacon.conf.jinja
- name: /etc/nginx/conf.d/bacon.conf
- makedirs: True
- template: jinja

nginx/init.sls - manage the template file /etc/nginx/conf.d/eggs.conf:
file.managed:
- source: salt://nginx/files/etc/nginx/conf.d/eggs.conf.jinja
- name: /etc/nginx/conf.d/eggs.conf
- makedirs: True
- template: jinja

How It Works

As such, this code is completely portable between different states with no modifications. The only caveat is having the files directory contain the full directory paths of where the config files and templates need to be placed.

A Note On Security

Originally published at https://smartaleksolutions.com on October 20, 2020.

--

--

Climber, surfer, yogi, dad who does some IT on the side to get by.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Aleksandr Rain

Climber, surfer, yogi, dad who does some IT on the side to get by.