34

In the Salt system there are grains and pillars. I understand how I can assign custom grains, but when would it be better to consider using pillars?

Simon A. Eugster
  • 4,114
  • 4
  • 36
  • 31
Jeff Bauer
  • 13,890
  • 9
  • 51
  • 73
  • Also, pillar can be targeted to particular minions, just as you can target states to specific minions. – lexual May 21 '13 at 06:03

4 Answers4

30

In Salt, grains are used for immutable aspects of your minion, such as the cpu, memory, location, time zone, etc.

A pillar is a list of data on the master (in SLS format) that you need to distribute to your minions. Pillar allows you to set variables that the minions can access, for example a database configuration option.

Jeff Bauer
  • 13,890
  • 9
  • 51
  • 73
  • 14
    Importantly: Pillar data is stored on the master and cached on matching minions. Grains are stored on minions and cached on the master. Which is a bit counter intuitive but handy. Pillar data is only available to matching minions, all grains data is available to all minions. – Dan Garthwaite Feb 12 '14 at 00:57
  • @DanGarthwaite would you mind explaining how a minion can request all grains data? – brodie31k Sep 09 '15 at 00:00
  • @brodie31k you want to say that a minion can not get data from another minion grains ? – vskubriev Sep 04 '19 at 06:27
19

In short, custom static Grains is likely worse alternative than Pillars.

| Differences                  | Grains                        | Pillars                             |
|------------------------------|-------------------------------|-------------------------------------|
| This is info which...        | ... Minion knows about itself | ... Minion asks Master about        |
|                              |                               |                                     |
| Distributed:                 | Yes (different per minion)    | No (single version per master)      |
| Centralized:                 | No                            | Yes                                 |
|                              |                               |                                     |
| Computed automatically:      | Yes (preset/computed value)   | No (only rendered from Jinja/YAML)  |
| Assigned manually:           | No (too elaborate)            | Yes (Jinja/YAML sources)            |
|                              |                               |                                     |
| Conceptually intrinsic to... | ... individual Minion node    | ... entire system managed by Master |
| Data under revision control: | No (computed values)          | Yes (Jinja/YAML sources)            |
|                              |                               |                                     |
| They define rather...        | _provided_ resources          | _required_ resources                |
|                              | (e.g. minion OS version)      | (e.g. packages to install)          |
|                              |                               |                                     |
uvsmtid
  • 4,187
  • 4
  • 38
  • 64
16

The fundamental difference here is that you can set a custom grain as an innate property of a minion, versus pillar which needs to be assigned to a minion at some point.

For example, there are two practical ways to assign a role to a minion: the minion id or using custom grains. You can then match against the minion id or custom grains inside your top.sls file like so:

# salt/top.sls
base:
  # match against custom grain
  'G@role:webserver':
    - match: compound
    - webserver
  'G@role:search':
    - match: compound
    - elasticsearch
  # match against minion id
  'minion_db*':
    - database

You CANNOT do this with pillar. While you can indeed target with pillar, you first need a way to assign pillar to to your minions (this must be minion id, or grains as stated above). Think about how you would assign pillar in the pillar top file, you need to assign this pillar data using an innate attribute of the minion.

# pillar/top.sls
base:
  'G@env:dev':
    - match: compound
    - dev_settings
  'G@env:prod':
    - match: compound
    - prod_settings

The pattern here is that you use grains (or minion id) as a minimal way to set type/role/environment of your minion. After that, you use pillar data to feed it all the appropriate detailed settings.

mkobit
  • 43,979
  • 12
  • 156
  • 150
akoumjian
  • 1,594
  • 1
  • 15
  • 20
  • 1
    slight correction to the answer above. ```match: pillar``` **is possible now** as per this [salt doc](http://docs.saltstack.com/en/latest/ref/states/top.html#other-ways-of-targeting-minions) – Mayur Rokade Dec 28 '14 at 17:26
  • 1
    Note that for security reasons you shouldn't use grains to target sensitive pillar files (e.g. ones containing database passwords). Grains are set minion-side, and someone who's rooted a minion can change its grains such that it receives other minions' pillar data. – Andrew Jul 21 '15 at 01:15
  • 1
    Since pillars are set master-side, then if you wanted to distribute sensitive data based on some sort of roles, wouldn't you want those roles to be defined a pillar? – Andrew Farrell Jan 26 '16 at 03:28
  • 1
    There are definitely security concerns, as this model trusts all minions equally. Again though, you cannot use pillar to distinguish your different minions. It has to be based on something else. Even with `match: pillar`, well, how did those pillars get assigned to minions? They have to be assigned either by minion name, hostname, or grains. – akoumjian Jan 26 '16 at 15:59
  • I think that leaves targeting by minion name/ID the only "secure" path. Hostnames and grains (maybe IP addresses too, depending on the network security) can be manipulated on compromised minions, but the minion ID is locked when the key is accepted by the master, so compromising a single minion would only reveal sensitive information known by that minion. – kbolino May 24 '18 at 18:51
4

Pillar is also useful for ensuring that only certain minions get a particular bit of information.

There are some great docs here:

http://docs.saltstack.com/topics/pillar/index.html

and here:

http://docs.saltstack.com/topics/tutorials/pillar.html

You can also use an External Pillar to allow an arbitrary database or config file to set your Pillar data for you. This allows for very powerful integration with other aspects of your infrastructure. There are several built in external pillars listed here:

http://docs.saltstack.com/ref/pillar/all/index.html

And it's pretty straightforward to build a custom external pillar:

http://docs.saltstack.com/topics/development/external_pillars.html

Utah_Dave
  • 4,531
  • 24
  • 23
  • 1
    Doesn't really answer the question. Jeff Bauer - consider changing the accepted answer to akoumjian's instead. – Johntron Aug 11 '13 at 19:44