Best practices for repository structure: Is it recommended to host Ansible roles in subdirectories?

Hi everyone,

I am currently working on optimizing our project structure. We are using a monorepo approach and I am considering placing our Ansible roles inside a specific subfolder (e.g., /ansible/roles/my_role/).

I have two main questions regarding this setup:

  1. Architecture: Is hosting an Ansible role within a subdirectory of a larger repository considered a standard “best practice”? Or is it strongly recommended to maintain roles in their own dedicated repositories?
  2. Technical Implementation: If the subdirectory approach is acceptable, how can I configure the requirements.yml file to correctly target and install only that specific subdirectory using ansible-galaxy role install?

I have looked into the documentation, but I am struggling to find the correct syntax for partial repository imports. Any guidance, community feedback, or links to relevant resources would be greatly appreciated.

Thank you in advance for your help!

Hi @Yoann.

Organize your roles into collections. One collection = one repository. You can then pull the collections with ansible-galaxy collection install -r requirements.yml and use the roles you need in the project. Yeah, it will probably pull more roles that you really need but if you keep your collection with a well define scope, even that will not be an issue.

I would say this is the “best practice” way and most easy one to understand and implement.

From the moment you use the subdirectory approach, roles are already considered installed, you don’t need requirements.yml, possibly configure the roles_path ansible.cfg definition if you use a custom name.
If you want these roles to be reusable, which is usually what people want, go collections as stated above :slight_smile:

For smaller projects (where very few people work on, and where reuse in other repos is not needed), having the roles and collection(s) in the same repository as the playbooks is also OK. Ansible automatically looks in roles/<role-name>/ for roles and collections/ansible_collections/<namespace>/<name>/ for collections.

I’ve been re-reading your original question for 5 days now, and every day I’ve come up with a different misunderstanding of what you’re asking. The prior responses above are all fine as far as they go, but there are a lot of assumptions - that I was making at least - that need to be cleared up.

For instance:

We are using a monorepo approach…

To me that means all your projects and roles are in one repo, so there’s no need for calling ansible-galaxy to install roles. So that’s probably not what you mean.

I am considering placing our Ansible roles inside a specific subfolder (e.g., /ansible/roles/my_role/).

Does this mean all roles come from ./ansible/roles/<role_name> in the git project that is the canonical source for all your roles, or does it mean you intend to use
ansible-galaxy role install -r <path_to_reqs>/requirements.yml ./ansible/roles to place these roles there?

Either way, I don’t understand what you gain by using ./ansible/roles/ rather than ./roles/.

  1. Architecture: Is hosting an Ansible role within a subdirectory of a larger repository considered a standard “best practice”? Or is it strongly recommended to maintain roles in their own dedicated repositories?

[Given my standard set of myriad assumptions,] Hosting a project-specific role within a project is perfectly acceptable. That could be a stand-alone role typically in your project’s ./roles/ directory, or in a project-specific local collection. (The local collection namespace is reserved specifically for this purpose.

However, if it’s a role to be used by multiple projects, it’s better to host it in its own project, and best to put it in a collection. If it’s just a few tasks or task files, it probably doesn’t matter. But once it starts sprouting custom plugins or relying on other local roles, then all those things should be lumped into a collection. That lets you take advantage of fully qualified naming as well as keeping functionality in sync among the related roles.

  1. Technical Implementation: If the subdirectory approach is acceptable, how can I configure the requirements.yml file to correctly target and install only that specific subdirectory using ansible-galaxy role install?

Here’s where I have the hardest time reconciling my assumptions with your question. If you ansible-galaxy install something, it’s going to install the whole something. I’m afraid you may be trying to re-implement in roles the functionality that’s already provided by collections. As @bvitnik pointed out in the first response above, using a collection will pull in all the collections roles, plugins, etc. whether you need them or not, but in practice that’s not an issue. Non-standard (i.e. untested by anyone but you) one-off solutions for the sake of saving a few files is a false economy.

I’m not claiming this make it right, but in our shop, we have a mix of all the “standard” techniques. We have some common roles in their own repos that predate collections, and if we were starting from scratch they’d be in a local collection. But there’s absolutely nothing wrong with them as stand-alone roles which we ansible-galaxy role install …. We also have project-specific roles in practically every project, a few projects with their own local collections, and some shared collections. It all just works, and there’s no non-standard practice. That is to say anybody familiar with Ansible should be able to come in and see how everything works with a quick glance at any project’s ./roles/requirements.yml and ./collections/requirements.yml files.

Pretty much everything I’ve said was alluded to by prior posters. I’m not as gifted at brevity as they are. :slight_smile: Thanks for your patience. If I’ve misrepresented or missed entirely what you were asking about, please feel free to set me straight. It’s useful to me to spell these ideas out; I hope you found something worthwhile in it, too.