Dealing with a proliferation of playbooks

As our company is growing and our use of Ansible grows with it, we’re starting to struggle a bit with organization of our Ansible configs. The primary problem is that while we have things organized according to the documented best practices, those docs put all the playbooks at the root level, and we’re starting to get many of those.

Each playbook is fairly simple - a few chunks of code for provisioning an instance, a few chunks for setting up the firewall rules, and a list of roles to apply to the servers. However, this is enough stuff that it’s a bit messy including all of these in one giant file, so we have them split out by group, with a top-level file that includes them all. This also helps speed things up quite a bit, as we can run only the playbook we’ve changed, rather than check every single piece of configuration on every single server in the fleet.

However, since we’re getting a lot of different services we’re supporting, this ends up with a lot of different playbooks hanging out in the root. If we put them in a subredirectory, then they can no longer access the roles, variables, etc.

So far, the options I’ve considered are:

  1. Deal with it as-is.
  2. Move everything into one playbook (less than ideal, for the reasons stated above).
  3. Move them into a directory structure and write a wrapper around ansible that adjusts ANSIBLE_CONFIG etc. to point to the correct places.
  4. Split up our entire ansible directory structure into separate components, each with their own roles, vars, etc. and put common shared functionality into a separate location that’s then pointed to by roles_path.
  5. Move everything into one playbook and use tags to allow us to easily-ish run only certain projects’ configuration.

Is there a community consensus on how to handle organization when supporting a large number of mostly disparate apps?

I don’t know what other people do - I suspect it varies a lot according to use and team size - ansible is very flexible after all, but for what its worth I moved all my playbooks out of root and into dirs a while ago as they were getting out of control too.

I have dirs like

plays/provision (putting the software stack in place for each type of server)
plays/update (install latest versions of software components)
plays/untested (where I work up new plays)
plays/operations (check things, rolling restarts etc)

I do however keep all my roles in a single roles dir and so far have managed not to have any roles which are ‘private’ to the playbook dirs. To me this maximizes the re-use I can get out of roles.
I make use of playbook includes to run multiple playbooks where appropriate in some cases too.

As far as vars are concerned I have several inventory files and at least 1 group_vars (directory) per inventory so I can set vars for each environment independently, where necessary.

Hope this helps

Jon

I don’t know what other people do - I suspect it varies a lot according to use and team size - ansible is very flexible after all, but for what its worth I moved all my playbooks out of root and into dirs a while ago as they were getting out of control too.

I have dirs like

plays/provision (putting the software stack in place for each type of server)
plays/update (install latest versions of software components)
plays/untested (where I work up new plays)
plays/operations (check things, rolling restarts etc)

Do you use an ansible.cfg in the playbook directory, or just a global one? I guess you could use symlinks in each of those directories so you only have to maintain one copy…

I do however keep all my roles in a single roles dir and so far have managed not to have any roles which are ‘private’ to the playbook dirs. To me this maximizes the re-use I can get out of roles.
I make use of playbook includes to run multiple playbooks where appropriate in some cases too.

As far as vars are concerned I have several inventory files and at least 1 group_vars (directory) per inventory so I can set vars for each environment independently, where necessary.

So you don’t find any times you wish you could share variables across playbook groups? We have things like ansible_ssh_user defined in host_vars, and some common “we use this value in a bunch of places” variables in another vars file, and I’m hesitant about duplicating them.

Hope this helps

Yes, thank you.

I’m interested in the best practices for multiple inventories with multiple ‘group_vars’ also. I’ve implemented a solution like this and found it cumbersome to have a default set of group_vars that were shared between the inventories.

I guess from what I’ve written, it would make sense to set the defaults for roles to be what are the default for our group_vars but it does include a lot of information that is particular to the organisation which isn’t appropriate for galaxy roles.

I guess another other would be constantly including a var_file for each play… This doesn’t feel like the right way to do it though.

Can anyone share experiences on setting this up in a scalable, manageable way?

I use a global ansible.cfg. I just didn’t fancy ansible behaviour changing if I changed directory.

Thinking about it, I have some groups which I use across inventories, and some groups which are strictly specific to one inventory - this is achievable using group children. The inventory file is a little more complex but it hasn’t been painful to manage once I’d got my head round the necessary groups.

I do use some groups just for connection settings (mixture of linux and windows hosts makes this necessary).

More recently have started defaulting a lot of vars as in a lot of cases I only actually need to have different values for production environments.

Hope this helps,

Could you elaborate?

The structure that I use is to keep all “task includes” in a “tasks/” subdirectory. Each include expects that any necessary variables, required by the include, will be passed in from a root-level master playbook.

Roles can be specified including a path: