7

In Saltstack, I have the following use case:

There is a state redis.sls which can be included by other states. The result of redis.sls should be configured differently, depending on the state which included redis.sls.

For example:

redis.sls:
--------
{% if x==1 %}
   #do something
{% else %}
   #do something else
{% endif %}


state_a.sls
-----------
{% set x=1 %}
include:
  - redis

state_b.sls
-----------
{% set x=2 %}
include:
  - redis

But x is not recognized in *state_a* and *state_b*

I also tried setting a pillar value with something like this:

{{salt['pillar.set']('x', 1)}}

but that didn't work either.

Any other ideas?

pcurry
  • 1,374
  • 11
  • 23
lev
  • 3,986
  • 4
  • 33
  • 46
  • It seems like you are trying to parameterize states in a way that they currently aren't designed to be parameterized. What are you trying to accomplish with this? – pcurry Apr 03 '14 at 00:42
  • I have almost the same [question](http://stackoverflow.com/questions/38904308/passing-variables-with-include-in-salt-stack). For example we have redis-master and redis-replication. This states are almost the same and question is how to avoid code duplication. – Raz Aug 12 '16 at 07:59

4 Answers4

1

I'd like to hear what the experts say but I have a similar use case. What I did was use the jinja template to extend a base template then my child templates populated the variables.

{% extends "base.template.sls" %}
{% block x %}1{% endblock %}

Only problem might be that you now have to call state_a and state_b separately but you can always put them in a comma separated list if you want both called.

Jim K
  • 111
  • 5
1

Make your redis state a jinja macro.

redis.sls:
--------
{% macro redis(x) %}
{% if x==1 %}
   #do something
{% else %}
   #do something else
{% endif %}
{% endmacro %}


state_a.sls
-----------
{% from 'redis.sls' import redis  %}
{{ redis(1) }}


state_b.sls
-----------
{% from 'redis.sls' import redis  %}
{{ redis(2) }}

For clarity redis.sls should be renamed to redis.jinja here.

This, and many other ways of managing state customization is best explained in the Salt Formulas conventions guide. Specifically the part about Jinja macros

Note that your if x==1 logic can be probably avoided altogether, take a look at the 'better' version of haproxy example in the guide.

kert
  • 2,161
  • 21
  • 22
0

It looks like you want to parameterize a state based on either what depends on it, or where it is used. That sounds like whatever is setting the parameter(s) on which the redis.sls state is supposed to mutate, depends on a specific configuration of redis.

To me, that seems like there are more than one distinct states in which redis could be, and that some of your states depend on one state of redis, and others of your states depend on other states of redis.

So, give the installation of redis one state, and the specific configurations of redis would each get their own state. Your state_a could depend on redis_state_1 and your state_b would in turn depend on redis_state_2. Both redis_state_1 and redis_state_2 would depend on redis. It seems to me that the parameter passing you're asking about would be less explicit.

pcurry
  • 1,374
  • 11
  • 23
  • Could you please explain how to archive it? For example I want to install 2 different redis instances on one server. I can make **redis** state with **version** variable. But how to call it with different values? – Raz Aug 12 '16 at 08:18
  • @Raz It's been so long since I used salt that I'd have to revisit the documentation. I think that Ansible is winning the user share these days. – pcurry Jul 21 '17 at 15:28
-1

SALT.STATES.ENVIRON might work for you:

set_secret_key:
  environ.setenv:
    - name: SECRET_KEY
    - value: ABC123!@#abc
    - update_minion: True

[..]

settings_secret_key:
  file.replace:
    - name: {{ salt['pillar.get']('data:source_folder') }}superlists/settings.py
    - pattern: "SECRET_KEY =.+$"
    - repl: 'SECRET_KEY = os.environ["SECRET_KEY"]'
scthi
  • 2,205
  • 1
  • 18
  • 14