11

I have two ssh keys that I'm trying to deploy to one of my minions. But I can't seem to get it to deploy. It errors out. Here is the init.sls in pillars:

/xxx/yyy/zzz/id_rsa:
  file.managed:
    - source: salt://private/id_rsa

/xxx/yyy/zz/id_rsa.pub:
  file.managed:
    - source: salt://private/id_rsa.pub

Here is my init.sls state:

ssh:
  file.managed:
    - name: {{ pillar['private'] }}

I must be doing something wrong (obviously), but I'm not sure what. Any suggestions?

Roald Nefs
  • 426
  • 5
  • 13
secure212
  • 228
  • 1
  • 3
  • 10
  • I'd like to help, but I can't answer with the information provided. Part of the reason is the yaml formatting. Edit your question but leave a blank link above and below each codeblock, then indent each line in the codeblock by at least 4 spaces. Second, did you already succeed in doing this without pillars in the equation? I've never seen pillar data set up they way you have it. – Dan Garthwaite Oct 23 '13 at 18:52
  • Did you find an answer to your question? – Dan Garthwaite Nov 06 '13 at 23:48
  • Yes, I believe I did – secure212 Nov 07 '13 at 19:00

2 Answers2

15

The Salt Pillar system does not have an init.sls file. Both states and pillars has a top.sls file. States that are subdirectories may have an init.sls file.

Step 1: Define your users in /srv/pillar/users.sls

users:

  - name: fred
    fullname: Fred Flintstone
    email: fflintstone@slaterockandgravel.com
    uid: 4001
    gid: 4001
    shell: /bin/bash
    groups:
      - bowling
    shadow: $6$Sasdf/Ss$asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfsadfasdfsadfsadfsdf
    authkey: ssh-dss AAAAasdfasdfsadfsadfsadfsadfasdfasdfsdafsdafaasdfasdfasdfasdfasdfsadfsadfsadfsadfasdfasdfsdafsdafaasdfasdfasdfasdfasdfsadfsadfsadfsadfasdfasdfsdafsdafaasdfasdfasdfasdfasdfsadfsadfsadfsadfasdfasdfsdafsdafa = fflinstone@slaterockandgravel.com
    sshpub: ssh-dss AAAAasdfasdfsadfsadfsadfsadfasdfasdfsdafsdafaasdfasdfasdfasdfasdfsadfsadfsadfsadfasdfasdfsdafsdafaasdfasdfasdfasdfasdfsadfsadfsadfsadfasdfasdfsdafsdafaasdfasdfasdfasdfasdfsadfsadfsadfsadfasdfasdfsdafsdafa = fflinstone@slaterockandgravel.com

  - name: barney
    fullname: Barney Rubble
    email: brubbel@slaterockandgravel.com
    uid: 4002
    gid: 4002
    shell: /bin/bash
    groups:
      - bowling
    shadow: $6$Suiop/Ss$uiopuiopuiopuiopuiopuiopuiopuiopuiopuiopuiopsadfuiopsadfsadfsdf
    authkey: ssh-dss AAAAuiopuiopsadfsadfsadfsadfuiopuiopsdafsdafauiopuiopuiopuiopuiopsadfsadfsadfsadfuiopuiopsdafsdafauiopuiopuiopuiopuiopsadfsadfsadfsadfuiopuiopsdafsdafauiopuiopuiopuiopuiopsadfsadfsadfsadfuiopuiopsdafsdafa = fflinstone@slaterockandgravel.com
    sshpub: ssh-dss AAAAuiopuiopsadfsadfsadfsadfuiopuiopsdafsdafauiopuiopuiopuiopuiopsadfsadfsadfsadfuiopuiopsdafsdafauiopuiopuiopuiopuiopsadfsadfsadfsadfuiopuiopsdafsdafauiopuiopuiopuiopuiopsadfsadfsadfsadfuiopuiopsdafsdafa = fflinstone@slaterockandgravel.com

Step 2: Add the new pillar to /srv/pillar/top.sls

base:
  'testminion':
    - users

Step 3: Use jinja to map pillar to states in /srv/salt/user/init.sls

{% for user in pillar['users'] %}
user_{{user.name}}:
  group.present:
    - name: {{user.name}}
    - gid: {{user.gid}}

  user.present:
    - name: {{user.name}}
    - fullname: {{user.fullname}}
    - password: {{user.shadow}}
    - shell: {{user.shell}}
    - uid: {{user.uid}}
    - gid: {{user.gid}}
    {% if user.groups %}
    - optional_groups:
      {% for group in user.groups %}
      - {{group}}
      {% endfor %}
    {% endif %}
    - require:
      - group: user_{{user.name}}

  file.directory:
    - name: /home/{{user.name}}
    - user: {{user.name}}
    - group: {{user.name}}
    - mode: 0751
    - makedirs: True

