Friday, 29 September 2017

SaltStack Targeting Methods - Grain Matching

We have been learning Salt remote command execution and how minions can be targeted, in particular. We have already covered three methods of targeting minions - Glob matching, PCRE matching and List matching. We move a step further and know about how we can target minions using grain matching.


What are Grains?


Grains are static data stores where we can store data about or describing our minions, in key-value format. We can use these grains to target our minions. We can get information about available grains using below command -

$ salt 'centos-rack1' grains.items
centos-rack1:
    ----------
    SSDs:
    cpu_flags:
        - fpu
        - vme
        - de
 ...
 ...
    num_cpus:
        4
    num_gpus:
        0
    os:
        RedHat
    os_family:
        RedHat
    osarch:
        x86_64
    oscodename:
        Santiago
    osfinger:
        Red Hat Enterprise Linux Server-6
 ...
 ...
 selinux:
        ----------
        enabled:
            False
        enforced:
            Disabled
    server_id:
        538503645
    shell:
        /bin/sh
    uid:
        0
    username:
        root
 ...
 ...

Thus, from above output, we can observe that there several grains, for example os, os_family, osfinger, etc. We can retrieve a specific information by targeting a particular grain using below command -

$ salt 'centos-rack1' grains.item os
centos-rack1:
    ----------
    os:
        RedHat
  
$ salt 'centos-rack1' grains.item os_family
centos-rack1:
    ----------
    os_family:
        RedHat
  
$ salt 'centos-rack1' grains.item osfinger
centos-rack1:
    ----------
    osfinger:
        Red Hat Enterprise Linux Server-6

We can create our own custom grains to store more detailed information, that may be used to target minions more specifically. For example, we may wish to run a remote execution command on the machines situated at a particular location or present in a particular rack. In that case, we can create our custom grain as shown below:

$ salt 'centos-rack1' grains.setval racknum 1
centos-rack1:
    ----------
    racknum:
        1
  
$ salt 'redhat-rack2' grains.setval racknum 2
redhat-rack2:
    ----------
    racknum:
        2

We can confirm this by retrieving the grain information.

$ salt '*' grains.item racknum
redhat-rack2:
    ----------
    racknum:
        2
centos-rack1:
    ----------
    racknum:
        1

We can also set more than one values associated with a grain as shown below :

$ salt 'centos-rack1' grains.setval application '["web", "nginx", "prod"]'
centos-rack1:
    ----------
    application:
        - web
        - nginx
        - prod

$ salt 'redhat-rack2' grains.setval application '["database", "mysql", "dev"]'
redhat-rack2:
    ----------
    application:
        - database
        - mysql
        - dev

In order to delete these values, you can use -

$ salt 'redhat-rack2' grains.delval application
redhat-rack2:
    None

$ salt 'centos-rack1' grains.delval application
centos-rack1:
    None

Please note that, even though we have deleted the custom grains, they do persist with a return value of None. To get rid of them completely, we need to mention destructive=True explicitly.

$ salt 'centos-rack1' grains.delval application destructive=True
centos-rack1:
    None
 
$ salt 'centos-rack1' grains.item application
centos-rack1:
    ----------
    application:

With this available information in the form of grains, we can target our minions using grain matching. In this case, we specify the option -G or --grain with salt command.

Grain Matching


Now that, we know what grains are and how they are retrieved, it's time to target minions using grains such that the remote execution commands are executed based on the values available in the grains. For this, we make use of --grain option as below -

# Targetting the machines with RedHat os_family
$ salt -G 'os_family:RedHat' test.ping
redhat-rack2:
    True
centos-rack1:
    True

We can also target the machines more specifically, e.g. machines with CentOS installed, as -
# Targetting the machines with CentOS os
$ salt -G 'os:CentOS' test.ping
centos-rack1:
    True

With the use of glob -

$ salt -G 'os:cent*' test.ping
centos-rack1:
    True

We can observe that grain matching is case-insensitive and we can combine glob matching with it too. This is very useful in configuration management where we have a large number of machines with different operating systems.


That's all for the scope of this tutorial, stay tuned for more interesting ones.

0 comments:

Post a Comment