--skip-tags equivalent inside playbooks

Hi everybody,

http://docs.ansible.com/playbooks_tags.html mentions several ways to use tags, one of which is:

  • { role: A, tags: [t1, t2] }

however cli interface allows for inversion via --skip-tags (which is great BTW) and there’s no mention of it’s equivalent in playbooks.

so in short:

“–tags” == “tags:”
“–skip-tags” == ???

Excerpts from Dmitry Makovey's message of 2014-07-08 18:49:22 -0400:

Hi everybody,

http://docs.ansible.com/playbooks_tags.html mentions several ways to use
tags, one of which is:

- { role: A, tags: [t1, t2] }

This doesn't do what you think it does. It applies tags 't1' and 't2'
to all the tasks in role 'A'. It doesn't filter that tasks within the
role.

As such, this is not applicable:

Correct.

Tags in playbooks apply tags to tasks.

–tags means “run the things that are so tagged”
–skip-tags means the opposite

darn. May I suggest some clarification for the documentation then? The way it is written currently allows for “free interpretation” which obviously mislead me.

Now the other question: would it be reasonable to ask for such feature then? I can see a lots of uses for it (both for using only tagX from roleA and skipping all tagY from roleB scenarios) also I can see how I can unify all tasks in fewer files and not have to resort to tricks like:

roles/
httpd/
install/
tasks/
setup/
tasks/

with subsequent:

roles:

  • role: httpd/install
  • role: httpd/setup

that I’ve done on advise from this list to separate my install from my setup yet I’d like to share a thing or two between those… having it done via tags would seem more natural to me.

"Now the other question: would it be reasonable to ask for such feature then? "

It would not :slight_smile:

I think it makes much more sense to explicitly tag things.

For instance, think of flickr.com and I tag all pictures in an album “vacation”, I don’t have the ability to take another album and tag pictures “not vacation” in such a way that the vacation tag doesn’t pick them up.

Being able to say “don’t run these tags” if of course what --skip-tags does, and we can do that.

It appears I should’ve been clearer with my question: “would it be reasonable to include feature that allows selective use of role’s tasks?”

So right now we can do { role: roleA, tags: tagX } which, if I understood things correctly applies tagX to all tasks under roleA. What I’m asking is something more like:
{ role: roleA, use-tags: tagY } which would be similar to the CLI “–tags” except localized down to a roleA only and exectuting only tasks tagged tagY from roleA.

My usecase: I’ve got playbook that does both install and setup. However install should really be ran once and setup, well, as many times as I please :slight_smile: for each role in my playbook I’d like to use common vars and some of the files, like templates and scripts. So, I would like to be able to write 2 playbooks: 1st_run.yml that uses “normal” role notation and invokes all the tasks under that role, and then “setup.yml” which would use above mentioned syntax for role: { role: roleA, use-tags: setup }. Passing --tags with CLI is a bit too blunt for the cases where I want all tags to run for roleB, for example. use of “when” and conditional vars for the same purpose becomes cumbersome as now I have to handle mutiple “when” statements for some tasks etc. Tags IMO present a way more elegant solution.

With above explanation, I’d like to restate my question: would it be reasonable to expect such feature in Ansible?

I think I’d be open to it, depending on patch complexity.

This sounds like very reasonable request, option like:

- { role: A, skip-tags: [t1, t2] }

whould be very useful in case of playbook with many roles having same tags thus --skip-tags is not an option in case one wants to skip tags in couple of roles only.

Any plans to support this?

Hi,

I'm asking is something more like:
{ role: roleA, use-tags: tagY } which would be similar to the CLI
"--tags" except localized down to a roleA only and exectuting *only*
tasks tagged tagY from roleA.

I'd like that too!

My usecase: I've got playbook that does both install and setup. However
install should really be ran once and setup, well, as many times as I
please :slight_smile: for each role in my playbook I'd like to use common vars and
some of the files, like templates and scripts. So, I would like to be
able to write 2 playbooks: 1st_run.yml that uses "normal" role notation
and invokes all the tasks under that role, and then "setup.yml" which
would use above mentioned syntax for role: { role: roleA, use-tags:
setup }. Passing --tags with CLI is a bit too blunt for the cases where
I want all tags to run for roleB, for example. use of "when" and
conditional vars for the same purpose becomes cumbersome as now I have
to handle mutiple "when" statements for some tasks etc. Tags IMO present
a way more elegant solution.

I would like to have the equivalent to
# ansible-playbook -i Testing/ ldap.yml --tags=ldap_schema mailserver
in a Playbook.
There is no way to do this at the moment, am I right?

I could put it in a shell script, but this does not feel right …

Marc

