Saltstack is a infrastructure management platform which promises to work with thousands of nodes at a time and still fast enough to communicate with those in near real time. In terms of functionality it compares with likes of Puppet, Chef, Ansible etc and can do configuration management and remote execution. It uses Python as primary underlying language though as a user you need not necessarily know Python well. For networking it uses ZeroMQ library to achieve the scale and speed it desires to target.
In this hands on tutorial we will start with a running salt setup and learn things as we go. We will cover some basic theory but only sufficient enough to get started. You will need a working setup of Virtualbox and Vagrant on your machine to get going. Clone the repo from here on your machine and from within saltstack-cluster directory execute “vagrant up”. While vagrant boxes will download and start, let’s go over some absolute basics for this part of tutorial:
Once boxes are up and running, ssh into salt-master
vagrant ssh salt-master
If your network connections are setup correctly - and the two/three boxes that you have are able to talk to each other properly - then running following command should show you some entries in “Unaccepted keys” section:
What we are seeing is requests from minions to accept their keys. This happens only once when a new minion (machine) comes up. Once this request is approved - master and minion can talk to each other. Let’s accept the all requests so we can fire some command against minions, for accepting keys from minions use command:
sudo salt-key -A
Once accepted, verify that the minion shows up in “Accepted keys” when you fire “sudo salt-key”. Now as a very first step let’s fire a command to ping all of our minions, you should see output similar to:
vagrant@smaster:~$ sudo salt '*' test.ping 0.sagent.learn.com: True
Let’s understand what is happening in above command: salt is the command to which our first argument is ‘’ - which means this command will execute on all minions. In a more real world scenario we would execute command only on a selected set of servers. This filtering of minions on which command should be run is called ‘targeting’ and there are multiple ways to define your targets. One of simplest ways would be to use a string which is part of hostname of target machines. For example if the expression in target field would be ‘apache*’ - then only servers with apache in their names would be selected for this particular command execution. Now let’s see what we are doing with servers that we are targeting. Our second argument is test.ping - this is simply calling ping() method from test module- which basically checks if minion is reachable. Fully qualified name of test module is salt.module.test but since it is an in built module we can only use short name. We could call other modules and their methods on command line in similar fashion, for a complete list of modules built in Salt check list of modules. Let’s call another method on test module and check version information of some libraries:
vagrant@smaster:~$ sudo salt '*' test.versions_information 0.sagent.learn.com: ---------- Dependency Versions: ---------- Jinja2: 2.7.2 M2Crypto: None Mako: 0.9.1 PyYAML: 3.10 PyZMQ: 14.0.1 Python: 2.7.6 (default, Jun 22 2015, 17:58:13)
Let’s run some more fun commands with Salt.
vagrant@smaster:~$ sudo salt '*' grains.items 0.sagent.learn.com: ---------- SSDs: biosreleasedate: 12/01/2006 biosversion: VirtualBox cpu_flags: - fpu - vme - de cpu_model: Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz cpuarch: x86_64 domain:
So we ran items method on grains module and we get some basic information about the machine, OS, hardware etc. These pieces of information of available by default for every machine where agent is operating and called grains. You can also set new pair of key and values to identify certain machines based on grains. For example you might add a grain with name ‘role’ and values like ‘load-balancer’, ‘web-server’ and so on (We will see in subsequent tutorials how to add custom grains). These values can be used to target machines for certain operations. For example over time a new node is added in topology - you will need to add the entry to load-balancer and reload the load balancer configuration.
Grains can also be used to target and filter minions based on their properties. Let’s try to ping all minions whose OS is CentOS. In our case we won’t get any minion because all of our minions are using Ubuntu OS:
vagrant@smaster:~$ sudo salt -G 'os:CentOS' test.ping No minions matched the target. No command was sent, no jid was assigned. ERROR: No return received
Let’s run another module’s method to do something fancy on our remote minion:
vagrant@smaster:~$ sudo salt '*' cmd.run 'ls /etc/salt' 0.sagent.learn.com: minion minion.d minion_id pki proxy
So we used “cmd” module to get list of files in a directory. As you can see most of stuff we have done so far is using command line. While you can form much longer commands, it might be better to write all of this in files and call them through certain mechanisms. We will see how to do that in coming parts of tutorial. While this tutorial just scratched the surface of Salt and got you started on command line, in next tutorial we will write a full fledged playbook to install desired stack on a machine.