15

I see in the pillar documentation that there are two ways to reference pillar data in an SLS.

{{ pillar['foo'] }}

and

{{ salt['pillar.get']('foo') }}

The pillar.get method handles nested pillar data better and allows to specify a default if the data isn't found in the pillar. But it's a bit more typing and I find the first method easier to read.

So, is it considered best practice to always use the pillar.get method or is using the pillar['foo'] acceptable, especially when dealing with non-nested pillar data.

I suspect always using the pillar.get method is best since it make sense to use it when dealing with nested pillar data or you want to set a default. And it's best to just you one method consistently. But I wanted to get other people's thoughts.

tshepang
  • 12,111
  • 21
  • 91
  • 136
NimbusScale
  • 428
  • 1
  • 5
  • 14

5 Answers5

15

I use pillar['foo'] for "required" options, as Utah_Dave suggests. I use salt['pillar.get']('foo', 'default') for options that have a sane default. There are a couple other variations that are interesting.

One is salt['defaults.get']('foo'), which allows you to keep your state's default values in a separate file. Very useful if you have a lot of possible pillar variables, most or all of which have default values. (NOTE: the behavior of defaults.get has changed since I wrote this, see this answer for other options)

A second is that it is possible to alias salt['pillar.get'] (and other functions of the same sort) so that they are less of a nuisance to type and read:

{%- set pget = salt['pillar.get'] %}
{%- set dget = salt['defaults.get'] %}
{%- set mget = salt['mine.get'] %}
{{ pget("foo1", "default1") }}
{{ pget("foo2", "default2") }}
{{ dget("foo3") }}
{{ dget("foo4") }}
...and so on.

That last variation in particular (dget) works wonders for readability in heavily-customizable states.

Andrew
  • 4,058
  • 4
  • 25
  • 37
9

I agree that the shorter syntax looks nicer.

In states that I build, I tend to use the {{ pillar['foo'] }} syntax when I'm referencing a value that ABSOLUTELY must be there for my state to work correctly. In that case, I do want a failure to happen.

Then with other values where I need to traverse nested data, or if I want to use a default value, I use the longer syntax.

In the end, it's mostly personal preference. None of them is more correct than another.

Utah_Dave
  • 4,531
  • 24
  • 23
1

The reason you'd want to use pillar.get is because you can specify a default in-case the pillar fails to obtain anything.

salt['pillar.get']('element', 'default')
Vasili Syrakis
  • 9,321
  • 1
  • 39
  • 56
1

You can simply do {{ pillar.foo }}.

And for default values, {{ pillar.foo|default('your default') }}.

Dorian Marchal
  • 634
  • 1
  • 9
  • 14
  • Is it smart to use dot notation in Salt? I found this issue: https://stackoverflow.com/questions/29703154/difference-between-dot-notation-and-square-brackets-in-flask-templates - I know nothing about it... – TheStoryCoder Jun 20 '22 at 08:24
0

You can also specify a default with the first variation:

{{ pillar['foo'] | default('bar') }}