DevOps
Saltstack Tutorial for beginners [2023]
Saltstack Tutorial: What Is SaltStack?
Salt (Salt-Stack) is infrastructure automation and management system written in Python. You’ll see through this introduction that it is a powerful tool. Please note that this saltstack tutorial is for beginners.
Installation
Let’s begin by installing it. I am using a Debian based distro (Ubuntu, Linux Mint ..), for other distros please check the installation manual (for this part).
For this saltstack tutorial blog post, I am going to install Master and Minion in the same server (localhost).
Master is the server and Minion is the target.
1 2 3 4 5 6 7 |
sudo apt-get install python-software-properties sudo add-apt-repository ppa:saltstack/salt sudo apt-get update sudo apt-get install salt-master sudo apt-get install salt-minion service salt-master start service salt-minion start |
We’re going for now to configure the (local) minion:
Search for master and tell it to use localhost or 127.0.0.1 or even the default gateway 10.0.0.1
and restart the service :
1 |
service salt-minion restart |
Salt works with a system of keys, it can tells you which Minion was accepted/rejected. To list all the Minion keys your Master knows about, type :
1 |
salt-key -L |
If the host is rejected, add it using -a :
1 |
salt-key -a 'hostname' |
Check that the Minion responds:
the ‘*’ refers to all Minions whose key is accepted. You can specify instead, the FQDN of your minion.
Usage
We’re going, for now, some usage examples:
For Nginx (Installation of the server and starting its service):
1 2 |
salt '*' pkg.install nginx salt '*' service.start nginx |
For vim (Installation of vim)
1 |
salt '*' pkg.install vim |
You can even see all of your minion servers’ disk usage:
Or list network interfaces:
1 |
salt '*' network.interfaces |
You can also execute a command
salt ‘*’ cmd.run ‘ls -l /etc’
To list the documentation you can type
1 |
salt '*' sys.doc | less |
Grains
Salt comes with an interface to derive information about the underlying system. This is called the grains interface because it presents salt with grains of information.
The grains interface is made available to Salt modules and components so that the right salt minion commands are automatically available on the right systems.
Let’s view all grains our minions (*):
1 |
salt '*' grains.ls |
To list grains data:
1 |
salt '*' grains.items |
As an example, if we want to match all CentOS and ping them, we can also use grains this way:
1 |
salt -G 'os:CentOS' test.ping |
To list all minions with 64-bit CPUs, and return number of CPU cores for each matching one:
1 |
salt -G 'cpuarch:x86_64' grains.item num_cpus |
Adding new grains
Grains can also be assigned within the minion configuration file.
Open :
1 |
/etc/salt/minion |
And search for “grains”
1 2 3 4 5 |
grains: roles: - webserver - memcache deployment: mydatacenter |
(As you can see, there is a list of grains like “deployment” that have the value mydatacenter. You can add your own grain. Make sure everything respects YAML language standards. )
or by adding the code below (without “grains:”) in
1 |
/etc/salt/grains |
Example:
1 2 3 4 |
roles: - webserver - memcache deployment: mydatacente |
If your favorited language is Python, you have the habit of using dicts, you can use it also as a grain :
1 2 3 4 5 6 7 8 |
auth: { 'host':'host.server.domain.tld', 'port':8900, 'users':{ 'web': {'login':'web', 'password':'login'}, 'dba': {'login':'dba', 'password':'pass'}, } } |
To query the last example :
1 |
salt "*" grains.get 'host' |
Output format
Changing the output format is easy:
1 |
salt myminion grains.item pythonpath --out=pprint |
“–out” could be also one of the values listed here.
Troubleshooting
As troubleshooting is always part of learning, to debug the master or the minion you can use:
1 2 |
salt-master -l debug salt-minion -l debug |
Let’s see what the port connectivity from the minion with the NC command.
(Remember that salt uses two ports, you can change them in master/minion configuration under /etc/salt/)
1 2 |
nc -v -z salt.master.ip 4505 nc -v -z salt.master.ip 4506 |
Debug with salt-call
We’re going to use salt-call with state.highstate if you’re not familiar with states, we’re going to explain them for later:
salt-call -l debug state.highstate
The verbose output could help you troubleshoot your problems. You only need patience.
Turn up logs
Salt can be quite chatty when you change the logging setting to debug:
1 |
salt-minion -l debug |
Foreground run
By not starting the minion in daemon mode (-d) one can view any output from the minion as it works:
1 |
salt-minion & |
Increase the default timeout value when running salt. For example, to change the default timeout to 60 seconds:
1 |
salt -t 60 |
Combine all:
1 2 |
salt-minion -l debug & # On the minion salt '*' state.highstate -t 60 # On the master |
Salt Authentification
We already spoke about keys but here is a reminder. We’re using two main functionality of salt-key command (on the master).
To list the keys that are on the master:
salt-key -L
The keys that have been rejected, accepted and pending acceptance are listed.
The easiest way to accept the minion key is to accept all pending keys:
1 |
salt-key -A |
Salt file roots
A base environment is required to house the top file.
In
1 |
/etc/salt/master |
you can add :
1 2 3 4 5 6 7 8 9 |
file_roots: base: - /srv/salt/ dev: - /srv/salt/dev/services - /srv/salt/dev/states prod: - /srv/salt/prod/services - /srv/salt/prod/states |
If you want to organize more as I did, you can create two subdirectories: states and pillars
1 2 |
/srv/salt/dev/states /srv/salt/dev/pillars |
and under each directory, you can create other subdirectories ( dev, integration, test, production ..etc).
In this blog post, I am going to speak about states, but not pillars. You can find good examples in the official documentation.
Salt States
If you consider working with salt, states are an important point to understand and it is not complicated.
As we already had configured “file_roots” which is “/srv/salt/”, we can move to the next simple example :
Example:
On the master, add the following code to
1 |
/srv/salt/top.sls |
1 2 3 4 5 |
#Code to add base: '*': - webserve |
“base” is an environment and it’s our default one. You can define a list of minion that will be attached to that environment
Explanation:
In the last example, all hosts are concerned ( ‘*’ ), and the state webserver will be applied to them.
Minions can be matched by glob, PCRE regular expression, or by grains.
If we modify the last example and use “grains” matching instead of just writing “*”, you’ll have to modify your code like this :
1 2 3 4 |
base: 'os:Debian': - match: grain - webserver |
os: Debian’ is the used grain to match host(s)
The last line tells Salt to use the sls called “webserver”.
Let’s keep the first example for the rest of this tutorial and continue to the second part (SLS).
Create our ‘sls’ file called ‘webserver.sls’. Write the next code to that file:
1 2 3 |
nginx: # ID declaration pkg: # state declaration - installed # function declaration |
ID declaration is a random name but unique, in our example, it is the name of the package that should be installed on our minions.
When you type :
1 |
salt '*' state.highstate |
Salt will install the package defined in “webserver.sls” on your target minions defined in “top.sls” file
Let’s move to another interesting part of salt: How can we manage a configuration file on a distant machine? This will be the main subject of the next saltstack tutorial post. Also, you can check our latest post regarding Docker ADD vs COPY. Enjoy 🙂
-
DevOps55 years ago
How to build a Docker cron job Container easily [2023]
-
Linux55 years ago
mail Command in Linux/Unix with 10+ Examples [2023]
-
DevOps55 years ago
Docker ADD vs COPY vs VOLUME – [2023]
-
DevOps55 years ago
How to setup Pritunl VPN on AWS to Access Servers
-
Linux55 years ago
Grep Command In Unix/Linux with 25+ Examples [2023]
-
Linux55 years ago
How To setup Django with Postgres, Nginx, and Gunicorn on Ubuntu 20.04
-
Linux55 years ago
Find command in Unix/Linux with 30+ Examples [2023]
-
Linux55 years ago
Whereis command in Linux with 10+ Examples [2023]