user_{{user.name}}_forward:
  file.append:
    - name: /home/{{user.name}}/.forward
    - text: {{user.email}}

user_{{user.name}}_sshdir:
  file.directory:
    - name: /home/{{user.name}}/.ssh
    - user: {{user.name}}
    - group: {{user.name}}
    - mode: 0700

{% if 'authkey' in user %}
user_{{user.name}}_authkeys:
  ssh_auth.present:
    - user: {{user.name}}
    - name: {{user.authkey}}
{% endif %}

{% if 'sshpriv' in user %}
user_{{user.name}}_sshpriv:
  file.managed:
    - name: /home/{{user.name}}/.ssh/id_rsa
    - user: {{user.name}}
    - group: {{user.name}}
    - mode: 0600
    - contents_pillar: {{user.sshpriv}}
{% endif %}

{% if 'sshpub' in user %}
user_{{user.name}}_sshpub:
  file.managed:
    - name: /home/{{user.name}}/.ssh/id_rsa.pub
    - user: {{user.name}}
    - group: {{user.name}}
    - mode: 0600
    - contents_pillar: {{user.sshpub}}
{% endif %}
{% endfor %} # user in users
# vim: ft=yaml tabstop=2 sts=2 sw=2 et ai si

Don't forget to sync the minions with the new pillars!

salt targetminions saltutil.refresh_pillar
Dan Garthwaite
  • 2,922
  • 18
  • 29
  • I was unable to get this example to work on Salt 2014.7.1; it appears to give an error: "Jinja variable 'str object' has no attribute 'name'" . I have resorted to doing something like this in the user/init.sls: `{% for user, data in salt['pillar.get']('users', {}).iteritems() %}` This will significantly change the sls file throughout; if I come up with a working example I will post it. – Mike S Apr 14 '15 at 17:50
  • Followup: If you, dear Traveller, are looking to utilize this code, I believe it has a number of errors in it. For example, the colons after "fred" and "barney" will cause salt to barf, as will the "end for" and "end if" (they should not have spaces in there). Again I suspect that the initial for construct is faulty but I don't know much about salt at this time so I can't be sure. Caveat Programmer. For myself, I'm going to work with the iteritems() concept. – Mike S Apr 14 '15 at 18:31
  • Sorry, Dan, I still get testminion: Data failed to compile: ---------- Rendering SLS 'base:users' failed: Jinja variable 'str object' has no attribute 'name' when I run: salt testminion state.highstate test=True ....I have copied your text verbatim, above. The only addition was my /srv/salt/top.sls file which is a simple 3-liner (base:, '*':, and -users). – Mike S Apr 14 '15 at 18:58
  • I'll spin up a docker container and sort it out, unless you get to it first? – Dan Garthwaite Apr 14 '15 at 19:11
  • The "Data failed to compile" was caused by the '.sls' filename suffix in /srv/pillar/top.sls. Than I also ran into problems. Please note, I've rewritten much of it. I had to drop user.sshpriv for now, it is just getting late and I keep getting in trouble with --- in the text content. – Dan Garthwaite Apr 15 '15 at 03:19
  • I've really cleaned this up. The state file could use a lot of defaults either via jinja filters: `{{user.blah | default('not specified') }}` or via `{{user.get('blah', 'not specified')}}`. I would really appreciate it if you give it a try, @MikeS – Dan Garthwaite Apr 15 '15 at 03:29
  • Sorry it took me so long to get back to this @Dan Garthwaite. It looks pretty good! I didn't have a `groups` entry on my test user so Jinja complained; I'm not sure why because you have an `if user.groups` statement. But basically it works. Perhaps you should include a Step 4: Add the following to your top.sls: `- user`. – Mike S May 20 '15 at 16:19
  • The contents_pillar lines should be referencing a pillar, but the users example has the content in it, ie sshpub has its value instead of the pillar. – rtaft Nov 17 '16 at 20:13
1

It should probably be noted that in relation to the original question, there's another simple solution if source: salt://... format doesn't work with file.managed - as it still happened with salt-ssh because of bug https://github.com/saltstack/salt/issues/38458 that was since fixed - and that is to switch to contents: with the file tree external pillar, which is also backed by files on the master.

The file_tree ext_pillar is documented at https://docs.saltstack.com/en/latest/ref/pillar/all/salt.pillar.file_tree.html#module-salt.pillar.file_tree nowadays. It has existed since version 2015.5.0 so it's newer than the original question and answer, yet it is a solution that is reasonably well available today.

Indeed, it is also in the FAQ at https://docs.saltstack.com/en/latest/faq.html#is-it-possible-to-deploy-a-file-to-a-specific-minion-without-other-minions-having-access-to-it

Josip Rodin
  • 1,575
  • 11
  • 17