Eric Radman : a Journal

Advanced Salt Templates

Dynamic Rules

Any system for configuration management can apply discovered facts to a template in order to generate files, but Salt is perhaps a step ahead in that the every SLS file is itself a template. This means that the rules that describe what files to process can be dynamic.

{% for host in ['www1', 'www2'] %}
/var/www/html/coreos/{{host}}.yml:
  file.managed:
    - source: salt://coreos/could-init.yml
    - template: jinja2
    - context:
      hostname: {{host}}
{% endfor %}

Extending Salt

Salt will parse python modules found in the _modules directory. this enables us to drive rule creation based on arbitray logic. In this example a we define a function for generating a list of hosts.

  # util.py
  import hostlist

  def expand_hostlist(spec):
      return  hostlist.expand_hostlist(spec)

Now in a SLS file or any template we can call this new functionality that was added by Salt.

{% set hosts = salt['util.expand_hostlist']('www[01-99]') %}

For other state information that is available see the SLS Temmplate Variable Reference. It's worth nothing that the filename of the template being generated is always available as the variable name. Also, in the SLS file we passed in context which contained the short hostname of it is rendering. This is very powerful, and allows us to build very generic templates that rely on information supplied in the loop.

We are now very close to a complete system that could be used for bare-metal provisioning. Installing an individual host could be as easy as

$ salt "server1" state.sls_id /var/www/html/coreos/www1.yml coreos

Raw Python

There is a lot that can be done with jinja2 templates + custom Salt modules, but Salt also supports processing files by executing Python

{% for host in ['www1', 'www2'] %}
/var/www/html/coreos/{{host}}.yml:
  file.managed:
    - source: salt://coreos/could-init.py
    - template: py
{% endfor %}

Last updated on October 04, 2016