We run several Python virtual environments on our minions managed by salt.
The name of the system is build by this schema:
project_customer_stage
Example:
supercms_favoritcustomer_p
The pillar data:
systems:
- customer: favoritcustomer
project: supercms
stage: p
- customer: favoritcustomer
project: supercms
stage: q
For every virtualenv we have one linux user. Up to now we compute values like "home" like this:
{% for system in pillar.systems %}
{% set system_name = system.project + '_' + system.customer + '_' + system.stage %}
{% set system_home = '/home/' + system_name %}
...
But it is redundant.
How could we avoid copy+pasting {% set system_home = ...%}
?
I am like the way object oriented programming works:
In Salt you have YAML and templating ... Both nice things. But in my case OOP would be nice.
You can also generate pillar data dynamically. Consider the following example for a pillar file:
{% import_yaml "systems.yml" as systems %}
systems:
{% for system in systems %}
{% set name = system['name'] | default(system.project + '_' + system.customer + '_' + system.stage) %}
{% set home = system['home'] | default('/home/' + name) %}
- name: {{ name }}
customer: {{ system['customer'] }}
project: {{ system['project'] }}
stage: {{ system['stage'] }}
home: {{ home }}
{% endfor %}
This pillar definition loads YAML data from a systems.yml
file for which Salt will look in your pillar_root
directory. This file might look like this (very similar to your initial example):
- customer: smith
project: cms
stage: p
- customer: jones
project: shop
stage: p
name: jones_webshop_p # <-- alternate name here!
Note that this example computes properties like the project name and the user's home directory dynamically, unless they are explicitly defined in your data file. For this, the Jinja default()
filter is used in the pillar definition.
Using this pillar definition, you can simply use name
and home
in your state definitions directly from the pillar data:
{% for system in salt['pillar.get']('systems') %}
{{ system.home }}:
file.directory
{% endfor %}
Additionally, as in my opinion these Jinja-heavy SLS files get a little hard to read, you might consider switching to the Python renderer for your pillar file:
#!py
import yaml
def run():
systems = []
with open('systems.yml', 'r') as f:
data = yaml.safe_load(f)
for system in data:
if not 'name' in system:
system['name'] = "%s_%s_%s" % (system['project'], system['customer'], system['stage'])
if not 'home' in system:
system['home'] = "/home/%s" % name
systems.append(system)
return {"systems": systems}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With