Ansible role structuring
In this short post I want to talk about structuring Ansible roles in a way that OS specific tasks and variables are cleanly separated from the other common logic of the role.
My main sources of inspiration for role structuring are Ansible Galaxy and the DebObs repository and I would like to share my findings here.
A simple ssh role
Let’s first quickly discuss the directory structure of an Ansible role. In general, we have a tasks
directory, which contains each task that has to be executed for that role. Further, we got the handlers
directory, which contains service handlers which can be called from any task. We also have a vars
directory, which as the name already can contain variables. Jinja2 templates and static files are being stored inside the templates
and files
directory respectively. Another common directory is the defaults
directory, which could be used for OS independant variables.
ssh ├── defaults ├── files ├── handlers ├── tasks ├── templates └── vars
In each directory, except files
and templates
, the file main.yml
gets included automatically when you use the role.
Now, to write our ssh role for Ubuntu 14.04 we would need a template for the sshd configuration.
templates/sshd_config.j2
Next, we need a handler for the sshd service.
handlers/main.yml
Further, we need tasks which ensure that sshd is installed and the ssh config template gets rendered and deployed.
tasks/main.yml
Finally, we could define some common variables.
defaults/main.yml
A more mature role structure
While the above approach does work for Ubuntu 14.04, we still would like to easily extend our role for any other OS too. One easy way to do so, is by separating OS specific tasks and variables in different OS dedicated files. Ansible helps us to automatically identify the currently used distribution with {{ ansible_distribution }}
and {{ ansible_distribution_version }}
, so we just have to name the OS dedicated yml files accordingly and include them in our main.yml
files.
For our ssh role, the dir tree would then look something like that:
ssh ├── defaults │ └── main.yml ├── handlers │ ├── main.yml │ └── Ubuntu14.04.yml ├── tasks │ ├── main.yml │ └── Ubuntu14.04.yml ├── templates │ └── Ubuntu14_04.sshd_config.j2 └── vars └── Ubuntu14.04.yml
Here are the gists of the files.
defaults/main.yml
handlers/main.yml
handlers/Ubuntu14.04.yml
tasks/main.yml
tasks/Ubuntu14.04.yml
vars/Ubuntu14.04.yml
In that way we separated OS specific variables in dedicated files inside the vars
directory. Also OS specific tasks and handlers can now easily be separated. Ansible detects the OS it operates on and includes the dedicated files.
I use disqus as a comment system. If you click on the following button, then the disqus comment system will load in your browser and you agree to the disqus privacy policy. To delete your data from disqus you can contact their support team directly.