Search code examples
salt-project

SaltStack extending another pillar


I'm using SaltStack, and I'm trying to re-use the values of a nested dictionary from one Pillar config in another one. Here's a simple example of what I'm trying to do:

Say I have pillar/app/common.sls which has the following items:

app:
  lookup:
    custom1: 'change the default'
    custom2: 'change the default'
  service1:
    value1: 'foo'
    value2: 'bar'
    list1:
      - apple
      - banana
    value3: 'xen'

What I'm aiming for is to have a new service (and the YAML key would be service2) on the same machine, but set up in such a way so that I'm not writing values twice (keep it DRY!). I would also like to override the value of one of the parameters. Essentially, I'm trying to extend one pillar into another.

The end result would be:

app:
  lookup:
    custom1: 'change the default'
    custom2: 'change the default'
  service1:
    value1: 'foo'
    value2: 'bar'
    list1:
      - apple
      - banana
    value3: 'xen'
  service2:
    value1: 'foo'
    value2: 'bar'
    list1:
      - apple
      - banana
    value3: 'future'

I've tried the following with a pillar/app/someserver.sls:

{% import_yaml "app/common.sls" as common %}

app:
  service2:
    {{ common.app.service1 }}
    value3: 'future'

What I've found is {{ common.app.service1 }} successfully renders, but it doesn't like the additional value3: 'future', which is my attempt to override value3 which comes from common.sls.

I'm using Salt 2016.11.4 on Ubuntu Xenial 16.04.2. Any ideas would be helpful. Thank you!


Solution

  • Since your common.app.service1 variable is nothing more than a common Python dict, you should be able to modify it using update. After that, you can use Jinja's yaml filter to render it into the new pillar:

    {% import_yaml "app/common.sls" as common %}
    {% set service2 = common.app.service1.copy() %}
    {% do service2.update({value3: 'future'}) %}
    
    app:
      service2: {{ service2 | yaml }}