Hi,
I’m in the process of breaking down my really long playbook into different roles and I’m wondering if there are any best practices for specifying how related roles should interact.
For example, suppose I have a Django role and a mod_wsgi role. The mod_wsgi role needs to know how to interact with the Django role (e.g. the path to the WSGI callable). Meanwhile, the Django role also needs to know how to interact with mod_wsgi (e.g. how to restart the server when certain changes are made to Django).
I can think of several ways for the two roles to interact (group vars, environment variables, etc.), but I’m wondering if there’s a preferred way to specify how they should do so. Is there the equivalent of saying that a role implements a particular interface or subclasses another role? My goal is to set things up so that I could, e.g, easily swap Django for Flask or mod_wsgi for Gunicorn and not have to muck around too much within an individual role.
Thanks.
– Andrew
If you define a variable in one role it will be totally accessible in another, but within a given role, it’s guaranteed to not have one role’s variables clobber another.
Don’t think of things as OO – Ansible is not a programming language.
Not a direct solution, but I've found it really helpful to define
dependencies in a roles meta/main.yml to ensure a 'generic'
handler exists.
Let's say you have a webapp task that needs to restart wsgi
somehow.
If there was :
roles/gunicorn/handlers/main.yml including a 'bounce wsgi' task
roles/mod_wsgi/handlers/main.yml including a 'bounce wsgi' task
and then your Flask tasks can just "notify: bounce wsgi", which will
resolve to whatever you set as a dependency in
roles/flask/meta/main.yml
It's not a universal solution, but is working pretty well for me to avoid
hard-baking an entire stack.
It is usually easier to just define that in a role called “common” and include it in all servers.
Honestly, they are useful because they silenced a large amount of user questions – usually users overcomplicating things coming from Chef – but I’m not a big fan of role dependencies.
They are only needed in a small set of cases.
Fair enough - I did start off with a 'common' role (I have a puppet
background) but there were
some slow tasks in there (JVM installs for example) that we _really_
only wanted to run
if necessary and flagging them as required plays up a fair bit on a big stack.
Agree there's a tradeoff between implicit 'magic' like dependencies and
having to remember that roleA needs a JVM if there's nothing in the role itself
to say so (arguably that's what site.yml is for of course).
Still feeling this out so appreciate the advice though, thanks!