Review: Salt keeps server automation simple

FREE

Become An Insider

Sign up now and get free access to hundreds of Insider articles, guides, reviews, interviews, blogs, and other premium content from the best tech brands on the Internet: CIO, CITEworld, CSO, Computerworld, InfoWorld, ITworld and Network World. Learn more.

Salt brings simplicity, flexibility, and high scalability to Linux and Unix server infrastructure management -- it does Windows too

Like Puppet, Chef, and Ansible, Salt is an open source server management and automation solution with commercial, officially supported options. Based on command-line-driven server and client services and utilities, Salt is primarily focused on Linux and Unix server management, though it offers significant Windows management capabilities as well. While Salt may look simple on its face, it's surprisingly powerful and extensible, and it has been designed to handle extremely large numbers of clients.

Salt uses a push method of communication with clients by default, though there's also a means to use SSH rather than locally installed clients. Using the default push method, the clients don't actively check in with a master server; rather, the master server reaches out to control or modify each client based on commands issued manually or through scheduling. But again, Salt can also operate in the other direction, with clients querying the master for updates. Salt functions asynchronously, and as such, it's very fast. It also incorporates an asynchronous file server for file deployments.

[ Review: Ansible orchestration is a veteran Unix admin's dream | Review: Chef cooks up configuration management | Review: Puppet Enterprise 3.0 pulls more strings | Puppet or Chef: The configuration management dilemma | Subscribe to InfoWorld's Data Center newsletter to stay on top of the latest developments. ]

Salt can be distilled into a few simple core concepts. You can issue raw commands to clients or groups of clients, or you can create YAML configuration templates called "states" to control the behavior of those clients. Further, you can extend and abstract functions and parameters through the use of extended templates called "pillars." All of this is combined with the capability to use a few different scripting interpreters to extend functionality through the use of Python or PyDSL (Python Domain Specific Language).

In addition to the free open source version, Salt is available in supported Professional and Enterprise versions (which are also completely open source) from SaltStack. SaltStack Enterprise costs $150 per node per year, with volume discounts and site licenses available.

Once you have a master and a selection of minions installed and running, you'll find that your master already has a key request in place for each minion that has tried to contact the master. You can view all of the keys on the master by issuing a salt-key -L command.

It's interesting to note here you may wind up with multiple keys per minion if there are multiple reverse zone entries for that minion's IP. In practice, that shouldn't happen, but you can delete the additional requests later.

On the master, you can accept all keys by issuing a salt-key -A, which will allow the master and the minions to communicate. You can then test this with the general salt command:

[root@saltmaster salt]# salt "*" test.ping
saltcentos.iwlabs.net:
    True
saltubuntu.iwlabs.net:
    True

This will display all known Salt minions and their status. Once this is done, you can now begin issuing commands and building up "states" and "pillars."

You can also poll minions for information such as network interface configuration:

[root@saltmaster salt]# salt "*" network.interfaces
saltubuntu.iwlabs.net:
    ----------
    eth0:
        ----------
        hwaddr:
            00:50:56:96:7f:07
        inet:
            ----------
            - address:
                172.16.32.70
            - broadcast:
                172.16.32.255
            - label:
                eth0
            - netmask:
                255.255.255.0
        inet6:
            ----------
            - address:
                fe80::250:56ff:fe96:7f07
            - prefixlen:
                64
        up:
            True
    lo:
        ----------
        hwaddr:
            00:00:00:00:00:00
        inet:
            ----------
            - address:
                127.0.0.1
            - broadcast:
                None
            - label:
                lo
            - netmask:
                255.0.0.0
        inet6:
            ----------
            - address:
                ::1
            - prefixlen:
                128
        up:
            True

This truncated example shows the network interface information for the minion, including IP addressing, MAC addressing, and interface status.

Grains, states, and pillars
You can segment minions into logical groups using "grains," which reference commonalities among the minions in order to perform required tasks. You could run this command to address only CentOS hosts:

[root@saltmaster salt]# salt -G 'os:CentOS' network.interfaces

