SaltStack – Using Grains

Grains are basically static data about a system. Grains are collected from the operating system, domain name, IP address, kernel, OS type, memory, and many other system properties.

By using the appropriate Grain, you can target specific machines, or specific things about a machine, like the OS, or a specific kernel version and so forth. For example, to target CentOS machines:

salt -G ‘os:CentOS’

Despite being static data, if an underlying parameter changes then the Grain will be refreshed accordingly.

If you need to narrow down the targeting, you can combine grains as follows:

salt -C ‘G@osmajorrelease:7 and G@plesk_installed:true’

What most people don’t realize is that Grains can be set in any host to any value by you and used for any purpose. So if you set a Grain call ‘FRONT_END_APP_SERVER’ on all your web servers that are public facing, then you can target them specifically. In fact, Grains provide a neat way to target application and functionality aspects of your software just by setting different Grains are easy to set and remove.

Listing grains

By using the command you can list the available grains, the exact format is:

salt ‘’

With the following output (reduced output shown):
– SSDs
– biosreleasedate
– biosversion
– cpu_flags
– cpu_model
– cpuarch
– domain
– fqdn
– fqdn_ip4
– fqdn_ip6
– gpus
– host
– hwaddr_interfaces

To get the specific data for each change the command to grains.items which will render output like the following (note that output is in YAML formatting which may not show correctly on this blog):

– 2
– 6
– 6
– final
– 0
– 2015
– 5
– 0
– 0

Using Grains

To set a grain against a host you can use the following method:

salt '' grains.setvals "{'php70':'True'}"


To remove a grain use:

salt '' grains.delval 'php55'


To see what servers have a specific grain:

root@salt:~# salt -G 'php55:True'

Writing you own grains

Grains are easy to write, all you basically return to the caller is a YAML formatted dictionary. This means you could implement anything just by returning specially formatted data in a common sense logical fashion. One novel use could be application specific performance data, even business transactional data could be coded and returned. The data could be requested by an app calling the salt interface rather than the Salt Server.


Taking the Python example from the SaltStack website:

#!/usr/bin/env python
def _my_custom_grain():
    my_grain = {'foo': 'bar', 'hello': 'world'}
    return my_grain

def main():
    # initialize a grains dictionary
    grains = {}
    grains['my_grains'] = _my_custom_grain()
    return grains

Practical Uses

Apart from system specific information, grains are handy to use for:

  • Application and functionality grouping.
  • Performance and monitoring grouping.
  • Production, UAT and development system groupings.
  • Dynamically accessing IAAS applications.
  • Business/Application specific metrics.

The list doesn’t end there of course and I would be interested to see what other uses people have for them.

More information on Grains can be found via the SaltStack web site: