# Dependency check between roles

**URL:** <https://forum.ansible.com/t/dependency-check-between-roles/24512>\
**Category:** Ansible Project\
**Created:** [May 18, 2017, 12:21pm UTC](https://forum.ansible.com/t/dependency-check-between-roles/24512 "2017-05-18T12:21:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jose\_Luis\_Fernandez](https://avatars.discourse-cdn.com/v4/letter/j/a88e4f/32.png) [@Jose\_Luis\_Fernandez](https://forum.ansible.com/u/Jose_Luis_Fernandez)\
**Post date:** [May 18, 2017, 12:21pm UTC](https://forum.ansible.com/t/dependency-check-between-roles/24512/1 "2017-05-18T12:21:58Z")

</div>

Hi all!

I need to disallow a role from being executed when it is include more than once. The scenario is like this.

Role A includes as a dependency Role B  
Role C includes as a dependency Role B

I include role A and role C in a playbook

The result is.

B is run  
A is run  
B is run  
C is run

Given that B is already executed I would like it not to be run again.

Any idea? Im currently setting a fact in B and use a conditional include in its main.yml file but this is code smell IMHO.

Thanks in advance!

---

<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 18, 2017, 7:46pm UTC](https://forum.ansible.com/t/dependency-check-between-roles/24512/2 "2017-05-18T19:46:26Z")

</div>

I'd skip the dependency mechanics and just explicitly apply both roles  
in the play.

---

<div class="post-metadata">

**Author:** ![Jose\_Luis\_Fernandez](https://avatars.discourse-cdn.com/v4/letter/j/a88e4f/32.png) [@Jose\_Luis\_Fernandez](https://forum.ansible.com/u/Jose_Luis_Fernandez)\
**Post date:** [May 19, 2017, 11:34am UTC](https://forum.ansible.com/t/dependency-check-between-roles/24512/3 "2017-05-19T11:34:01Z")

</div>

Well, the thing here is a matter of encapsulation, the responsibility of installing B is inside A or C not in the playbook (the playbook should be agnostic). Imagine this scenario:

I have a web server with an nginx with different sites installed (for two different applications). For each application I create a role that installs nginx and creates a site with its configuration, I want those roles to be self sufficient because maybe in the future those two applications wont be installed in the same host.

In the role of each application I could have a:

- name: "Install nginx package  
apt: pkg=nginx state=latest

This will be executed twice though only the first time will do stuff.

A good approach to DRY it out a little be would be extracting the nginx installation into a new role where I maybe also do some common tweaks like adding common files to /etc/nginx/conf.d directory etc. In this case, I should use a dependency in my application roles so I ensure nginx is installed before adding the site for the app. Now, after the refactor with the dependencies approach, the nginx tasks will be executed twice (again), first time doing stuff and second not doing anything but spending time with state checking. This is because the whole ‘Dependencies are only installed once unless allow\_duplicates is yes’ thing is scoped to the role.

I’m currently creating a guard to ensure it gets executed only once. But this is ugly and I think this scenario is quite common and ansible should implement a way of dealing with such things. Maybe there is a way of doing it but Im missing it. In puppet is straightforward, a simple require would do, because is declarative.

Any thoughts?

---

<div class="post-metadata">

**Author:** ![Trond\_Hindenes](https://avatars.discourse-cdn.com/v4/letter/t/96bed5/32.png) [@Trond\_Hindenes](https://forum.ansible.com/u/Trond_Hindenes)\
**Post date:** [May 21, 2017, 10:11am UTC](https://forum.ansible.com/t/dependency-check-between-roles/24512/4 "2017-05-21T10:11:34Z")

</div>

As long as you haven’t set the “private\_role\_vars = yes” option in Ansible.cfg, you could do this by adding a set\_fact step at the end of role B (something like “role\_b\_has\_run”: true), and then at the beginning you check for the existence of it, probably using a “when block” on the entire thing.

First time Role B runs, it will toggle the variable to true using set\_fact, and next time it runs you can skip the role or parts of it by checking for the existence of that fact.

-Trond

---

<div class="post-metadata">

**Author:** ![Jose\_Luis\_Fernandez](https://avatars.discourse-cdn.com/v4/letter/j/a88e4f/32.png) [@Jose\_Luis\_Fernandez](https://forum.ansible.com/u/Jose_Luis_Fernandez)\
**Post date:** [May 22, 2017, 8:44am UTC](https://forum.ansible.com/t/dependency-check-between-roles/24512/5 "2017-05-22T08:44:44Z")

</div>

That’s what I’m doing now and it works but I find two trade offs with this approach.

1. You pollute the global scope with facts, and you are at risk of name clashing
2. You have to explicitly write the guard with code, something that is going to be the same in several roles. That’s more boilerplate and code complexity.

I think this use case is common enough to be implemented in the language itself. Something like a meta key saying ‘this module should only be run once per server, don’t bother to run in several times’ lets say:

---

<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 22, 2017, 12:42pm UTC](https://forum.ansible.com/t/dependency-check-between-roles/24512/6 "2017-05-22T12:42:57Z")

</div>

I started liking the dependency model but it was generally met with confusion by  
other admins, so we started being explicit in the play.

e.g. we'd have an nginx role that setup a 'conf.d' folder to  
auto-include vhost definitions.  
That would be nginx\_confd\_dir , set in roles/nginx/defaults/main.yml.

If I 'layer' another role onto that in the same play, it can access  
the var directly and  
know where to drop it's vhost files.

In practice, this has worked pretty well for us and it makes it  
obvious what the play  
is putting on each inventory group. It also avoids the 'role gets  
applied twice' issue  
that dependencies can cause.

If the playbooks are composable and it's obvious what's being deployed  
where, it's  
a win in my book.

Code reuse makes sense when you have a load of complex libraries of thousands  
of lines of code but IMO it's massive overkill wrt. copying and  
pasting a dozen lines  
of YAML.
