Search code examples
salt-project

SaltStack file.recurse per minion


Goal

How can I install files with file.recurse on the minion which are specific to minions?

Current Strategy

This would works:

   files_per_minion:
      file.recurse:
        - source: salt://monitoring/files/per_minion/{{ grains.id }}
        - name: /
        - template: jinja

... but it fails for minions which don't have this directory on the master. I don't want to create a directory for every minion on my master.

I search for a way for an optional include. Here is a condition in pseudo code:

 {% if magic_way_to_check_if_source_exists salt://monitoring/files/per_minion/{{ grains.id }} %}

   files_per_minion:
      file.recurse:
        - source: salt://monitoring/files/per_minion/{{ grains.id }}
        - name: /
        - template: jinja

 {% endif %}

Question

How to write the condition magic_way_to_check_if_source_exists ?

Other solutions welcome

The condition magic_way_to_check_if_source_exists is just one strategy to get to the goal. Other solutions are welcome.

Use Case

Imagine I want cron_tab_file_for_xhost to get installed, but only on the host called xhost. I could solve this by creating a directory tree and a file for this host like this:

monitoring/files/per_minion/xhost/etc/cron.d/cron_tab_file_for_xhost

Solution

  • There are different ways depending on your use cases and state tree.

    The easiest one is to create a separate state and attach this using top.sls.

    If you work on formulas, which are configured through pillar. I would write this information somewhere in my pillar. The states then decide based on the pillar data.

    pillar.example:

    yourformula:
      getspecificfile: true
    

    somestate.sls:

    {% if salt['pillar.get']("yourformula:getspecificfile") %}
    files_per_minion:
      file.recurse:
        - source: salt://monitoring/files/per_minion/{{ grains.id }}
        - name: /
        - template: jinja
    {% endif %}
    

    UPDATE:

    i just had a look in the docs of the file.managed state

    The source parameter can be specified as a list. If this is done, then the first file to be matched will be the one that is used. This allows you to have a default file on which to fall back if the desired file does not exist on the salt fileserver. Here's an example:

    /etc/foo.conf:
      file.managed:
        - source:
          - salt://foo.conf.{{ grains['fqdn'] }}
          - salt://foo.conf.fallback
        - user: foo
        - group: users
        - mode: 644
        - backup: minion
    

    This seems to be another option - if you don't care to roll out empty files which are not necessary on your minions.