< Previous | Contents | Next >
10.2.3. Salt States and Other Features
While remote execution is an important building block, it is only a tiny fraction of what SaltStack can do.
When setting up a new machine, you often run many commands and tests to determine the details of the system prior to installation. These operations can be formalized in re-usable configuration templates called state files. The operations described in state files can then be performed with a single state.apply salt command.
To save some time, you can rely on many ready-to-use state files that have been created by the community and which are distributed in “Salt formulas”:
➨ https://docs.saltstack.com/en/latest/topics/development/conventions/formulas. html
There are many other features that can be combined:
• Scheduled execution of actions
• Defining actions in response to events triggered by minions
• Collecting data out of minions
• Orchestration of a sequence of operations across multiple minions
• Applying states over SSH without installing the salt-minion service
• Provisioning systems on cloud infrastructures and bringing them under management
• And more
SaltStack is quite vast and we can’t possibly cover all the features here. In fact, there are books dedicated entirely to SaltStack and the online documentation is very extensive as well. Check it out if you want to learn more about its features:
➨ https://docs.saltstack.com/en/latest/
If you manage a significant number of machines, you would be well advised to learn more about SaltStack as you can save a significant amount of time when deploying new machines and you will be able to maintain a coherent configuration throughout your network.
To give you a taste of what it looks like to work with state files, we will cover a simple example: how to enable the APT repository and install a package that you create in section 10.3.3, “Creating a Package Repository for APT” [page 269] and section 10.3.2, “Creating Configuration Packages” [page 263]. You will also register a SSH key in root’s account so that you can login remotely in case of problems.
By default, state files are stored in /srv/salt on the master; they are YAML structured files with a .sls extension. Just like for running commands, applying a state relies on many state modules:
➨ https://docs.saltstack.com/en/latest/topics/tutorials/starting_states.html
➨ https://docs.saltstack.com/en/latest/ref/states/all/
Your /srv/salt/offsec.sls file will call three of those modules:
offsec_repository: pkgrepo.managed:
- name: deb http://pkgrepo.offsec.com offsec-internal main
- file: /etc/apt/sources.list.d/offsec.list
- key_url: salt://offsec-apt-key.asc
- require_in:
- pkg: offsec-defaults
offsec-defaults: pkg.installed
ssh_key_for_root: ssh_auth.present:
- user: root
- name: ssh-rsa AAAAB3NzaC1yc2...89C4N rhertzog@kali
offsec_repository: pkgrepo.managed:
- name: deb http://pkgrepo.offsec.com offsec-internal main
- file: /etc/apt/sources.list.d/offsec.list
- key_url: salt://offsec-apt-key.asc
- require_in:
- pkg: offsec-defaults
offsec-defaults: pkg.installed
ssh_key_for_root: ssh_auth.present:
- user: root
- name: ssh-rsa AAAAB3NzaC1yc2...89C4N rhertzog@kali
The offsec_repository state relies on the pkgrepo state module. The example uses the managed
function in that state module to register a package repository. With the key_url attribute, you
let salt know that the (ASCII armored) GPG key required to verify the repository’s signature can be fetched from /srv/salt/offsec-apt-key.asc on the salt master. The require_in attribute ensures that this state is processed before the offsec-defaults, since the latter needs the repository correctly configured to be able to install the package.
The offsec-defaults state installs the package of the same name. This shows that the name of the key is often an important value for states, although it can always be overridden with a name at- tribute (as done for the former state). For simple-cases like this one, this is both readable and concise.
The last state (ssh_key_for_root) adds the SSH key given in the name attribute to /root/.ssh/ authorized_keys (the target user is set in the user attribute). Note that we have shortened the key for readability here, but you should put the full key in the name attribute.
This state file can next be applied to a given minion:
server# salt kali-scratch state.apply offsec
kali-scratch:
----------
ID: offsec_repository Function: pkgrepo.managed
Name: deb http://pkgrepo.offsec.com offsec-internal main Result: True
Comment: Configured package repo ’deb http://pkgrepo.offsec.com offsec-internal
➥ main’
Started: 06:00:15.767794
Duration: 4707.35 ms Changes:
----------
repo:
deb http://pkgrepo.offsec.com offsec-internal main
----------
ID: offsec-defaults Function: pkg.installed
Result: True
Comment: The following packages were installed/updated: offsec-defaults Started: 06:00:21.325184
Duration: 19246.041 ms Changes:
----------
offsec-defaults:
----------
new:
1.0
old:
----------
ID: ssh_key_for_root Function: ssh_auth.present
server# salt kali-scratch state.apply offsec
kali-scratch:
----------
ID: offsec_repository Function: pkgrepo.managed
Name: deb http://pkgrepo.offsec.com offsec-internal main Result: True
Comment: Configured package repo ’deb http://pkgrepo.offsec.com offsec-internal
➥ main’
Started: 06:00:15.767794
Duration: 4707.35 ms Changes:
----------
repo:
deb http://pkgrepo.offsec.com offsec-internal main
----------
ID: offsec-defaults Function: pkg.installed
Result: True
Comment: The following packages were installed/updated: offsec-defaults Started: 06:00:21.325184
Duration: 19246.041 ms Changes:
----------
offsec-defaults:
----------
new:
1.0
old:
----------
ID: ssh_key_for_root Function: ssh_auth.present
Name: ssh-rsa AAAAB3NzaC1yc2...89C4N rhertzog@kali Result: True
Comment: The authorized host key AAAAB3NzaC1yc2...89C4N for user root was added Started: 06:00:40.582539
Duration: 62.103 ms Changes:
---------- AAAAB3NzaC1yc2...89C4N:
New
Summary for kali-scratch
------------
Succeeded: 3 (changed=3)
Failed: 0
------------
Total states run: 3
Total run time: 24.015 s
Name: ssh-rsa AAAAB3NzaC1yc2...89C4N rhertzog@kali Result: True
Comment: The authorized host key AAAAB3NzaC1yc2...89C4N for user root was added Started: 06:00:40.582539
Duration: 62.103 ms Changes:
---------- AAAAB3NzaC1yc2...89C4N:
New
Summary for kali-scratch
------------
Succeeded: 3 (changed=3)
Failed: 0
------------
Total states run: 3
Total run time: 24.015 s
It can also be permanently associated to the minion by recording it in the /srv/salt/top.sls
file, which is used by the state.highstate command to apply all relevant states in a single pass:
server# cat /srv/salt/top.sls
base:
kali-scratch:
- offsec
server# salt kali-scratch state.highstate
kali-scratch:
----------
ID: offsec_repository Function: pkgrepo.managed
Name: deb http://pkgrepo.offsec.com offsec-internal main Result: True
Comment: Package repo ’deb http://pkgrepo.offsec.com offsec-internal main’ already
➥ configured Started: 06:06:20.650053
Duration: 62.805 ms Changes:
----------
ID: offsec-defaults Function: pkg.installed
Result: True
Comment: Package offsec-defaults is already installed Started: 06:06:21.436193
Duration: 385.092 ms Changes:
----------
ID: ssh_key_for_root
server# cat /srv/salt/top.sls
base:
kali-scratch:
- offsec
server# salt kali-scratch state.highstate
kali-scratch:
----------
ID: offsec_repository Function: pkgrepo.managed
Name: deb http://pkgrepo.offsec.com offsec-internal main Result: True
Comment: Package repo ’deb http://pkgrepo.offsec.com offsec-internal main’ already
➥ configured Started: 06:06:20.650053
Duration: 62.805 ms Changes:
----------
ID: offsec-defaults Function: pkg.installed
Result: True
Comment: Package offsec-defaults is already installed Started: 06:06:21.436193
Duration: 385.092 ms Changes:
----------
ID: ssh_key_for_root
Function: ssh_auth.present
Name: ssh-rsa AAAAB3NzaC1yc2...89C4N rhertzog@kali Result: True
Comment: The authorized host key AAAAB3NzaC1yc2...89C4N is already present for
➥ user root
Started: 06:06:21.821811
Duration: 1.936 ms Changes:
Summary for kali-scratch
------------
Succeeded: 3
Failed: 0
------------
Total states run: 3
Total run time: 449.833 ms
Function: ssh_auth.present
Name: ssh-rsa AAAAB3NzaC1yc2...89C4N rhertzog@kali Result: True
Comment: The authorized host key AAAAB3NzaC1yc2...89C4N is already present for
➥ user root
Started: 06:06:21.821811
Duration: 1.936 ms Changes:
Summary for kali-scratch
------------
Succeeded: 3
Failed: 0
------------
Total states run: 3
Total run time: 449.833 ms