Roles purpose, best practices

Hi!
We have automations for provisioning and for updating configuration when needed, for backup and restore, and we also have event driven - getting an alert and doing something to address the alert.
We are planning to decide on some standards for us and rewrite what we have.

I’m not sure about how is the correct way of using roles, should it be like its name actual role the server has, that will include everything it needs for that role and if it doesn’t match this to have it in the play? or should a role be more small and generic like a function?
Is there best practices on this?

1 Like

Hi!

I think the best answer to your question is, ‘It depends’. I’ve been using roles as (small) building blocks, but that’s due to the nature of my work. I’m an infrastructure engineer, so I build servers as ‘blocks’ and the amount of control I have after the fact differs.

And having my roles organized like this, it’s also easier to maintain the roles themselves as their scope is limited.

But as roles can have dependencies on other roles, it might be viable in your environment to have ‘all-in-one’ roles, with or without extra dependencies.

1 Like

Unix philosophy applied to roles proved to be the way to go for me. Small roles that do one thing and do it well significantly reduced code duplication and helped the code to be easily maintainable. You then combine those roles to build more complex solutions. Basically the same thing @Thulium-Drake already said.

Good to notice that “role” is a little bit of misnomer. It implies that a server some role is applied to would have some “role” in a sense of “purpose”. So each server would have a single “role” or a small number of them. That’s only applicable if you have a small number of different servers (or different types of servers). In case of a lot off servers with a lot of small differences, different combinations of services running on then etc, it would lead to the explosion of the number of roles… very hard to maintain.

For me a role has more of a sense of a “service”. Each role manages some service on a server (e.g. nginx) and only that service, nothing else. Each server has some services running on them so it can have a multitude of roles applied to it in various combinations.

2 Likes

We are have Ansible Good Practices were a lot of consultant/architect provide information. Anyone can submit a PR or an issue. This is a good centralized location for this type of questions.

To answer your question, roles usually describe the function they are doing so its a great practice to name the role after that. For example, “windows updates” or “linux security best practices”. It all depends on how many roles you have or how your organization writes automation content. Sometimes you will see things like “http_install” or “http_configure”.

1 Like

In my opinion: use roles when you need or want role-scoped variables, role-scoped files, or anything else in the role folder structure (such as argument validation).

If you just have tasks that use host_vars and group_vars, what I prefer doing instead is creating a shared_tasks/ subfolder and using include_tasks to load them in playbooks.

I wonder if at that point it’s best to make a collection which contains multiple roles that are related. It seems like the Ansible team is prioritizing collections over roles.

well is different but, related concepts. Roles are more define or specific automation. Collection is usually all related content including multiple roles, playbooks, modules, utils and other code. Roles can be just automation like tasks. Collections can be just modules, utils and codes. Everything works together. It just varies what you are doing.

A lot of people are using collection because its easier to pull other content instead of defining a role and the roles dependencies. Collections handles all of that.

2 Likes

Maybe the Ansible core team specifically might not be working much on roles (not that they really need to these days), there’s definitely a few teams at Red Hat that are developing roles. Red Hat CoP, TheForeman, and Fedora teams, to name a few, are all producing roles and/or collections of roles.

RedHat-CoP produces the infra namespace of collections:

TheForeman is upstream of RedHat Satellite:

And Fedora is responsible for the linux_system_roles which is upstream of rhel_system_roles

While some of these collections do have plugins, and some quite a few, many of these collections contain several roles and might even exclusively contain roles.

1 Like

To answer the question, I make a collection out of all my code.

All my roles are individually on my GH page (and sometimes “{{ customer }}” git repos). But I also made a script that will turn whatever latest version of all my roles are on my personal Git server into a collection and upload that to Galaxy.

It isn’t pretty and there’s probably a million better ways to do it, but the idea is simple:

  1. Get all roles I have in my Gitea server (I have them stored inside a organization)
  2. Get the current week number (for somewhat of a CalVer scheme)
  3. Check the latest version available on Galaxy and increment if required
  4. Download the latest tagged release (or if they have none, just use master) of each role, record in a file
  5. Package and upload to Galaxy

In case you’re looking for inspiration: GitHub - Thulium-Drake/ansible-collection-general

EDIT: BTW, most of my roles work independent of each other, which is on purpose, but for the sake of distributing them (especially at work) I wrapped them together in a collection

2 Likes

I personally would always put roles into collections (even if it’s just one role per collection) for three reasons:

  1. It makes dependency management easier. You cannot have dependencies between standalone roles and collections (collections can only depend on collecfions, standalone roles only on standalone roles), and you usually also need collections, so just for that reason it’s easier to stick to collections.
  2. Sometimes you need specialized modules or plugins for a role. While you can also package them with standalone roles, you get better separation - and a chance for code reuse! - when putting them into a collection.
  3. Sometimes you might end up with two roles that kind of belong together, and are tightly coupled, and you don’t want to package them separately. While you can use different entrypoints for standalone roles, it’s easier to have two different roles in the same collection.

Obviously if you start with already having a lot of standalone roles then some of these arguments do not really apply, but if you start from scratch (or mostly from scratch) I would always stick with roles in collections.

5 Likes