Struggling with user accounts

I’m still trying to wrap my head around ansible in general and I guess I just don’t understand its structure fully yet. The very first thing I’m attempting to do is to create some user accounts across a group of servers. We have a handful of sysadmins who manage a group of servers, so I figured I could so something along these lines to define how we want an account created:

tasks:
-name: Add user ${username}
action: command /bin/echo ${username}

  • name: Add/remove user ${username}
    action: user name=${username}
    comment=“${fullname}”
    uid=${uid}
    group=wheel
    shell=/bin/bash
    createhome=yes
    state=present

  • name: Add ssh key for ${username}

action: authorized_key user=${username} key=“$FILE(/ansible/conf/users/files/ssh-key.${username})”

  • name: Add user ${username} to nagios group on the util server only
    action: user name=${username}
    groups=nagios
    only_if: “‘$facter_hostname’== ‘util’”

But then for the life of me I can’t figure out how to apply this playbook for each of the sets of username/fullname/uid that I need to create accounts for. Is this a good way of doing this sort of thing or am I completely missing the boat?

-Bruce

This is what I have...

In an appropriate group_vars file:-
sysadmin_users:
  - username: fred
    fullname: Fred Flintston
    crypted_pass: '$6$the_rest_of_the_password_hash'
    ssh_pubkey: 'ssh-rsa ABCEF-ssh-key fred@localhost.localnet'

removed_sysadmin_users:
  - oldadmin
  - somone

Then in the tasks list (some bits have wrapped - sure you can work it out):-
- name: ensure ${item.username} has an account
  action: user name=${item.username} comment="${item.fullname}"
password=${item.crypted_pass} createhome=yes
  with_items: $sysadmin_users

- name: ensure ${item.username} has ssh keys
  action: authorized_key user=${item.username} key="name=${item.ssh_pubkey}"
  with_items: $sysadmin_users

- name: ensure old sysadmin accounts are removed
  action: user name=${item} state=absent remove=yes
  with_items: $removed_sysadmin_users

- name: Build sudo config file
  action: template src=templates/sudo/sudoers.j2
dest=/etc/sudoers.templated owner=root group=root mode=0440

- name: Move sudo config file into place
  action: command /usr/bin/install --mode=0440 --owner=root --group=root
/etc/sudoers.templated /etc/sudoers
  only_if: '${last_result.changed}'

Nice Nigel!

I would probably recommend explicitly setting the variable name in the
"Build sudo config" step like:

register: sudo_result

...

only_if: ${sudo_result.changed}

just so that if you ever insert a step the 'last_result' won't throw you.

Thanks for posting this, I find it useful as well. I don't understand
why you have separate steps of building sudo and installing it though.
Why do you do that? Does it have something to do with ansible using
sudo and it could potentially mess up your ansible session?

Thanks,

Nigel,

removed_sysadmin_users:
  - oldadmin
  - somone

[...]

- name: ensure old sysadmin accounts are removed
  action: user name=${item} state=absent remove=yes
  with_items: $removed_sysadmin_users

Very nice!

sysadmin_users:
    fullname: Fred Flintston

You misspelled his surname. :wink:

        -JP

Would this work when splitting out this yaml list over more than one group file?

I was also wondering how register variables would work out when using with_items?

Serge

Romeo Theriault wrote:

Thanks for posting this, I find it useful as well. I don't understand
why you have separate steps of building sudo and installing it though.
Why do you do that? Does it have something to do with ansible using
sudo and it could potentially mess up your ansible session?

I believe the issue I was working around has been fixed in ansible now
(as in 0.9), but it has been the case that templating/copying a file
into place with ansible has been a two (or more) stage operation where
the file is put into place, and then (in a separate sudo invocation) the
file has its permissions set.
For sudoers this meant the permissions were wrong on the file at the
time of invocation of the permissions setting stage, which meant you
were locked out of the system - which is sorta embarrassing!
Hence templating it into a different file and then an atomic operation
to put it in place with the correct permissions.

Michael also picked up on my use of last_result in that stage - which no
longer works as written in 0.8. Unfortunately the copy in my laptop git
repo didn't have the most recent changes on it - but the only thing I
had done was add a 'register: last_result' to the template action, which
is the bare minimum to make it work.

The general rule of course is to be *very* careful when playing with
sudoers - and make sure you test the case where you actually update it
because it can be a nasty surprise when it goes pear shaped. Thankfully
I am only working on our dev network, but plans are well underway for a
slow roll out on production.

  Nigel.

Thanks so much! This is exactly the sort of thing I was looking for and gives me a much better understanding of the right way to work with ansible.

-Bruce