Search code examples
jinja2salt-project

SaltStack jinja run command on master before pushing to minion


I have a simple task, which I'm trying to execute with Salt.

I want to dynamicly create a motd file for all my servers, which requires rendering ascii art at top, with the machines hostname.

I would like to make this render on the master, and then be pushed to the minion.

So far I have this simple file: /srv/salt/content/all/etc/update-motd.d/05-hostname

#!/bin/bash
cat << "EOF"
{{ salt.cmd.shell('figlet TestServer') }}
EOF

This file is then used in: /srv/salt/motd/init.sls

/etc/update-motd.d/05-hostname:
  file.managed:
    - source: salt://content/all/etc/update-motd.d/05-hostname
    - template: jinja

If I try to run this, It'll will save the file with the output: /bin/sh: 1: figlet: not found, which I guess, is because the command is executed on the minion and not on the master.

sudo salt 'server' state.sls motd

I do realize, that I can make the saltmaster install figlet on all servers, but I think that would be a waste. The master already knows the hostname through grains, and it should therefore be a simple task, to generate this file on the master before pushing it.

Does anyone have any ideas for accomplishing this?


Solution

  • State jinja are rendered on the minion itself so there is no way the file.managed would work that way.

    In order to render something on the master you need to use pillars.

    So you would need to add a pillar on the master which looks something like this :

    {% set host = grains['fqdn'] %}
    {% set command = 'figlet ' + host %}
    {% set output = salt.cmd.shell(command) %}
    motd:
      out: {{ output|yaml_encode }}
    

    then point /srv/salt/content/all/etc/update-motd.d/05-hostname to the pillar.

    #!/bin/bash
    cat << "EOF"
    {{ pillar['motd']['out'] }}
    EOF