Saltstack pillar
The pillar stores secret information that you may want to encrypt, and limit which machines have access to.
The pillar is also useful for altering the context of your statefiles. Sometimes you may find yourself wishing you could parametrize your statefiles. Using the pillar (and swapping out pillar values for different systems) you can make your states more dynamic.
For example, this is how I reuse the same statefile for a program, but use different ports on different servers.
Structure
files
Your pillar is a collection of YAML files where you can define variables, and their values. Add variables defined within one of these files to your
pillar/top.sls
file underneath a hostname, and that host will gain access to all of the variables defined within that file.
name description location pillar-files .sls files under the pillar subdirectory are YAML files that let you define variables, and their values. {project}/pillar/*.sls
pillar/top.sls a special sls file that contains hostnames, and under each the path to a pillar-file. Adding a pillar-file to a hostname makes all of it's contained variables accessible to that host's salt-minion. {project}/pillar/top.sls
Example of a
pillar/top.sls
file:base: # the environment the pillar applies to '*': # apply to all hostnames - filesystem.backup.tarsnap # includes keys defined in `{project}/pillar/filesystem/backup/tarsnap.sls` - passwd.service # includes keys defined in `{project}/pillar/passwd/service.sls` 'dev-*' # apply to all hostnames with the prefix 'dev-' - progs.vm.virtualbox.guestadditionsformat
The pillar is formatted as a nested dictionary. Beyond that, you can do just about anything. Personally, I have found the two practices to be particularly useful:
- have your dictionary-key paths match the filesystem location of your pillar items (to help you find/change them)
- define a base set of required_keys. You can override their values for specific machines, but this will allow your states to depend on the presence of a pillar entry.
Example of a pillarfile.
#!yaml|gpg passwd: will: mypasswordencryption
See saltstack configuration for instructions.
system passwords
passwd/shadow have very specific requirements for how their passwords are stored. To generate a system password:
Linux/FreeBSD:
python -c "import crypt,uuid; print(crypt.crypt( 'YOURPASSWORD', crypt.mksalt(crypt.METHOD_MD5) ))"
Windows
# password entered as plaintext
NOTE:
crypt is unix-only, and depends on your system's crypt C library. You can use python passlib to produce password hashes from anywhere.
ext_pillar (databases, other)
If your pillar's needs are more dynamic, or integrated into a system you can use various types of backends to produce youre pillar's output.
If using a traditional saltmaster setup, configuration goes into your
/usr/local/etc/salt/master
. If using a masterless setup, configuration goes into your/usr/local/etc/salt/minion
.CREATE TABLE users ( id INT, first TEXT, initial TEXT, last TEXT ); INSERT INTO users (id, first, initial, last) VALUES (1, 'will', 'j', 'pittman'), (2, 'alex', 'p', 'szeplaki');# /usr/local/etc/salt/master sqlite3: database: /var/tmp/test.db timeout: 5.0 ext_pillar: - sqlite3: MY_PEOPLE: query: 'SELECT id, first, last FROM mytable WHERE minion = ?' # query MUST include '?', which is substituted with the minion name depth: 1salt-call pillar.get MY_PEOPLE # local: # ----------- # 1: # ----------- # first: will # last: pittman # ----------- # 2: # ----------- # first: alex # last: szeplaki # -----------
Using Pillar
refreshing pillar
Your pillar gets refreshed whenever a state is applied, but sometimes while testing keys on the commandline you'd like to refresh your pillar.
salt-call saltutil.refresh_pillarstatefiles
Within statefiles, your pillar is exposed to jinja2.
#!stateconf {% set my_password = pillar['passwd']['will'] %}configfile template
You can apply your pillar as context to a configuration-file, enabling you to use both jinja AND your pillar.
I use this to more dynamically configure my
sshd_config
file../etc/ssh/sshd_config: file.managed: - source: salt://progs/netwk/openssh/files/sshd_config - template: - jinjacommandline
You can test your pillar values on the commandline, or even override pillar values while applying states to test new ones.
salt-call pillar.ls ## list all pillar items, accessible to this machine salt-call pillar.get passwd:will ## query value of a specific pillar item. salt-call state.apply my_state \ ## manually supply pillar-values to override any pillar='{ \ # included automatically "ftpusername": "test", \ "ftppassword": "0ydyfww3giq8" \ }'