Alternatively, you can use:

[root@saltmaster salt]# salt -G 'kernelrelease:2.6.32-358.11.1.el6.x86_64' network.interfaces

The grains.items directive will pull an inventory of one or more minions:

We then run the salt command to reference that directory:

[root@saltmaster ntpd]# salt "saltcentos.iwlabs.net" state.sls ntpd
saltcentos.iwlabs.net:
----------
    State: - file
    Name:      /etc/ntp.conf
    Function:  managed
        Result:    True
        Comment:   File /etc/ntp.conf updated
        Changes:   diff: New file
                  
----------
    State: - pkg
    Name:      ntp
    Function:  installed
        Result:    True
        Comment:   The following packages were installed/updated: ntp.
        Changes:   ntp: { new : 4.2.4p8-3.el6.centos
old :
}
                  
----------
    State: - service
    Name:      ntpd
    Function:  running
        Result:    True
        Comment:   Started Service ntpd
        Changes:   ntpd: True

We can see that Salt has installed the ntp package, added the custom configuration file, and started the service.

We can get a little deeper in state files to accommodate issues like the aforementioned package naming disparity. We can use simple if/then constructs to alter the package name depending on the OS running on the minion:

{% if grains['os'] == 'RedHat'%}
    - name: httpd
    {% endif %}
{% if grains['os'] == 'Ubuntu'%}
    - name: apache
    {% endif %}

Here's a Python example that will make sure that ntp is installed and running:

#!py

def run():
    return {'include': ['python'],
            'ntp': {'pkg': ['installed'],
                    'service': [ { 'name': 'ntpd'}, 'running',
                    { 'require': [ {'pkg': 'ntp'} ] }
                    ]
             }
     }

You can also pass variables to files in order to dynamically alter the contents when the file is placed on the minion. This can be used for specific alterations in a configuration file for a particular set of clients, for example.

The upshot of all this is that you can do simple things easily with the default YAML syntax and leverage Python and PyDSL to accomplish more complex tasks.

Next up are pillars, which are sets of data that can be made available to states while they're running. This allows you to collect common data points in a central file hierarchy and reference them elsewhere. For instance, you might have a list of user names and user IDs, or a simple script that determines package names based on the OS in use, or any number of other parameters that need to be globally available.

A Python-based Web UI for Salt, called Halite, can be installed and run on the same server as the Salt master. As with many elements of Salt, you're best off using the development version of Halite for now, as there are inconsistencies between versions that will cause unexpected behavior. Using the development versions of Salt from the Git repo for both Salt and Halite brought up a functional Web interface.

Configuring the Web interface is relatively straightforward, requiring changes to be made to the Salt master config file. This is also where the configuration for external authentication must be completed in order to allow users to log into Halite. By default this uses the local PAM authentication method on the server itself.

Halite is a new, bare-bones Web UI that offers views of running jobs, minion status, and event logging, and it allows you to execute commands on minions. While it does work, it is not as complete as it could be, and it suffers from the bugs you would expect from new code. In practice, most Salt admins will use Halite as an overview tool for now, and look forward to a greater feature set in the future.

Deep Salt
Beyond the simple aspects of Salt lie a multitude of heavy-duty features. For instance, minions can attach to multiple masters, allowing for redundancy. In addition, masters can themselves be minions to upstream masters, which allows for high scalability. You can issue commands on an upstream master that will flow down to the masters below, then on to the minions controlled by those masters.

Further, the peer system allows minions to ask questions of a Salt master that may require data collection from other servers. For instance, a minion may need to populate data in a configuration derived from a database residing on another server. This system allows the minion to query the master to retrieve that data, which is then used for the configuration. Minions can send out flags when they are back in operation after some manual changes, and trigger events such as being added to a list of available database servers or being re-added to a load-balancer configuration.

To continue reading, please begin the free registration process or sign in to your Insider account by entering your email address:
Mobile Security Insider: iOS vs. Android vs. BlackBerry vs. Windows Phone
Recommended
Join the discussion
Be the first to comment on this article. Our Commenting Policies