Scaling the Ansible Hierarchy?

Hello,

I am currently following the directory layout provided by Ansible.

I understand that if I keep all of my roles/* in a directory, I can easily call each role from the top level directory like so:

site.yml # master playbook webservers.yml # playbook for webserver tier dbservers.yml # playbook for dbserver tier

However, if I have more than just webservers, dbservers, etc. my top level directory will get filled with yml files like so:

`
site.yml # master playbook
webservers.yml # playbook for webserver tier
dbservers.yml # playbook for dbserver tier
appservers.yml # playbook for appserver tier
logservers.yml # playbook for logserver tier
otherservers1.yml # playbook for otherservers1 tier
otherservers2.yml # playbook for otherservers2 tier
otherservers3.yml # playbook for otherservers3 tier
otherservers4.yml # playbook for otherservers4 tier

roles/
common/ # this hierarchy represents a “role”
tasks/ #
main.yml # ← tasks file can include smaller files if warranted
handlers/ #
main.yml # ← handlers file
templates/ # ← files for use with the template resource
ntp.conf.j2 # <------- templates end in .j2
files/ #
bar.txt # ← files for use with the copy resource
foo.sh # ← script files for use with the script resource
vars/ #
main.yml # ← variables associated with this role
defaults/ #
main.yml # ← default lower priority variables for this role
meta/ #
main.yml # ← role dependencies

`

Question: What is the solution to not overfilling my top-level directory with yml files? (Or is this normal?)

At you top level, create a directory called playbooks (or choose you
favorite name). Then you can run "ansible-playbook playbooks/site.yml".

Since Ansible look for roles relative too where the playbook is, you
need to set the "roles_path = ./roles" in your ansible.cfg.

The ansible.cfg can live in your top level directory.

Thank you, Kai! That works for me!

Thanks for the info! I tried this in my own environment, since I actually had a similar question before.

Moved playbooks to a playbooks dir. Set role_path=./roles. This broke my include statements, which I now modified to ‘- include: “{{ roles_path }}/role_handlers_ant/handlers/main.yml”’. This is likely a better practice anyway.

However, it seems that my plays can no longer find my group_vars and other such objects. Basic structure is below:

`
ansible.cfg
.ansible/inventory

playbooks/
pb.yml
roles/

roles…

host_vars/

host_vars…

group_vars/

group_vars…

`

Should host and group vars also be moved? They worked fine before I moved playbooks from top level dir to their own dir.

Specifically, the error I get now is below. This is a variable defined in a group_vars.

fatal: [ptl01a0fap006]: FAILED! => {“failed”: true, “msg”: “The conditional check ‘’{{ ansible_user_id }}’ != ‘{{ wmadmin }}’’ failed. The error was: error while evaluating conditional (‘{{ ansible_user_id }}’ != ‘{{ wmadmin }}’): ‘wmadmin’ is undefined\n\nThe error appears to have been in ‘/manh/roles/role_utility_preplay_validation/tasks/main.yml’: line 2, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n—\n- name: Ensure uid is appropriate for {{ inventory_hostname_short }}\n ^ here\nWe could be wrong, but this one looks like it might be an issue with\nmissing quotes. Always quote template expression brackets when they\nstart a value. For instance:\n\n with_items:\n - {{ foo }}\n\nShould be written as:\n\n with_items:\n - "{{ foo }}"\n”}

Thanks

Ok so I ended up rolling back to playbooks in the top level directory.

I got myself turned around a bit here. The {{roles_path}} as part of the include actually wasn’t working; which, I should have known since you can’t use ansible.cfg parameters in tasks like that. I think my main problem is that I’m using ‘include’ statements to include roles during plays. In this way, I function them out as reusable functions for different roles. I was warned that this is a nonstandard, in favor of meta dependencies. I think that’s coming back to bite me now.

Sample:

`

  • name: database param_def select

Initial select statement to see if db changes are required

tags: db
include: roles/role_utility_sqlplus/tasks/main.yml
vars:
query_type: “select”
table: “param_def”
filename: “dbselect_paramdef_mhe.sql”

`

When you run the ansible-playbook, what about prefixing the command with ANSIBLE_ROLES_PATH.

For example:

ANSIBLE_ROLES_PATH=your_path ansible-playbook site.yml

Ansible is looking for host_vars and group_vars in the inventory file
directory or the playbook directory.
If they exist in both, playbook directory overrides.

You could use
include: ../roles/role_utility_sqlplus/tasks/main.yml

Or you could set roles_path to a absolute path instead, but then the
problem is that every Ansible users need to have the files in the same
path and thats unpractical.