Understanding and writing Salt states
In this recipe, we will learn one of the most important components of Salt states. We will understand what states are, how to write them, and how to use pillar data in writing states. We will configure a state called user
to add a user to the development
environment.
How to do it...
- First, we will create a directory for the state and populate it with state data:
[root@salt-master ~]# mkdir \ /opt/salt-cookbook/development/user [ root@salt-master ~]# touch \ /opt/salt-cookbook/development/user/init.sls
- Edit
/opt/salt-cookbook/development/user/init.sls
and add the following contents:generic_user: user.present: - name: {{ pillar['dev_user']['name'] }} - shell: /bin/bash - home: /home/{{ pillar['dev_user']['name'] }} - uid: {{ pillar['dev_user']['uid'] }} - password: {{ pillar['dev_user']['password'] }}
How it works...
In Salt, states are written to determine which and what kind of resources will be added to a system. States are written with the help of built-in state modules, a full list of which can be found at http://docs.saltstack.com/en/latest/ref/states/all/. Using these state
modules, we can configure a massive amount of system resources, a few being users, groups, files, repositories, packages, services, code repositories, and so on. These states are then configured to be available to desired nodes or minions based on various properties.
In this recipe, we configured a user to be added to a system in the development
environment, irrespective of the operating system.
First, we created a directory with the name of the state, that is, the user
in the base directory of the development
environment. Then, we created a file named init.sls
, which is the default file in a state
directory. Salt State File or SLS is used as the only file type of all Salt configuration files.
In the first line, we defined a custom name of this resource that can be any name, we named it generic_user
. This name can be used in subsequent resources, when referencing this resource and have to be unique in the complete state space being used by the minion. However, this is optional as the definition could also be written as follows:
{{ pillar['dev_user']['name'] }}: user.present: - shell: /bin/bash - home: /home/{{ pillar['dev_user']['name'] }}
Here, we also learn about how to refer to pillar data when writing states. It is usually in the following format:
{{ pillar[<first_key>][<second_key>]... }}
However, do note that, in the reference, the directory name of the pillar, that is, user
is never used. Instead, the reference begins from the first YAML key found in the file, that is, dev_user
, followed by the next mentioned key. Also, note that the first keys are always unique in the environment for a minion, that is, dev_user
can only be used once as the first key. If a second file is created, called devs.sls
, and the first key is named dev_user
, there will be a conflict of key names and Salt synchronization will fail.
The following method can also be used to achieve the same objective:
{{ pillar['pillar.get']('dev_user:name', 'defaultuser') }}:
This is a better method as it also gives us the option to mention a default value if the pillar is not available.
The second line mentions the built-in state module name, that is, user
and the function is present. There can be multiple functions for a module name and this can be looked up in the URL mentioned earlier in this recipe. For the user
module, the two functions available are present and absent, which in turn take multiple parameters such as name
, uid
, gid
, password
, and so on.
Next, we see how each of the function parameters are populated for the user using static data, as well as pillar data:
- name: {{ pillar['dev_user']['name'] }} - shell: /bin/bash - home: /home/{{ pillar['dev_user']['name'] }} - uid: {{ pillar['dev_user']['uid'] }}
See also
- Chapter 2, Writing Advanced Salt Configurations, to learn more about advanced state configurations
- The Understanding and writing the top file recipe, to learn about how to make Salt states available to minions