# User management by ansible - any ideas ?

**URL:** <https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919>\
**Category:** Ansible Project\
**Created:** [August 12, 2014, 9:25am UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919 "2014-08-12T09:25:06Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![P11](https://avatars.discourse-cdn.com/v4/letter/p/a9adbd/32.png) [@P11](https://forum.ansible.com/u/P11)\
**Post date:** [August 12, 2014, 9:25am UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/1 "2014-08-12T09:25:06Z")

</div>

I would like to use ansible for our user management (I know there are software for it like LDAP but not for now …).  
This is typical definition of users and their groups:

Groups and users:

- group1

- user1

- user2

- group2

- user1

- user2

- user3

- group3

- user1

- user2

- user3

- user4

The problem I have is that every server is going to have subset of all groups, i.e:

- server1
- group1
- group3- server2
- group3- server3
- group1

Then there is a request from business/developers/managers/whatever that particular group of users should have access to particular servers so we need to modify ansible config and add e.g. group3 to server3.

Is it possible to create a role with a sort of “map” file where I could specify which server will have particular user groups  
so we could modify this one (!) file, run site.yml and done (the role and its file knows where to create each group).

I would like to avoid redundancy in terms of user definitions (error prone) and have just one file with all users defined in it.

That way I could include this role in every playbook and it would automatically create (or not) particular group of users  
on every host.  
Is it possible to do that ?

---

<div class="post-metadata">

**Author:** ![Dick\_Davies](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@Dick\_Davies](https://forum.ansible.com/u/Dick_Davies)\
**Post date:** [August 12, 2014, 10:16am UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/2 "2014-08-12T10:16:08Z")

</div>

You can parameterise roles, maybe that would help.  
([http://docs.ansible.com/playbooks\_roles.html](http://docs.ansible.com/playbooks_roles.html) )

Define all the group memberships in your accounts role  
(accounts/defaults/main.yml)  
and then in your inventory, load the accounts role into specific hosts  
with a list  
of the groups you want defined.

---

<div class="post-metadata">

**Author:** ![P11](https://avatars.discourse-cdn.com/v4/letter/p/a9adbd/32.png) [@P11](https://forum.ansible.com/u/P11)\
**Post date:** [August 13, 2014, 8:08am UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/3 "2014-08-13T08:08:36Z")

</div>

While reading this URL I came across the following example:

```auto

- hosts: webservers
  roles:
    - common
    - { role: foo_app_instance, dir: '/opt/a', port: 5000 }
    - { role: foo_app_instance, dir: '/opt/b', port: 5001 }

```

Can anyone show me how would the “foo\_app\_instance” role look like ?

---

<div class="post-metadata">

**Author:** ![Rodney\_Quillo](https://avatars.discourse-cdn.com/v4/letter/r/7ba0ec/32.png) [@Rodney\_Quillo](https://forum.ansible.com/u/Rodney_Quillo)\
**Post date:** [August 13, 2014, 8:37am UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/4 "2014-08-13T08:37:28Z")

</div>

I’m using this user role, [https://github.com/mivok/ansible-users](https://github.com/mivok/ansible-users)  
Maybe you can take a look at this too.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 13, 2014, 1:17pm UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/5 "2014-08-13T13:17:09Z")

</div>

Basically it could be anything, it would just be able to use variables like {{ port }} in the playbooks or Jinja2 templates.

---

<div class="post-metadata">

**Author:** ![Alex\_Wheeler](https://avatars.discourse-cdn.com/v4/letter/a/5e9695/32.png) [@Alex\_Wheeler](https://forum.ansible.com/u/Alex_Wheeler)\
**Post date:** [August 13, 2014, 2:51pm UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/6 "2014-08-13T14:51:46Z")

</div>

Here’s how I solved this problem for myself: [https://gist.github.com/awheeler/a3e4c500f1bb70bd31dd](https://gist.github.com/awheeler/a3e4c500f1bb70bd31dd)  
You can define groups that users should be members of with a host specification that is a regex, so:

> users: devdomain.net$

would say that the user should be in the users group on all hosts with ansible\_fqdn that end with [devdomain.net](http://devdomain.net).  
You can get just as complex as you want:

> wheel: ((host1|differenthost2|cluster\_nodes[0123])-[0-9]+.proddomain.com|devdomain.net|another.devhost.dev)$

The thing that makes this possible is the fact that you can embed complex jinja2 in the middle of an Ansible task, a fact which is not immediately apparent.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 14, 2014, 11:39am UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/7 "2014-08-14T11:39:23Z")

</div>

Here’s an easier way that avoids the messy Jinja2 in the playbook, which we as a community like to discourage (it’s the reason Ansible templates don’t evaluate into YAML, but are YAML… Jinja2 is intended to be just a quick way to get variables, unless you are in a template)

In ansible, a host specification that is a regex starts with “~”

# hosts endsing in devdomain or qadomain:

hosts: “~([devdomain.net](http://devdomain.net)|[qadomain.net](http://qadomain.net))$”

Thus you can have multiple plays in the playbook

- hosts: all  
roles:

- foo

- hosts: “~([devdomain.net](http://devdomain.net)|[qadomain.net](http://qadomain.net))$”  
roles:

- setup\_my\_users

- hosts: all  
tasks:

- 
# more steps here

Etc

---

<div class="post-metadata">

**Author:** ![Alex\_Wheeler](https://avatars.discourse-cdn.com/v4/letter/a/5e9695/32.png) [@Alex\_Wheeler](https://forum.ansible.com/u/Alex_Wheeler)\
**Post date:** [August 14, 2014, 2:34pm UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/8 "2014-08-14T14:34:34Z")

</div>

I think I get where you are going with the idea of different plays, but they way I understand it, I would need a different play for every user that had different host/group requirements.  
So, with 100+ users, 70 might need the same access for a given set of hosts (1 play), but there could be 30 that have unique requirements. So, that means 31 plays, and probably logging into some of the servers in question 31 times.  
Ugh! I am not a huge fan of my creation (it’s not clean and elegant, though the line-breaks make it better), other than the fact it is very flexible, and reasonably efficient. I would love to be able to convert it to something more consistent with what the community recommends, but I don’t see how to do it without possibly creating a different play for every user.

With my solution, every host is only accessed once, and each user can have a different host regex for each group, and the full definition of what permissions a user has is all in once place.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 16, 2014, 2:26pm UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/9 "2014-08-16T14:26:55Z")

</div>

“I think I get where you are going with the idea of different plays, but they way I understand it, I would need a different play for every user that had different host/group requirements.”

Definitely not.

This is where useful things like “with\_items” come in, and you can do

“with\_items: myusers”.

Thus you can still keep one play that uses a variable to source the list of users, and that variable can come from things like group\_vars.

---

<div class="post-metadata">

**Author:** ![P11](https://avatars.discourse-cdn.com/v4/letter/p/a9adbd/32.png) [@P11](https://forum.ansible.com/u/P11)\
**Post date:** [August 20, 2014, 2:43pm UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/10 "2014-08-20T14:43:15Z")

</div>

The problem with this approach is that it requires the servers name to be similar (regex).  
In our case the servers name could be totally different so it won’t work (perhaps …)

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 20, 2014, 4:33pm UTC](https://forum.ansible.com/t/user-management-by-ansible-any-ideas/15919/11 "2014-08-20T16:33:28Z")

</div>

“The problem with this approach is that it requires the servers name to be similar (regex).”

You should use groups. We recommend this in nearly all cases, hardly anyone is using host patterns matched by regex.

If using cloud services, tags also automatically form groups, which is highly useful, as servers can self-declare what groups they are in.
