# Create different sets of users on different sets of hosts

**URL:** <https://forum.ansible.com/t/create-different-sets-of-users-on-different-sets-of-hosts/16615>\
**Category:** Ansible Project\
**Created:** [October 27, 2014, 2:55pm UTC](https://forum.ansible.com/t/create-different-sets-of-users-on-different-sets-of-hosts/16615 "2014-10-27T14:55:03Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Paul\_Slootman](https://avatars.discourse-cdn.com/v4/letter/p/e5b9ba/32.png) [@Paul\_Slootman](https://forum.ansible.com/u/Paul_Slootman)\
**Post date:** [October 27, 2014, 2:55pm UTC](https://forum.ansible.com/t/create-different-sets-of-users-on-different-sets-of-hosts/16615/1 "2014-10-27T14:55:03Z")

</div>

Hi,  
A new ansible user here… I’ve been perusing the mailing list archives and have gathered a lot of useful tidbits.

I’ve been fairly successful in figuring out how to create a set of users on a list of hosts. However, what I’m not so clear about is how to create different sets of users on different categories of hosts. We’re a software house that administrates the server farms at our customers. Let’s say we have 20 customers, and each customer can have 3-20 servers; these servers fall into different categories as well: application servers, database servers, test app. servers, test DB servers for example.

One set of users should be created on all systems always, namely our sysadmins.  
Another set of users should only be created on the database servers; likewise for the application servers.

The approach I’d find logical would be to write a playbook such as:

- hosts: all\_hosts

tasks:

- name: Add sysadmin users  
user: name={{ item.key }} password={{ item.value.password }} uid={{ item.value.uid }} group={{ item.value.group }} groups=“” comment=“{{ item.value.comment }}” state={{ item.value.state }} update\_password=always  
with\_dict: sysadmin\_user

- hosts: db\_hosts  
tasks:

- name: Add DBA users  
user: name={{ item.key }} password={{ item.value.password }} uid={{ item.value.uid }} group={{ item.value.group }} groups=“” comment=“{{ item.value.comment }}” state={{ item.value.state }} update\_password=always  
with\_dict: dba\_user

- hosts: application\_hosts  
tasks:

- name: Add application users  
user: name={{ item.key }} password={{ item.value.password }} uid={{ item.value.uid }} group={{ item.value.group }} groups=“” comment=“{{ item.value.comment }}” state={{ item.value.state }} update\_password=always  
with\_dict:appl\_user

This would work, but would entail listing all hosts at least twice: once for the “all\_hosts” list, and once for the specific type of host. I’d like to be able to compose the “all\_hosts” list automatically out of the other lists. I’ve tried a couple of ways after reading things in the mailing list archive that might be applicable, but haven’t had any success.

So, in short, my question really boils down to: Is it possible to merge existing host lists so that I don’t have to repeat hosts in different lists? The same question also applies to user lists, although I suspect that if it’s possible with host lists, the same method will work for user lists as well.

(Being able to merge host lists would mean it would be possible to define hosts in lists according to customer + type, and then build different host lists such as “all DB hosts” or “all hosts at customer XYZ”.)

Thanks!

---

<div class="post-metadata">

**Author:** ![mephage](https://avatars.discourse-cdn.com/v4/letter/m/e274bd/32.png) [@mephage](https://forum.ansible.com/u/mephage)\
**Post date:** [October 28, 2014, 10:07pm UTC](https://forum.ansible.com/t/create-different-sets-of-users-on-different-sets-of-hosts/16615/2 "2014-10-28T22:07:00Z")

</div>

Paul,

I recently encountered what I believe the be the same scenario. I googled around and couldn’t seem to find anything to fit the scenario so I used the following approach (probably re-inventing the wheel). The key is to make use of roles, playbooks and vars separately. I’ve adapted your example and truncated it for simplicity:

1. Create a role ‘groups\_users’ consisting of least ‘roles/groups\_users/tasks/main.yml’:

---

<div class="post-metadata">

**Author:** ![mephage](https://avatars.discourse-cdn.com/v4/letter/m/e274bd/32.png) [@mephage](https://forum.ansible.com/u/mephage)\
**Post date:** [October 30, 2014, 2:29am UTC](https://forum.ansible.com/t/create-different-sets-of-users-on-different-sets-of-hosts/16615/3 "2014-10-30T02:29:17Z")

</div>

Made an error (why aren’t google group posts editable? who knows…). Should read:

1. Create group\_vars files for each group:

‘group\_vars/myhosts’:

---

<div class="post-metadata">

**Author:** ![Paul\_Slootman](https://avatars.discourse-cdn.com/v4/letter/p/e5b9ba/32.png) [@Paul\_Slootman](https://forum.ansible.com/u/Paul_Slootman)\
**Post date:** [October 30, 2014, 8:41am UTC](https://forum.ansible.com/t/create-different-sets-of-users-on-different-sets-of-hosts/16615/4 "2014-10-30T08:41:48Z")

</div>

Thanks for your example, I’m just about understanding how it works 🙂 I did need to add a .yml extension to the external\_vars/groups\_users\_\* files but that was obvious from how the playbook referenced those file. Also the role needs “group:” and not “groups:” (the error message could have been a bit clearer…).

However, when I try this, the gathering facts works fine, then:

TASK: [groups\_users | Add groups] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
fatal: [host1] =\> with\_items expects a list or a set  
fatal: [host2] =\> with\_items expects a list or a set  
fatal: [host3] =\> with\_items expects a list or a set

FATAL: all hosts have already failed – aborting

This is the sort of thing that’s probably trivial to fix with some experience but I have no clue how to proceed now ☹

FWIW I’m running:  
ansible 1.8 (devel 44afa7facc) last updated 2014/10/27 14:31:42 (GMT +200)

---

<div class="post-metadata">

**Author:** ![Paul\_Slootman](https://avatars.discourse-cdn.com/v4/letter/p/e5b9ba/32.png) [@Paul\_Slootman](https://forum.ansible.com/u/Paul_Slootman)\
**Post date:** [October 30, 2014, 10:14am UTC](https://forum.ansible.com/t/create-different-sets-of-users-on-different-sets-of-hosts/16615/5 "2014-10-30T10:14:52Z")

</div>

Following up on myself:

If I change the roles/groups\_users/tasks/main.yml to this:

---

<div class="post-metadata">

**Author:** ![mephage](https://avatars.discourse-cdn.com/v4/letter/m/e274bd/32.png) [@mephage](https://forum.ansible.com/u/mephage)\
**Post date:** [November 3, 2014, 8:48pm UTC](https://forum.ansible.com/t/create-different-sets-of-users-on-different-sets-of-hosts/16615/6 "2014-11-03T20:48:06Z")

</div>

Hey Paul,

My apologies for the delayed reply.

I can’t see why you’re getting the result you are. But I did notice a few errors in the snippets I posted. Here’s a testing and working example:

[https://github.com/mephage/ansible-groups\_users\_example](https://github.com/mephage/ansible-groups_users_example)

---

<div class="post-metadata">

**Author:** ![Paul\_Slootman](https://avatars.discourse-cdn.com/v4/letter/p/e5b9ba/32.png) [@Paul\_Slootman](https://forum.ansible.com/u/Paul_Slootman)\
**Post date:** [November 11, 2014, 4:00pm UTC](https://forum.ansible.com/t/create-different-sets-of-users-on-different-sets-of-hosts/16615/7 "2014-11-11T16:00:04Z")

</div>

Also apologies, I was offline for a bit and then had other priorities at work.

I’ve downloaded your github example as a zip file, unpacked it, modified host and usernames to reflect the local situation.

I now don’t get an error, but now the tasks just show “skipping” for everything:

PLAY [Add sysadmins group and users] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

GATHERING FACTS \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [host2]  
ok: [host1]

TASK: [groups\_users | Add groups] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
skipping: [host1] =\> (item={‘state’: ‘present’, ‘gid’: 7575, ‘name’: ‘impulsys’})  
skipping: [host2] =\> (item={‘state’: ‘present’, ‘gid’: 7575, ‘name’: ‘impulsys’})

TASK: [groups\_users | Add users] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
skipping: [host1] =\> (item={‘comment’: ‘Paul Slootman 2’, ‘state’: ‘present’, ‘group’: ‘groupname’, ‘name’: ‘pslootman’, ‘password’: ‘$1$.xxxxxxxxxxxxxxxxxxxxxx’, ‘pubkey’: ‘ssh-rsa AAAA…’, ‘uid’: 54343})  
skipping: [host2] =\> (item={‘comment’: ‘Paul Slootman 2’, ‘state’: ‘present’, ‘group’: ‘groupname’, ‘name’: ‘pslootman’, ‘password’: ‘$1$.xxxxxxxxxxxxxxxxxxxxxx’, ‘pubkey’: ‘ssh-rsa AAAA…’, ‘uid’: 54343})

PLAY [Add db group and users] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

GATHERING FACTS \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [host1]  
ok: [host2]

TASK: [groups\_users | Add groups] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
skipping: [host1] =\> (item={‘state’: ‘present’, ‘gid’: 7576, ‘name’: ‘dbagroup’})  
skipping: [host2] =\> (item={‘state’: ‘present’, ‘gid’: 7576, ‘name’: ‘dbagroup’})

TASK: [groups\_users | Add users] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
skipping: [host1] =\> (item={‘comment’: ‘Nelson DBA’, ‘state’: ‘present’, ‘group’: ‘dbagroup’, ‘name’: ‘ndba’, ‘password’: ‘$1$.xxxxxxxxxxxxxxxxxxxxxx’, ‘pubkey’: None, ‘uid’: 54331})  
skipping: [host2] =\> (item={‘comment’: ‘Nelson DBA’, ‘state’: ‘present’, ‘group’: ‘dbagroup’, ‘name’: ‘ndba’, ‘password’: ‘$1$.xxxxxxxxxxxxxxxxxxxxxx’, ‘pubkey’: None, ‘uid’: 54331})

PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
host1 : ok=6 changed=0 unreachable=0 failed=0  
host2 : ok=6 changed=0 unreachable=0 failed=0

I’ve modified roles/groups\_users/tasks/main.yml to this:
