SaltStack: How to target specific minions - salt-stack

Is it possible to target a specific set of minions when applying a state? Instead of doing:
salt '*' state.sls mystate.sls
I want to do:
salt '[key1,key2,...]' state.sls mystate.sls

Of course, just use -L
salt -L 'key1,key2,key3,...' state.sls mystate.sls
http://docs.saltstack.com/en/latest/topics/targeting/globbing.html#lists

Related

How to apply a top file when using salt-ssh and roster file

I'm new to salt, and I'm trying to use salt-ssh to manage hosts. I have the following roster file
~/salt/roster
pi:
host: raspberypi1.local
tty: True
sudo: True
I have salt states
~/salt/states/docker.sls
I am able to apply the salt states by calling the state explicitly
sudo salt-ssh '*' -c . state.apply docker
How can I make it so that I don't have to call the state directly? I want the raspberypi1.local node to always run the docker state.
Things I've tried
Make ~/salt/top.sls
base:
'pi*':
- docker
However the top.sls appears to be ignored by salt-ssh
I've tried editing ~/salt/Saltfile to point at a specific file_roots
salt-ssh:
roster_file: /Users/foobar/salt/roster
config_dir: /Users/foobar/salt
log_file: /Users/foobar/salt/log.txt
ssh_log_file: /Users/foobar/salt/ssh-log.txt
file_roots:
base:
- /Users/foobar/salt/top.sls
Here file_roots also appears to be ignored.
Whats the proper way to tie states to nodes when using salt-ssh?
I moved ~/salt/top.sls to ~/salt/states/top.sls, and removed file_roots: entirely from the Saltfile (it belongs in the master file). And now I am able to apply states like so:
sudo salt-ssh '*' -c . state.apply

Salt-Stack exclude minions from salt '*' state.apply in top.sls

Is there a way to exclude minions from being targeted even if I run salt '*' state.apply on CLI?
Ideally the exclusion should be declared somewhere in top.sls
From CLI, you can exclude minion as follows,
salt -C 'not minion-id' test.ping
Above pattern is available since version 2015.8.0. If you are using older version then,
salt -C '* and not minion-id' test.ping
Please read more about Compound matchers here.
You want to use compound matching. Targetting all the minions for the webserver states except minion_id_1 can be done like this.
base:
'not minion_id_1':
- match: compound
- webserver
Documentation on compound matching can be found here: docs.saltstack.com/en/latest/topics/targeting/compound.html

How to seamlessly rename a minion?

I am considering to move to salt (currently using ansible) to manage a set of standalone IoT devices (Raspberry Pi in practical terms).
The devices would be installed with a generic image, to which I would add on top the installation of salt (client side) as well as a configuration file pointing to salt-master, which is going to serve state files to be consumed by the minions.
The state files include an HTTP query for a name, which is then applied to the device (as its hostname). The obvious problem is that at that stage the minion has already registered with salt-master under the previous (generic) name.
How to handle such a situation? Specifically: how to propagate the new hostname to salt-master? (just changing the hostname and rebooting did not help, I assume the hostname is bundled, on the server, with the ID of the minion).
The more general question would be whether salt is the right product for such a situatiuon (where setting the state of the minion changes its name, among others)
Your Minion ID is based on the hostname during the installation. When you change the hostname after you installed the salt-minion, the Minion ID will not change.
The Minion ID is specified in /etc/salt/minion_id. When you change the Minion ID:
The Minion will identify itself with the new ID to the Master and stops listening to the old ID.
The Master will detect the new Minion ID as a new Minion and it shows a new key in Unaccepted Keys.
After accepting the key on the Master you will be able to use the Minion with the new key only. The old key is still accepted on the Master but doesn't work anymore.
I can come up with two solutions for your situation:
Use salt-ssh to provision your minions. The Master will connect to your Raspberry PI using SSH. It will setup the correct hostname, install and configure salt-minion. After this is finished, your minion will connect to the master with the correct ID. But this requires the Master to know when and where a minion is available...
You mentioned the state where the hostname is set. Change the Minion ID and restart the minion service in the same state. This will change the Minion ID but you need to accept the new key afterwards. Note that the minion will never report a state as successfully finished when you restart the salt-minion service in it.
Here is a short script to change the hostname/minion_id. It should also work well for batch jobs. Simply call the script like so: sudo ./change-minion-id oldminionid newminionid
change-minion-id:
#! /bin/bash
echo $2; salt "$1" cmd.run "echo $2> /etc/hostname && hostname $2 && hostname > /etc/salt/minion_id" && salt "$1" service.restart "salt-minion" && salt-key -d $1 -y && salt-key -a $2 -y
My answer is a direct rip off from user deput_d. I modified it a bit for what I needed.
Even my code will return a Minion did not return. [No response] (due to the salt-minion restart) but this error should be ignored, just let it run. I wait for 40 seconds just to be sure that the minion has re-connected:
#!/bin/bash
echo "salt rename $1->$2"; salt "$1" cmd.run "echo $2> /etc/hostname && hostname $2 && hostname > /etc/salt/minion_id" && salt "$1" cmd.run "/etc/init.d/salt-minion restart &" || true
salt-key -d $1 -y && echo "Will sleep for 40 seconds while minion reconnects" && sleep 40 && salt-key -a $2 -y

How to render a sls pillar file in saltstack?

Is there a way I could render an sls file that resides in the pillar? Something more or less the equivalent of state.show_sls?
Take a look at pillar module. You can check rendered pillar (or rather resulting data) by calling e.g.
$ salt '*' pillar.items
Or some particular part of the pillar e.g. elasticsearch:
$ salt '*' pillar.get elasticsearch
See also the slsutil.renderer module:
salt '*' slsutil.renderer salt://path/to/file
salt '*' slsutil.renderer /path/to/file
salt '*' slsutil.renderer /path/to/file.jinja 'jinja'
salt '*' slsutil.renderer /path/to/file.sls 'jinja|yaml'
salt '*' slsutil.renderer string='Inline template! {{ saltenv }}'
salt '*' slsutil.renderer string='Hello, {{ name }}.' name='world'
For pillar sls files it may only work on the saltmaster. Example:
salt-call --local slsutil.renderer /srv/nacl/pillar/myservice/init.sls 'yamlex'

Saltstack - Preview Highstate

Is there a way to preview what files will be served to a minion on a state.highstate? I know that you can run state.show_highstate, but that is not the output I am looking for. For example, inside /path/to/recurse/dir/ I have foo.txt and bar.txt and in my sls file I have
/path/to/recurse/dir/:
file.recurse:
- source: salt://dir/
I would like to run state.preview_highstate and it would show me the contents of foo.txt and bar.txt. Does anyone know how to go about this without just running state.highstate?
If you are able to run the state on the minion but just don't want to apply any changes you can append the test=True to your command:
salt '*' state.highstate test=True
This will run the highstate on the minion but will not make any changes to the system. Changes that would be applied are shown in yellow.

Resources