# Prevent executing a role more than once

**URL:** <https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685>\
**Category:** Ansible Project\
**Created:** [July 16, 2014, 10:01pm UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685 "2014-07-16T22:01:21Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ahmad\_Khayyat](https://avatars.discourse-cdn.com/v4/letter/a/858c86/32.png) [@Ahmad\_Khayyat](https://forum.ansible.com/u/Ahmad_Khayyat)\
**Post date:** [July 16, 2014, 10:01pm UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/1 "2014-07-16T22:01:21Z")

</div>

I have a common role, which i always want executed, but only once. It is also a dependency of a few other roles that may be executed on their own (via dedicated playbooks).

The problem is: in a top-level playbook, e.g. site.yml, if the common role is listed anywhere (in site.yml or an included playbook), and is also a dependency of any other role, its tasks are executed twice.

What I’m thinking is to create a dummy role that depends on ‘common’, and include the dummy role in the top-level playbook for all hosts. That way, ‘common’ is _always_ a dependency, and is always executed exactly once.

Is there a better solution?

More generally, how can I avoid executing a role more than once, whether it’s listed explicitly or pulled in as a dependency?

If a role is a dependency of multiple other roles, it’s executed once, but if it’s also listed explicitly, it is executed twice.

---

<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:** [July 16, 2014, 11:53pm UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/2 "2014-07-16T23:53:28Z")

</div>

Take a look at the “allow\_duplicates” parameter.

[http://docs.ansible.com/playbooks\_roles.html#id8](http://docs.ansible.com/playbooks_roles.html#id8)

---

<div class="post-metadata">

**Author:** ![Ahmad\_Khayyat](https://avatars.discourse-cdn.com/v4/letter/a/858c86/32.png) [@Ahmad\_Khayyat](https://forum.ansible.com/u/Ahmad_Khayyat)\
**Post date:** [July 17, 2014, 12:04am UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/3 "2014-07-17T00:04:44Z")

</div>

This does not solve my problem.

I’m happy with the default (`allow_duplicates=no`). My issue is that it only prevents the same role from executing multiple times _as a dependency_. If the same role is also listed somewhere in the playbook (in addition to being a dependency), `allow_duplicates` is irrelevant (currently).

I am looking for the equivalent of having `allow_duplicates` affect that role everywhere, whether it is being executed as a dependency, or explicitly due to being listed in a play.

​

---

<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:** [July 17, 2014, 12:22am UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/4 "2014-07-17T00:22:28Z")

</div>

Generally people should write roles so that they are idempotent (grr, that word again) and running them more than one time is a no-op.

If the operation is very destructive and you don’t want to run it again, maybe consider a touch file to indicate the configuration has been done once.

I do understand what you mean about not being a dependency anywhere, but because ansible allows parameterized roles as dependencies, this would also remove some other use cases if we applied it globally.

Some roles might allow deps, others might not, etc. The role gets to pick.

---

<div class="post-metadata">

**Author:** ![Antonio\_Marin](https://avatars.discourse-cdn.com/v4/letter/a/e5b9ba/32.png) [@Antonio\_Marin](https://forum.ansible.com/u/Antonio_Marin)\
**Post date:** [July 17, 2014, 7:31am UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/5 "2014-07-17T07:31:59Z")

</div>

You can try to set a condition on the whole role (you can use an empty main.yml with an inmport: … when: common\_executed is defined) based upon a fact/variable that you can define at the end of the common role, thus if it has been executed once, it will be skipped afterwards.

> **(attachments)**
>
> ![email_smslogo.png](https://us1.discourse-cdn.com/ansible/original/2X/b/bf3e6c6449d4dec753826c49c05d006b991d5909.png)  
> ![email_icon_mobile.png](https://us1.discourse-cdn.com/ansible/original/2X/b/b0f139f5c5e43ef87d126400b917bd24915f3d09.png)  
> ![email_icon_phone.png](https://us1.discourse-cdn.com/ansible/original/2X/b/b74cd524dbbf0e00b6a3785174947431b0201bac.png)  
> ![email_icon_skype.png](https://us1.discourse-cdn.com/ansible/original/2X/e/e823c7e1a55292a1f987d45940679ebd0be5270c.png)  
> ![email_icon_location.png](https://us1.discourse-cdn.com/ansible/original/2X/3/338e299801b9a07a4c7900163a9772f30da0a261.png)  
> ![email_icon_email.png](https://us1.discourse-cdn.com/ansible/original/2X/4/46940bb242ccbb82b87bd8e8f1749e2430b0c148.png)  
> ![email_icon_linkedin.png](https://us1.discourse-cdn.com/ansible/original/2X/c/ca838365667d8197fc713b2d1e1c59bf98a0871c.png)  
> ![email_icon_website.png](https://us1.discourse-cdn.com/ansible/original/2X/5/5c81c3c6ff3c344a10d980a674d7ef9d98002b77.png)

---

<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:** [July 17, 2014, 12:30pm UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/6 "2014-07-17T12:30:41Z")

</div>

Right! Good plan.

You could do a “set\_fact: role\_has\_executed=1” at the end of the role

and then on the role:

- role: { name: foo, when: “role\_has\_executed is defined” }

> **(attachments)**
>
> ![email_icon_mobile.png](https://us1.discourse-cdn.com/ansible/original/2X/b/b0f139f5c5e43ef87d126400b917bd24915f3d09.png)  
> ![email_smslogo.png](https://us1.discourse-cdn.com/ansible/original/2X/b/bf3e6c6449d4dec753826c49c05d006b991d5909.png)  
> ![email_icon_linkedin.png](https://us1.discourse-cdn.com/ansible/original/2X/c/ca838365667d8197fc713b2d1e1c59bf98a0871c.png)  
> ![email_icon_website.png](https://us1.discourse-cdn.com/ansible/original/2X/5/5c81c3c6ff3c344a10d980a674d7ef9d98002b77.png)  
> ![email_icon_email.png](https://us1.discourse-cdn.com/ansible/original/2X/4/46940bb242ccbb82b87bd8e8f1749e2430b0c148.png)  
> ![email_icon_location.png](https://us1.discourse-cdn.com/ansible/original/2X/3/338e299801b9a07a4c7900163a9772f30da0a261.png)  
> ![email_icon_skype.png](https://us1.discourse-cdn.com/ansible/original/2X/e/e823c7e1a55292a1f987d45940679ebd0be5270c.png)  
> ![email_icon_phone.png](https://us1.discourse-cdn.com/ansible/original/2X/b/b74cd524dbbf0e00b6a3785174947431b0201bac.png)

---

<div class="post-metadata">

**Author:** ![Joseph\_Tate](https://avatars.discourse-cdn.com/v4/letter/j/bc8723/32.png) [@Joseph\_Tate](https://forum.ansible.com/u/Joseph_Tate)\
**Post date:** [July 17, 2014, 4:21pm UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/7 "2014-07-17T16:21:49Z")

</div>

Even if a role ends up being a no-op, it takes time. This makes playbook execution slower, which is annoying.

---

<div class="post-metadata">

**Author:** ![Joseph\_Tate](https://avatars.discourse-cdn.com/v4/letter/j/bc8723/32.png) [@Joseph\_Tate](https://forum.ansible.com/u/Joseph_Tate)\
**Post date:** [July 17, 2014, 4:23pm UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/8 "2014-07-17T16:23:44Z")

</div>

Why would this not be default behavior?

---

<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:** [July 18, 2014, 1:33am UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/9 "2014-07-18T01:33:20Z")

</div>

What good does it do to tell the list you are annoyed? Provide an  
alternative, perhaps.

---

<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:** [July 18, 2014, 1:34am UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/10 "2014-07-18T01:34:01Z")

</div>

Role dependencies can have parameters.

---

<div class="post-metadata">

**Author:** ![Ahmad\_Khayyat](https://avatars.discourse-cdn.com/v4/letter/a/858c86/32.png) [@Ahmad\_Khayyat](https://forum.ansible.com/u/Ahmad_Khayyat)\
**Post date:** [July 18, 2014, 2:34am UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/11 "2014-07-18T02:34:57Z")

</div>

​Isn’t that what `allow_duplicates=yes` is for?

Wouldn’t it be more consistent for `allow_duplicates` not to discriminate​ between executing the role explicitly or as a dependency?

​

---

<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:** [July 18, 2014, 11:40am UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/12 "2014-07-18T11:40:40Z")

</div>

There are cases (again, parameterized roles) - different roles can have the same dependency with different parameters, where that doesn’t make sense.)

People get too hung up on role dependencies. In most of the content we write for customers, we actually don’t use role deps at all. They are not needed.

We generally find people coming over from Chef, specifically, get caught up in overdesign of playbook content, and people should keep things simple.

That being said there is a certain class of users that really really really want role deps, and they exist for that purpose.

it sounds like some people may like a role metadata parameter that is different from this, that is not allow\_duplicates, that is something like once\_per\_play or something.

I’d be open to consideration, but some refactoring of role implementations will need to happen first, that is in plan.

---

<div class="post-metadata">

**Author:** ![Ahmad\_Khayyat](https://avatars.discourse-cdn.com/v4/letter/a/858c86/32.png) [@Ahmad\_Khayyat](https://forum.ansible.com/u/Ahmad_Khayyat)\
**Post date:** [July 18, 2014, 3:35pm UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/13 "2014-07-18T15:35:11Z")

</div>

> There are cases (again, parameterized roles) - different roles can have the same dependency with different parameters, where that doesn’t make sense.)

​AFAIU, this is exactly the use case for `allow_duplicates=yes`, isn’t it? It would allow the role to be executed multiple times to accommodate the different parameters. What doesn’t make sense here?

On the other hand, currently, setting `allow_duplicates=no` does not help parameterized roles, nor does it help the _execute at most once_ use case.​ It allows multiple executions if the role is listed explicitly and is also a dependency.

> it sounds like some people may like a role metadata parameter that is different from this, that is not allow\_duplicates, that is something like once\_per\_play or something.

​What I’m after is not once\_per\_play, it’s absolutely once, no matter how many times the role is listed in top-level or included plays, and no matter how many times it’s pulled in as a dependency.​

If we forget about dependencies for a bit, and consider the case where a role is listed in two plays, which are both included in a top-level role. Should that role be executed multiple times even when `allow_duplicates=no`?

​

---

<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:** [July 18, 2014, 6:12pm UTC](https://forum.ansible.com/t/prevent-executing-a-role-more-than-once/15685/14 "2014-07-18T18:12:49Z")

</div>

"AFAIU, this is exactly the use case for `allow_duplicates=yes`, isn’t it? "

This only deals with role deps. I feel I am repeating myself 🙂

“If we forget about dependencies for a bit, and consider the case where a role is listed in two plays, which are both included in a top-level role. Should that role be executed multiple times even when `allow_duplicates=no`?”

Yes, because allow\_duplicates only is has meaning for role deps.
