CoursesSaltIntermediate

Jinja & templating in states

Data-driven, portable SLS.

Intermediate12 min · lesson 7 of 12

SLS files are rendered through Jinja before they are parsed as YAML, which makes states data-driven and portable. You use Jinja to pull values from pillar and grains, loop to generate repeated blocks, and branch on the platform — so one state file adapts to every minion. This two-stage rendering (Jinja first, then YAML) is powerful and, occasionally, a source of confusing errors when the two layers interact.

TWO-STAGE SLS RENDERING
1SLS source file
Jinja mixed into YAML
2Jinja renders first
inject pillar/grains, loop, branch
3Plain-text output
must be valid YAML
4YAML parsed
into state data structures
5States execute
converge the minion
Jinja runs before YAML parses — a loop that emits mis-indented lines yields a YAML error, so render the SLS to inspect the generated YAML.
users/init.sls
{% for user in pillar.get('users', []) %}
create_{{ user['name'] }}:
user.present:
- name: {{ user['name'] }}
- shell: {{ user.get('shell', '/bin/bash') }}
- groups: {{ user.get('groups', []) }}
{% endfor %}
# one loop renders a user.present state per entry in pillar

Keep logic light, and know the render order

The discipline mirrors Ansible/Puppet templating: use Jinja to inject data and lightly branch, but do not turn SLS into a program — heavy logic belongs in pillar (data) or execution modules (code). And remember Jinja runs first: it produces text that must then be valid YAML, so a Jinja loop that emits mis-indented lines yields a YAML error that points at the rendered output, not your source. When puzzled, render the SLS to see what YAML Jinja actually produced.

terminal
# see the YAML that Jinja actually produced (invaluable for debugging)
$ salt 'web1' state.show_sls users
$ salt 'web1' slsutil.renderer salt://users/init.sls default_renderer=jinja
Jinja renders to text, then YAML parses it
Because Jinja runs before YAML parsing, indentation produced by a loop or conditional must come out as valid YAML — a common bug is a Jinja block that emits misaligned lines and yields a cryptic YAML error. Debug by rendering the SLS (state.show_sls / slsutil.renderer) to inspect the generated YAML, and keep Jinja output cleanly indented rather than fighting the parser blind.