Search code examples
python-3.xyamlsalt-project

Setting values based upon whether the host ID exists in a list


I am trying to create a state where a handful of settings can be retrieved without me having to make lots of individual pillar files for all the hosts. This way seems tedious and incorrect but I can't wrap my head around how to do it with Jinja and YAML.

How I was doing it:

/srv/pillar hosts1.sls,host2.sls,host3.sls,...host1000

cluster:
  name: cluster_one
  server: 1.1.1.1
  setting: foo

/srv/pillar hosts4.sls,host5.sls,host6.sls,...

cluster:
  name: cluster_two
  server: 2.2.2.2
  setting: bar

Is it possible to do something like this with pillar or even a map.jinja file and then use Jinja to in a state file and say 'if my minion name is in the members list, then set these server, setting and cluster name'?

clusters:
  cluster_one:
    server: 1.1.1.1
    setting: foo
    members:
       - host1
       - host2
       - host3
  cluster_two
    server: 2.2.2.2
    setting: bar
    members:
      - host4
      - host5
      - host6

The end result I wanted is just those three lines in a file like this.

host1,host2,host3 /tmp/example.txt

name: cluster_one
server: 1.1.1.1
setting: foo

host4,host5,host6 /tmp/example.txt

name: cluster_two
server: 2.2.2.2
setting: bar

The idea being that I want to just be able add minions to the members list without then having to make tons of new pillar files for each host. A host would only appear in one cluster so no need to worry about matching.

Then if I wanted to add new members I could simple edit this (refresh if needed) and apply without having to create new pillar files for host7, host8, and host9.

clusters:
  cluster_one:
    server: 1.1.1.1
    setting: foo
    members:
       - host1
       - host2
       - host3
  cluster_two
    server: 2.2.2.2
    setting: bar
    members:
      - host4
      - host5
      - host6
 cluster_three
   server: 3.3.3.3
   setting: baz
   members:
     - host7
     - host8
     - host9
 

Solution

  • We can achieve this with by organizing the pillar data and using Jinja template to create the resulting file on minions.

    Pillar

    Consider the pillar data pillar/data.sls:

    clusters:
      - name: cluster_one
        server: 1.1.1.1
        setting: foo
        members:
          - host1
          - host2
          - host3
      - name: cluster_two
        server: 2.2.2.2
        setting: bar
        members:
          - host4
          - host5
          - host6
      - name: cluster_three
        server: 3.3.3.3
        setting: baz
        members:
          - host7
          - host8
          - host9
    

    Jinja Template

    Then have a template for test/example.txt.j2 as below:

    {%- for cluster in clusters -%}
    {%- if grains['id'] in cluster.members -%}
    name: {{ cluster.name }}
    server: {{ cluster.server }}
    setting: {{ cluster.setting }}
    {%- endif -%}
    {%- endfor -%}
    

    State SLS

    Then I have a simple file.managed in test.sls to render the above template:

    create_temp_file:
      file.managed:
        - name: /tmp/example.txt
        - source: salt://test/example.txt.j2
        - mode: 0644
        - template: jinja
        - defaults:
            clusters: {{ pillar['clusters'] }}