# Multiple clients and multiple sub groups

**URL:** <https://forum.ansible.com/t/multiple-clients-and-multiple-sub-groups/2496>\
**Category:** Get Help\
**Tags:** playbook, documentation, inventory\
**Created:** [November 21, 2023, 7:22pm UTC](https://forum.ansible.com/t/multiple-clients-and-multiple-sub-groups/2496 "2023-11-21T19:22:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Amit.z](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/amit.z/32/3375_2.png) [@Amit.z](https://forum.ansible.com/u/Amit.z)\
**Post date:** [November 21, 2023, 7:22pm UTC](https://forum.ansible.com/t/multiple-clients-and-multiple-sub-groups/2496/1 "2023-11-21T19:22:52Z")

</div>

Hi, I would appreciate it if someone could direct me to the appropriate documentation or give me a tip.

The company I work for manages hundreds of sites for hundreds of clients. For some of them we use Ansible.  
I want to take it to the next level!

I am looking for the most efficient way to do the following: a client named jack has 2 db servers, 2 web servers and 1 stg server.

I would build the inventory file like this:  
[jack]  
db1  
db2  
web1  
web2  
stg1

[jack-db]  
db1  
db2

[jack-web]  
web1  
web2

[jack-stg]  
stg1

This way, I can run a different play-book for each sub group, and also a playbook for the whole main group. (jack)  
Now lets say that I have the same structure for the rest of the clients.

I am looking for a way to run a play-book for all the db servers for all of our clients for example.  
Or all the web servers…  
I would like not to create multiple inventorys, but to keep it simple as possible.

Do you know this kind of solution?

---

<div class="post-metadata">

**Author:** ![jrglynn2](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@jrglynn2](https://forum.ansible.com/u/jrglynn2)\
**Post date:** [November 21, 2023, 9:00pm UTC](https://forum.ansible.com/t/multiple-clients-and-multiple-sub-groups/2496/2 "2023-11-21T21:00:08Z")

</div>

I think you can experiment with patterns - [Patterns: targeting hosts and groups — Ansible Documentation](https://docs.ansible.com/ansible/latest/inventory_guide/intro_patterns.html)

For example, if all the “db servers” groups will be named `-db`, I would think you could run against `*-db`…

I don’t use static inventory files, but I do use wildcards often when calling hosts/groups/etc. …

---

<div class="post-metadata">

**Author:** ![dbpiv](https://avatars.discourse-cdn.com/v4/letter/d/90ced4/32.png) [@dbpiv](https://forum.ansible.com/u/dbpiv)\
**Post date:** [November 21, 2023, 9:39pm UTC](https://forum.ansible.com/t/multiple-clients-and-multiple-sub-groups/2496/3 "2023-11-21T21:39:56Z")

</div>

We do something similar… We look at it as a horizontal and vertical inventory. We are able to run on a specific instance (say PROD) or a specific type (say web). You can also join groups using the “:children” option and have groups of groups.

We are able to use this inventory and say PROD:!WEB and that will run on all servers in PROD that are not type WEB. Or we can union two groups and say PROD:&APP this will run on PROD servers that are type APP. We also use the children option for patching. We might patch all of NONPROD at the same time and that would exclude any PROD servers.

Our inventories look something like this:  
[WEB]  
web101  
web102  
web103

[APP]  
app101  
app102  
app103

[DB]  
db101  
db102  
db103

[PROD]  
web103  
app102  
db102

[DEV]  
web101  
app101  
db101

[STG]  
web102  
app102  
db102

[NONPROD:children]  
DEV  
STG

Hope that helps,

dp

---

<div class="post-metadata">

**Author:** ![chris](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/chris/32/293_2.png) [@chris](https://forum.ansible.com/u/chris)\
**Post date:** [November 22, 2023, 2:56pm UTC](https://forum.ansible.com/t/multiple-clients-and-multiple-sub-groups/2496/4 "2023-11-22T14:56:10Z")

</div>

Personally I prefer using YAML to INI for the inventory file, there are [example of both in the documentation](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html#inventory-basics-formats-hosts-and-groups).

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [November 22, 2023, 7:40pm UTC](https://forum.ansible.com/t/multiple-clients-and-multiple-sub-groups/2496/5 "2023-11-22T19:40:21Z")

</div>

We have a naming convention for both inventories and groups within, and some guidelines.

- Each inventory source should have a clear purpose.
- All groups from a given inventory source will start with the same prefix.
- All sub-groups are named such that it’s obvious which group(s) they are a sub of.
- Any host should show up only once in a given inventory source.

Problems with that last bullet point indicate that we either haven’t fully articulated our groups in the inventory source, or that we’re mixing inventory purposes - i.e. we’re trying to use one inventory source for two different things, such that we probably need another source _at that level_.

So if we were looking at your inventory, we’d structure it like this (maybe):  
`{prefix}_{customer}_{environment}_{tier}`  
and the whole thing might look like this:

```auto
[client_all:children]
client_jack
client_jill

#### jack ####
[client_jack:children]
client_jack_dev
client_jack_prd

[client_jack_dev:children]
client_jack_dev_db
client_jack_dev_web
client_jack_dev_stg

[client_jack_dev_db]
dbdev1

[client_jack_dev_web]
webdev1

[client_jack_dev_stg]
stgdev1

[client_jack_prd:children]
client_jack_prd_db
client_jack_prd_web
client_jack_prd_stg

[client_jack_prd_db]
dbprd1
dbprd2

[client_jack_prd_web]
webprd1
webprd2

[client_jack_prd_stg]
stgprd1

#### jill ####
[client_jill:children]
client_jill_dev
client_jill_prd

[client_jill_dev:children]
client_jill_dev_db
client_jill_dev_web
client_jill_dev_stg

[client_jill_dev_db]
dbdev2

[client_jill_dev_web]
webdev2

[client_jill_dev_stg]
stgdev2

[client_jill_prd:children]
client_jill_prd_db
client_jill_prd_web
client_jill_prd_stg

[client_jill_prd_db]
dbprd3
dbprd4

[client_jill_prd_web]
webprd3
webprd4

[client_jill_prd_stg]
stgprd2

```

Only we’d use hosts’ FQDNs, For us, `{{ inventory_hostname }}` always equals `{{ ansible_fqdn }}` after gathering facts.

About hosts only being listed in one place: If you set up your groups right, then the hosts will always pop into whatever parent groups they should be in. But if they’re listed in multiple places, then every time you add or change a host, you have to examine the whole inventory source’s groups and make a decision about each one. That’s the kind of work computers were supposed to do for us, not the other way around.

This looks overblown for such a small set of hosts, and maybe it is practical to leave out some intermediate groups if you never need them. But if you ever do, it’s clear just from the group names how the hierarchy fits together so you could add them later.

If you take nothing else from our experience, consider this suggestion: **Although Ansible allows you to structure your inventory in gajillions of ways besides a strict hierarchy, don’t do it.** It’s easy to understand, verify, and maintain a hierarchy, and therefor easy(ish) to see when you mess it up. But if you accidentally build an _N_-dimensional ad hoc polyfrackus inventory from Mordor, you could get in pretty deep before you realize you’ve created a monster.
