How do I pass parameters to a salt state file?
Question:
I want to create a group and user using salt state files, but I do not know the group, gid, user, uid, sshkey until I need to execute the salt state file which I would like to pass in as parameters.
I have read about Pillar to create the variable. How do I create pillars before execution?
/srv/salt/group.sls
:
{{ name }}:
group.present:
- gid: {{ gid }}
- system: True
Command line:
salt 'SaltStack-01' state.sls group name=awesome gid=123456
Answers:
You use Pillars to create “dictionaries” that you can reference into State files. I’m not sure if I’m understanding you correctly, but here’s an example of what you can do:
-
mkdir /srv/pillar/
-
Create /srv/pillar/groups.sls
and paste something like this into it:
groups:
first: 1234
second: 5678
These are names and GIDs of the groups you want to create.
-
Create /srv/pillar/top.sls
so you can apply this pillar to your minions. This is very similar to a salt top file, so you can either apply it to all minions ('*'
) or just the one ('SaltStack-01'
):
base:
'hc01*':
- groups
To test that that has worked, you can run salt '*' pillar.items
and you should find the groups
pillar somewhere in the output.
-
Now, your /srv/salt/group.sls
file should look like this:
{% for group,gid in pillar.get('groups',{}).items() %}
{{ group }}:
group.present:
- gid: {{ gid }}
{% endfor %}
This is a for loop: for
every group
and gid
in the pillar groups
, do the rest. So basically, you can look at it as if the state file is running twice:
first:
group.present:
- gid: 1234
And then:
second:
group.present:
- gid: 5678
This was incorporated from this guide.
If you really want to pass in the data on the command like you can also do it like this:
{{ pillar['name'] }}:
group.present:
- gid: {{ pillar['gid'] }}
- system: True
Then on the command line you can pass in the data like this:
salt 'SaltStack-01' state.sls group pillar='{"name": "awesome", "gid": "123456"}'
Another nice way to pass (incase you don’t want to use pillars Nor create a file as other answers shows) – you can pass a local environment variable to salt and read it from within the sls file, like this:
Command:
MYVAR=world salt 'SaltStack-01' state.sls somesalt # Note the env variable passed at the beginning
sls file:
# /srv/salt/somesalt.sls
foo:
cmd.run:
- name: |
echo "hello {{ salt['environ.get']('MYVAR') }}"
Will print to stdout:
hello world
Another good thing to know is that the env variable also gets passed on to any included salt states as well.
I want to create a group and user using salt state files, but I do not know the group, gid, user, uid, sshkey until I need to execute the salt state file which I would like to pass in as parameters.
I have read about Pillar to create the variable. How do I create pillars before execution?
/srv/salt/group.sls
:
{{ name }}:
group.present:
- gid: {{ gid }}
- system: True
Command line:
salt 'SaltStack-01' state.sls group name=awesome gid=123456
You use Pillars to create “dictionaries” that you can reference into State files. I’m not sure if I’m understanding you correctly, but here’s an example of what you can do:
-
mkdir /srv/pillar/
-
Create
/srv/pillar/groups.sls
and paste something like this into it:groups: first: 1234 second: 5678
These are names and GIDs of the groups you want to create.
-
Create
/srv/pillar/top.sls
so you can apply this pillar to your minions. This is very similar to a salt top file, so you can either apply it to all minions ('*'
) or just the one ('SaltStack-01'
):base: 'hc01*': - groups
To test that that has worked, you can run
salt '*' pillar.items
and you should find thegroups
pillar somewhere in the output. -
Now, your
/srv/salt/group.sls
file should look like this:{% for group,gid in pillar.get('groups',{}).items() %} {{ group }}: group.present: - gid: {{ gid }} {% endfor %}
This is a for loop:
for
everygroup
andgid
in the pillargroups
, do the rest. So basically, you can look at it as if the state file is running twice:first: group.present: - gid: 1234
And then:
second: group.present: - gid: 5678
This was incorporated from this guide.
If you really want to pass in the data on the command like you can also do it like this:
{{ pillar['name'] }}:
group.present:
- gid: {{ pillar['gid'] }}
- system: True
Then on the command line you can pass in the data like this:
salt 'SaltStack-01' state.sls group pillar='{"name": "awesome", "gid": "123456"}'
Another nice way to pass (incase you don’t want to use pillars Nor create a file as other answers shows) – you can pass a local environment variable to salt and read it from within the sls file, like this:
Command:
MYVAR=world salt 'SaltStack-01' state.sls somesalt # Note the env variable passed at the beginning
sls file:
# /srv/salt/somesalt.sls
foo:
cmd.run:
- name: |
echo "hello {{ salt['environ.get']('MYVAR') }}"
Will print to stdout:
hello world
Another good thing to know is that the env variable also gets passed on to any included salt states as well.