pre_tasks and tags...

1,934 views
Skip to first unread message

seanosh

unread,
Jul 11, 2013, 9:21:54 AM7/11/13
to ansible...@googlegroups.com
Hey all,

Assuming the following example playbook:

- name: run common tasks against all hosts...
  hosts: all

  pre_tasks:
    - name: hello world!
      shell: echo 'hello world' > /tmp/hello

  roles:
    - { role: 'common', tags: [ 'common' ] }

When I execute the playbook without specifying any tags, the "hello world" task is executed. When I specify tags (to say, limit to a subset of specific tasks I'd like to run), the pre_tasks get skipped. Is this by design/intentional? Could just be me assuming functionality here, but I look at the logic and think any tasks in 'pre_tasks' would be executed regardless of whether or not any tags were specified... 

Thanks!

C. Morgan Hamill

unread,
Jul 11, 2013, 11:49:27 AM7/11/13
to ansible-project
Excerpts from seanosh's message of 2013-07-11 09:21:54 -0400:
> Could just be me assuming functionality here, but I look at the logic
> and think any tasks in 'pre_tasks' would be executed regardless of
> whether or not any tags were specified...

When you specify tags, ansible will run *only* the tasks with the
specified tags. In other words, tags can be used only to _limit_ the
set of tasks run. Untagged tasks are run unconditionally.

If you think about it makes sense: in your given example, if no tags are
specified, both your pre_tasks and role tasks are run; when you specify
the tag 'common', only the role tasks get run. If it worked the way you
are expecting, then in your example, whether you specified the tag
'common' or not, the same result would occur. Which seems weird to me
at least. On the other hand, given how it does work, there's no
super-clean way to mark tasks as needing to be run unconditionally,
except by making sure *every* task is tagged, one way or another (e.g.,
with a throw-away tag that you always specify whenever you specify any
tags.

If you find yourself in that situation, I'd recommend rethinking your
mental model: the whole point of playbooks is to map hosts to tasks, so
if you're trying to make one playbook map a single set of hosts to more
than one set of tasks, it may mean you actually want two or more
separate playbooks...
--
Morgan

seanosh

unread,
Jul 11, 2013, 12:54:17 PM7/11/13
to ansible...@googlegroups.com
Hey Morgan,

Thank you for your response. Inline:

On Thursday, July 11, 2013 11:49:27 AM UTC-4, C. Morgan Hamill wrote:
Excerpts from seanosh's message of 2013-07-11 09:21:54 -0400:
> Could just be me assuming functionality here, but I look at the logic
> and think any tasks in 'pre_tasks' would be executed regardless of
> whether or not any tags were specified...

When you specify tags, ansible will run *only* the tasks with the
specified tags.  In other words, tags can be used only to _limit_ the
set of tasks run.  Untagged tasks are run unconditionally.

Right, totally get that. 
 

If you think about it makes sense: in your given example, if no tags are
specified, both your pre_tasks and role tasks are run; when you specify
the tag 'common', only the role tasks get run.  If it worked the way you
are expecting, then in your example, whether you specified the tag
'common' or not, the same result would occur.  Which seems weird to me
at least.  On the other hand, given how it does work, there's no
super-clean way to mark tasks as needing to be run unconditionally,
except by making sure *every* task is tagged, one way or another (e.g.,
with a throw-away tag that you always specify whenever you specify any
tags.

To me, "pre_" specifies a "before" state for actions nested under it. If I wanted/needed a way to run a task early and have it only run under certain tags, I would've gone with "tasks" and then tagged them accordingly. So then, for me, it begs the question - what would "pre_tasks" do differently than if I had just put "tasks" in that same spot?

I guess what I'm expecting is that pre_ and post_tasks behave in a "setup" and "teardown" type way... they're always executed as part of the playbook (maybe a setup command to run a custom module that does some fact gathering, maybe a teardown command that uses the "campfire" module to notify a room that tasks have completed successfuly).  

Using https://github.com/ansible/ansible-examples/blob/master/lamp_haproxy/rolling_update.yml as an example, let's say I only wanted to update an Apache config. I don't need the whole playbook re-executed top to bottom when I know what I'm after, so I'll use tags to limit that (unless this is an incorrect mental approach to take to such things). In that example, none of the the pre_ or post_ tasks would fire since I narrowed the scope with the tag. 

Ultimately if I have to tag the pre_ tasks with all the other tags to ensure their execution, then I guess that's what it needs to be - just pointing out it's not immediately clear that it's needed for pre_ and post_ tasks. If there's an agreement there I'll happily contribute by updating the documentation and creating a PR to prevent any future confusion. 


If you find yourself in that situation, I'd recommend rethinking your
mental model: the whole point of playbooks is to map hosts to tasks, so
if you're trying to make one playbook map a single set of hosts to more
than one set of tasks, it may mean you actually want two or more
separate playbooks...

Right, totally get that as well, but that's not what I'm doing. I have hosts that should have "common" tasks executed against them and for other hosts, say "webservers" - those grab their own "roles" as well - which from what I understand is how it's recommended to be done based on the examples repo and the "Best Practices" README. 
 
--
Morgan

Serge van Ginderachter

unread,
Jul 11, 2013, 1:11:17 PM7/11/13
to ansible...@googlegroups.com

If I wanted/needed a way to run a task early and have it only run under certain tags, I would've gone with "tasks" and then tagged them accordingly. So then, for me, it begs the question - what would "pre_tasks" do differently than if I had just put "tasks" in that same spot?

"tasks" run after roles, "pre_tasks" run ​​before roles. you have to keep in mind that roles are basically nothing more than some automation around tasks, in a more portable way.

The order in in which tasks are executed are:


  pre_tasks:
  roles:
  tasks:
  post_tasks:

I guess what I'm expecting is that pre_ and post_tasks behave in a "setup" and "teardown" type way... they're always executed as part of the playbook 

That's just not how it works.
​​
Using https://github.com/ansible/ansible-examples/blob/master/lamp_haproxy/rolling_update.yml as an example, let's say I only wanted to update an Apache config. I don't need the whole playbook re-executed top to bottom when I know what I'm after, so I'll use tags to limit that (unless this is an incorrect mental approach to take to such things). In that example, none of the the pre_ or post_ tasks would fire since I narrowed the scope with the tag. 

That's because in this example, none of the pre_ and post_tasks are tagged.​​ Also, I'm not sure which tags you would use here, as the apache_common and web roles do not have any tags in their tasks. ( lamp_haproxy / roles / base-apache / tasks / main.yml etc...)

Ultimately if I have to tag the pre_ tasks with all the other tags to ensure their execution, then I guess that's what it needs to be - just pointing out it's not immediately clear that it's needed for pre_ and post_ tasks.

AFAIK, it's nowhere mentioned that *tasks and roles behave differently as far as tags are concerned​.
 
If there's an agreement there I'll happily contribute by updating the documentation and creating a PR to prevent any future confusion. 

Better documentation is always good :)​​


   Serge 


Michael DeHaan

unread,
Jul 11, 2013, 4:48:30 PM7/11/13
to ansible...@googlegroups.com
"When you specify tags, ansible will run *only* the tasks with the
specified tags.  In other words, tags can be used only to _limit_ the
set of tasks run.  Untagged tasks are run unconditionally."

This statement is not quite correct.  If you have 3 out of 57 steps tagged "go" and run --tags go, it will run 3 steps.




--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Michael DeHaan

unread,
Jul 11, 2013, 4:50:25 PM7/11/13
to ansible...@googlegroups.com
If I may summarize, it sounds like you are using pre and post tasks for load balancing, specified some tags, and the pre and post tasks were not tagged with anything, so they didn't run, and this was not intuitive.

I generally don't think pre tasks *should* be exempt from tag filtering (as that would be confusing too) but we should probably make a note of this in the documentation, so that if people are running rolling updates they can be aware to specify a tag for those tags and also include them.




--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

seanosh

unread,
Jul 11, 2013, 5:29:25 PM7/11/13
to ansible...@googlegroups.com
Thank you Michael and Serge for the replies... Inline:


On Thursday, July 11, 2013 4:50:25 PM UTC-4, Michael DeHaan wrote:
If I may summarize, it sounds like you are using pre and post tasks for load balancing, specified some tags, and the pre and post tasks were not tagged with anything, so they didn't run, and this was not intuitive.

Yup, that's it - just not for load balancing. I have a custom module that grabs facts I want available to any play (regardless of tag) via an external API.  Since I assumed that pre_tasks behaved like a 'setup' task, I figured that'd be the best place for it. I'll just go a different route. Thanks for your responses! 

Michael DeHaan

unread,
Jul 11, 2013, 5:30:54 PM7/11/13
to ansible...@googlegroups.com
I'd tag your pre and post tags with something like "lb" for now and remember to include them when you specify tags, maybe?

Michael DeHaan

unread,
Jul 11, 2013, 5:32:34 PM7/11/13
to ansible...@googlegroups.com
Ticket opened to upgrade docs:  https://github.com/ansible/ansible/issues/3505


seanosh

unread,
Jul 11, 2013, 5:39:11 PM7/11/13
to ansible...@googlegroups.com
Right, that works. This ends up prompting me to do some tag cleanup (a good thing!) to keep tags manageable so that they can be attached to pre_tasks and also only consider loading these facts when I need them (vs. having them for any playbook execution). Thanks for your suggestion!
Reply all
Reply to author
Forward
0 new messages