I agree that I’d like to be able to have roll contain a number of tasks and then have then selective run. A use-tags or play-tags option would be nice to use in that case. While you can certainly implement that with vars (see #2 below), it seems that a tags solution would be more elegant.

There are also times when you want to insert debug tasks but don’t want them to play by default and don’t want to have to remember to always send --skip-tags=‘debug’ every time you run a playbook.

However, for now, I work around this in two ways:

  1. I write a python script that calls the playbook and it sets the tags for me.

e.g.

`
./run_playbook.py site.yml

`

would essentially run:

`
ansible-playbook -i hosts site.yml --skip-tags=‘debug’

`

or something to that effect.

  1. I require an extra-var to not skip.

e.g.

`
tasks:

  • name: Show vars
    debug: msg={{item.ansible_facts}}
    with_items: some_loaded_vars.results
    tags: debug
    when: debug|default(false)

`

then:

`
ansible-playbook site.yml -e ‘{“debug”:true}’

`

would execute that task.

Yeah, for sure there can be some workarounds but very tedious ones. Your example can work but needs to be thought of at the very beginning of organizing your repository and I can’t see anyone that clever foreseeing that far in the future about issue like this. Ones you have repository of 30 roles and more than hundred of playbooks retrofitting this into every playbook for every task and who knows how many different variables (you obviously need separate variable per tag type) is really impossible.

Is this feature implemented yet? Does somebody know anything about it?

  1. december 18., péntek 0:48:06 UTC+1 időpontban Igor Cicimov a következőt írta:

Anyone knows if this is possible in any ansible release?

No, it is not possible

Brian, I find the current usage of “tags” when calling a role via “roles:” or “include_role/import_role” is counter intuitive. The reason we tag tasks in our playbooks is for the purpose of filtering which we would expect to be the case in the above mentioned scenarios as well. But it is not, and that is major draw back in making reusable (DRY) code.

I constantly find my self in need to execute just a part of some role tasks, lets say the ones tagged with “install” but skip the ones tagged with “configure” lets say. This is exactly what we get by passing “–tags” or “–skip-tags” on the command line so why not make this consistent everywhere?

I would argue that it's very consistent at the moment.
All tags in a yaml file sets/add that tag(s), and which tags you want to run is specified on the command line.

Use variables if you want to run part of your code.
An example:

roles/test/install.yml
roles/test/configure.yml

roles/test/main.yml

Kai, why would I use vars when I already have tags on my tasks which purpose, and only purpose, is filtering during execution?

Also as I said back in 2015 https://groups.google.com/d/msg/ansible-project/WimzDEJLHJc/9U10Yjb4CQAJ it is hard to retrofit variables into hundreds of playbooks you have written with tags expecting they will serve the purpose they exist for, which is filtering.

From where I stand, the “tags” option that we can pass to the role like this:

  • roles:
  • { name: role1 tags: [“tag1”,“tag2”] } <== this IS/SHOULD BE equivalent to a command line

is pretty much useless since instead filtering the role’s tasks based on that “tags” list it adds those tags to each of them. Really not sure how is this helping me in any way and what would be the use case or advantage I get from doing this? I mean if I wanted those tags in a role I would have included them in its tasks already … or am I missing something?

So to conclude, when I call a role with tags I expect those and only those tags to be in effect during role’s execution. Similarly I would expect to use skip-tags for tags I do not want executed during run time. Instead of that you are telling me to use vars when I already have tags that should serve the purpose.

Not sure why such a resistance towards a feature that is very logical to have and makes much more sense than what it is atm.

Kai, why would I use vars when I already have tags on my tasks which
purpose, and only purpose, is filtering during execution?

Filtering is done on the command line with --tags not inside a playbook or task file.
If you need any other functionality, variables is the way to go.

Also as I said back in 2015
https://groups.google.com/d/msg/ansible-project/WimzDEJLHJc/9U10Yjb4CQAJ it
is hard to retrofit variables into hundreds of playbooks you have written
with tags expecting they will serve the purpose they exist for, *which is
filtering*.

They do, the filtering is done on the command line.
Tags on a role in a playbook is adding the tags to all the task in the role.

So it pretty uniform, tags in in task files and playbooks is adding that tag to the task.
Filtering is done at run time on the command line.

From where I stand, the "tags" option that we can pass to the role like
this:

- roles:
    - { name: role1 tags: ["tag1","tag2"] } <== this *IS/SHOULD BE*
equivalent to a command line

Why should it, in my opinion this will make it pretty confusing for when tags add a tag and when it's filtering on tags.

is pretty much useless since instead filtering the role's tasks based on
that "tags" list it adds those tags to each of them. Really not sure how is
this helping me in any way and what would be the use case or advantage I
get from doing this? I mean if I wanted those tags in a role I would have
included them in its tasks already ... or am I missing something?

The functionality is that if you want to run a few of the role(s) in a playbook, add a tag to the role and filter the tag on the command line.
I use this feature a lot, a playbook have have tens of roles and I just want to run one or two of them, so changing that will destroy my and everyone else's use of tags.

If you download a role from Galaxy you don't want to change the tags in the role because that makes it very hard to download newer version of that role.
But you can at least add your own tags on the role so you can filter to run or not run the role when the playbook is running.

So to conclude, when I call a role with *tags* I expect those and only
those tags to be in effect during role's execution.

But I don't, and it's not feature I need since I use variables for that.

Similarly I would
expect to use *skip-tags* for tags I do not want executed during run time.
Instead of that you are telling me to use vars when I already have tags
that should serve the purpose.

The problem here is if you have 20 roles where all roles have uniq tag and you only want to run one of them, adding 19 skiped tags instead of 1 include tag is not very practical.

Not sure why such a resistance towards a feature that is very logical to
have and makes much more sense than what it is atm.

It might be logical for you but that doesn't mean it is logical for everyone else.
There is no resistance of new feature, only removing the one that's there.
In Ansible they have a rule to not break/change feature that people use unless it's a bug, this one is not a bug as it has function like this for years and people are using the feature. (Like all rules, there are exception but I hardly think this is one of them.)

So changing how tags works on role is probably not going to happen, but an alternative could be to add new keyword to something like a filter tag and a add tag.

You are free to add a proposal at https://github.com/ansible/proposals and maybe someone have already done that for all i know.

Kai, why would I use vars when I already have tags on my tasks which
purpose, and only purpose, is filtering during execution?

Filtering is done on the command line with --tags not inside a playbook
or task file.

That’s correct … and have you tried doing so? In the below example:

`

  • roles:
  • role1
  • role2
  • role3
    `

where all 3 roles have the same tags, lets say “instal” and “configure”, how are you going to filter the “install” tag for the role1 only?

If you need any other functionality, variables is the way to go.

Yeah like in the example you gave above:

You have the tag “never” which will make that role/task not execute by default when running the play, unless explicitly called with --tags. Check special tags in the docs: https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html