0

I'm not sure if I am thinking about this the right way, but here is my Problem:

I want to use the same Salt state and pillar configuration for production, development and test servers. The only difference should be:

  1. Which minions are used
  2. The values of Pillar keys, like passwords or usernames

I could go ahead and create different Pillar environments, but this would lead to separated sls files, which in turn means that the configurations could drift apart. Another aproach would be to use different git branches, one for each environment. But I imagine that this would lead to a lot of merge conficts.

If feel like the problem boils down to my pillar files having structure. For example, my pillar file for servers that have collectd enabled:

#!yaml|gpg

collectd:
  host:
    ip: 1.2.3.4
    port: 123
    username: my_username
    password: |
      -----BEGIN PGP MESSAGE-----
      ...
      -----END PGP MESSAGE-----

I would love to be able to use this file for all my environments just with different values, like so:

#!yaml|gpg

collectd:
  host:
    ip: $HOST_COLLECTD
    port: 123
    username: $USER_COLLECTD
    password: $PASS_COLLECTD

Is something like this possible, or am I using Salt the wrong way?

Thanks!

EDIT, to add some information:

I am using git_pillar to get the files directly from git. This allows me to have multiple environments without creating multiple directories, as each branch can be a environment. On solution I can think of is using templating to check the saltenv. This feels a little hacky, but would do what I want for now:

#!yaml|gpg

collectd:
  host:
    ip: 1.2.3.4
    port: 123
    username: my_username
    password: |
      {% if saltenv == 'dev' %}
      -----BEGIN PGP MESSAGE-----
      ...
      -----END PGP MESSAGE-----
      {% else %}
      -----BEGIN PGP MESSAGE-----
      ...
      -----END PGP MESSAGE-----
      {% endif %}

I am still looking for better ways to solve my problem, though

Leifb
  • 75
  • 8

1 Answers1

1

While I am not entierly happy with the result, I want to post what I am using now for others who stumble accross the same issue.

At the top of every file that needs differnent values depending on the environment, I declare jinja variables. It still means that there is some self coded logic in every file, but at least the actual structure of the pillar data is easy to understand. It comes with some formatting challanges, but works for everything I need. Here is an example:

#!jinja|yaml|gpg

{# Set values based on saltenv #}
{% if saltenv == 'test' %}
  {% set ip = 1.2.3.4 %}
  {% set username = 'user_test'%}
  {% set password = '
      -----BEGIN PGP MESSAGE-----
      ...
      -----END PGP MESSAGE-----'%}
{% elif saltenv == 'production' %}
  {% set ip = 5.6.7.8 %}
  {% set username = 'user_prod' %}
  {% set password = '
      -----BEGIN PGP MESSAGE-----
      ...
      -----END PGP MESSAGE-----'%}
{% else %}
  {{ raise('Invalid / Unknown saltenv:' ~ saltenv)}}
{% endif %}

collectd:
  host:
    ip: {{ ip }}
    port: 123
    username: {{ username }}
    password: |- {{ password }}

You have to be very carfull with the indentation of multiline strings like the PGP message!

Leifb
  • 75
  • 8