Prevent executing a role more than once

813 views
Skip to first unread message

Ahmad Khayyat

unread,
Jul 16, 2014, 6:01:26 PM7/16/14
to ansible...@googlegroups.com
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.

Michael DeHaan

unread,
Jul 16, 2014, 7:53:31 PM7/16/14
to ansible...@googlegroups.com
Take a look at the "allow_duplicates" parameter.





--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/CAM19uTCnyStH4yH9hkLg58T2MqG5Vv9CWXR1FB11%3D5hBkvXcdQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Ahmad Khayyat

unread,
Jul 16, 2014, 8:04:48 PM7/16/14
to ansible...@googlegroups.com

On Thu, Jul 17, 2014 at 2:53 AM, Michael DeHaan <mic...@ansible.com> wrote:

Take a look at the "allow_duplicates" parameter.

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.

Michael DeHaan

unread,
Jul 16, 2014, 8:22:34 PM7/16/14
to ansible...@googlegroups.com
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.






--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

Tony Marin

unread,
Jul 17, 2014, 3:32:11 AM7/17/14
to ansible...@googlegroups.com
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.
--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
Swiss Mobility Solutions

Tony Marin

DevOps Manager

Swiss Mobility Solutions
a Gemalto Company

Mobile+34 637402568

Office Telephone+34 966370055

Skypeantonymcs

LocationAv. Locutor Vicente Hipólito 39
03540 Alicante Spain

Email LinkedIn Website

 

Michael DeHaan

unread,
Jul 17, 2014, 8:30:44 AM7/17/14
to ansible...@googlegroups.com
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" }






Joseph Tate

unread,
Jul 17, 2014, 12:21:49 PM7/17/14
to ansible...@googlegroups.com
Even if a role ends up being a no-op, it takes time. This makes playbook execution slower, which is annoying.

Joseph Tate

unread,
Jul 17, 2014, 12:23:45 PM7/17/14
to ansible...@googlegroups.com
On Thursday, July 17, 2014 5:30:44 AM UTC-7, Michael DeHaan wrote:
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" }

Why would this not be default behavior?

Michael DeHaan

unread,
Jul 17, 2014, 9:33:23 PM7/17/14
to ansible...@googlegroups.com
On Thu, Jul 17, 2014 at 12:21 PM, Joseph Tate <dragon...@gmail.com> wrote:
Even if a role ends up being a no-op, it takes time. This makes playbook execution slower, which is annoying.

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


Michael DeHaan

unread,
Jul 17, 2014, 9:34:04 PM7/17/14
to ansible...@googlegroups.com
Role dependencies can have parameters.

 

Ahmad Khayyat

unread,
Jul 17, 2014, 10:35:01 PM7/17/14
to ansible...@googlegroups.com

On Fri, Jul 18, 2014 at 4:34 AM, Michael DeHaan <mic...@ansible.com> wrote:

Role dependencies can have parameters.

​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?

Michael DeHaan

unread,
Jul 18, 2014, 7:40:45 AM7/18/14
to ansible...@googlegroups.com
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.





--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

Ahmad Khayyat

unread,
Jul 18, 2014, 11:35:17 AM7/18/14
to ansible...@googlegroups.com

On Fri, Jul 18, 2014 at 2:40 PM, Michael DeHaan <mic...@ansible.com> wrote:

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?

Michael DeHaan

unread,
Jul 18, 2014, 2:12:52 PM7/18/14
to ansible...@googlegroups.com
"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.




--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages