# Question about design of playbooks and roles

**URL:** <https://forum.ansible.com/t/question-about-design-of-playbooks-and-roles/8647>\
**Category:** Get Help\
**Created:** [September 20, 2024, 6:29am UTC](https://forum.ansible.com/t/question-about-design-of-playbooks-and-roles/8647 "2024-09-20T06:29:04Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![hieronymus](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/hieronymus/32/1624_2.png) [@hieronymus](https://forum.ansible.com/u/hieronymus)\
**Post date:** [September 20, 2024, 6:29am UTC](https://forum.ansible.com/t/question-about-design-of-playbooks-and-roles/8647/1 "2024-09-20T06:29:04Z")

</div>

Hi,

I have a design/architecture question about the best structure of playbook/roles in ansible.  
While we are most redundancy tasks for divers servers/applications like : configuration of firewall, software, services, certificate, etc… and we use many times the same module. I thought it would be appropriate to create identical roles for each function. Here’s an example:

```auto
ansible.cfg
playbooks
├── playbook_configure_linux_default.yml
├── playbook_configure_webservers.yml
└── playbook_configure_mariadb.yml
...etc
roles
├── role_software
├── role_firewall
└── role_services
...etc

```

But does this correspond to ansible logic? Or is it preferable to define one role per function? like these:

```auto
playbooks
├── playbook_configure_linux_default.yml
├── playbook_configure_webservers.yml
└── playbook_configure_mariadb.yml
...etc
roles
├── role_linux_default
├── role_webservers
└── role_mariadb
...etc

I don't think there's just one solution, but I'd like to hear your opinion on the one that ultimately corresponds best to the philosophy of ansible.
```

---

<div class="post-metadata">

**Author:** ![tonk](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/tonk/32/214_2.png) [@tonk](https://forum.ansible.com/u/tonk)\
**Post date:** [September 20, 2024, 7:27am UTC](https://forum.ansible.com/t/question-about-design-of-playbooks-and-roles/8647/2 "2024-09-20T07:27:48Z")

</div>

You could have a look at my setup, the  
_One role to rule them all_ on Github ([One role to rule them all · GitHub](https://github.com/one-role)) and the presentation I gave at CfgMgmtCamp ([Ansible in a dev, tst, acc and prod enviroment - Speaker Deck](https://speakerdeck.com/tonk/ansible-in-a-dev-tst-acc-and-prod-enviroment))

---

<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:** [September 22, 2024, 6:28pm UTC](https://forum.ansible.com/t/question-about-design-of-playbooks-and-roles/8647/3 "2024-09-22T18:28:58Z")

</div>

I try to aim to have one role per application, eg a [PHP role](https://git.coop/webarch/php), a [MariadDB role](https://git.coop/webarch/mariadb) and so on, but I’ve also ended up with a (big and complicated) [users role](https://git.coop/webarch/users) that configures multiple services, with hindsight and since I’ve started using Molecule for testing roles, I think the one role per application works best.

---

<div class="post-metadata">

**Author:** ![acestuff](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/acestuff/32/4838_2.png) [@acestuff](https://forum.ansible.com/u/acestuff)\
**Post date:** [September 22, 2024, 6:50pm UTC](https://forum.ansible.com/t/question-about-design-of-playbooks-and-roles/8647/4 "2024-09-22T18:50:49Z")

</div>

My experience is that smaller, more coherent roles are easier to both develop, and maintain. Similarly, having smaller, targeted playbooks, can be useful for small, rapid deployments. This can be good if your entire site playbook takes a long time to get applied over a large fleet - and you just need to update a small piece quickly.

Single purpose roles additionally have the advantage that they can be mixed-and-matched between different machines, e.g. both your webservers and your database servers might want to leverage a role that sets up the SSH server.

Finally, if you want to share a role on Ansible Galaxy, it is more likely others would find it useful if it did one thing, and did it well; the more things a role does, the less likely others will want all those things.

---

<div class="post-metadata">

**Author:** ![hieronymus](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/hieronymus/32/1624_2.png) [@hieronymus](https://forum.ansible.com/u/hieronymus)\
**Post date:** [September 25, 2024, 6:12am UTC](https://forum.ansible.com/t/question-about-design-of-playbooks-and-roles/8647/5 "2024-09-25T06:12:01Z")

</div>

Thank you for your replay. After reading you, I find that a mix between specific roles e.g. for firewall, users, ssh… and global roles like mariadb, snd so on can be interesting… I’m going to test all of these out…

---

<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:** [September 25, 2024, 8:38am UTC](https://forum.ansible.com/t/question-about-design-of-playbooks-and-roles/8647/6 "2024-09-25T08:38:10Z")

</div>

> [@hieronymus](#):
>
> I’m going to test all of these out…

If you do have the time and are interested enough in some of the roles I’ve written to test them then I’d suggest you start by looking at and perhaps copying and amending [this repo](https://git.coop/webarch/dev) — I use it for development and testing of the roles — all the servers it provisions are just for development and testing.

The approach I have adopted is to use the YAML format for [the inventory](https://git.coop/webarch/dev/-/blob/main/hosts.yml) and then [a directory per server for all the server variables](https://git.coop/webarch/dev/-/tree/main/host_vars) and then a [file per role for the variables for each role](https://git.coop/webarch/dev/-/tree/main/host_vars/nextcloud.webarch.org.uk).

The [requirements file](https://git.coop/webarch/dev/-/blob/main/requirements.yml) is generated using the [requirements role](https://git.coop/webarch/requirements) as it became tedious to manually ensure that it listed the latest versions of roles.

Locally I also have a `roles` directory with symlinks to each role so I can work on a role without committing changes to the `git.coop` server, the `roles` directory has a higher precedence than the directory used for the roles checked out using the `requirements.yml` list.

The quality and style of the roles vary as the older ones were written when I didn’t have as much understanding of Ansible as I do now (so they use loops too much and can be slow for example), however I’m still learning and I have no doubt that all the roles could do with improvement!

Good luck!
