# Interfaces Between Roles

**URL:** <https://forum.ansible.com/t/interfaces-between-roles/15249>\
**Category:** Ansible Project\
**Created:** [May 15, 2014, 8:08pm UTC](https://forum.ansible.com/t/interfaces-between-roles/15249 "2014-05-15T20:08:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Andrew\_Fong](https://avatars.discourse-cdn.com/v4/letter/a/7feea3/32.png) [@Andrew\_Fong](https://forum.ansible.com/u/Andrew_Fong)\
**Post date:** [May 15, 2014, 8:08pm UTC](https://forum.ansible.com/t/interfaces-between-roles/15249/1 "2014-05-15T20:08:53Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [May 15, 2014, 10:01pm UTC](https://forum.ansible.com/t/interfaces-between-roles/15249/2 "2014-05-15T22:01:02Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Dick\_Davies](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@Dick\_Davies](https://forum.ansible.com/u/Dick_Davies)\
**Post date:** [May 17, 2014, 1:21pm UTC](https://forum.ansible.com/t/interfaces-between-roles/15249/3 "2014-05-17T13:21:59Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [May 19, 2014, 2:53am UTC](https://forum.ansible.com/t/interfaces-between-roles/15249/4 "2014-05-19T02:53:44Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Dick\_Davies](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@Dick\_Davies](https://forum.ansible.com/u/Dick_Davies)\
**Post date:** [May 19, 2014, 8:15am UTC](https://forum.ansible.com/t/interfaces-between-roles/15249/5 "2014-05-19T08:15:18Z")

</div>

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!
