14

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
Alaa Ali
  • 896
  • 1
  • 12
  • 24
Ryan Currah
  • 1,067
  • 6
  • 15
  • 30

4 Answers4

24

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"}'
Josh Correia
  • 3,807
  • 3
  • 33
  • 50
Utah_Dave
  • 4,531
  • 24
  • 23
  • 1
    This is the answer I was looking for when I asked the question all those years ago. The accepted answer is probably best practice tho. Thanks Dave! – Ryan Currah Jul 12 '17 at 13:46
6

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:

  1. mkdir /srv/pillar/

  2. 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.

  3. 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.

  4. 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.

John Hazen
  • 1,296
  • 1
  • 8
  • 19
Alaa Ali
  • 896
  • 1
  • 12
  • 24
5

if you do not want use Pillar
you can do as:

# /srv/salt/params.yaml

name: awesome
gid: 123456

and then:

# /srv/salt/groups.sls

{% import_yaml "params.yaml" as params %}

{{ params['name'] }}:
  group.present:
    - gid: {{ params['gid'] }}
    - system: True

more details:doc

sshow
  • 8,820
  • 4
  • 51
  • 82
Hohenheim
  • 535
  • 6
  • 7
1

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.

Mercury
  • 7,430
  • 3
  • 42
  • 54