Ansible Verbosity and Tags

A question that sometimes comes up on the forums about Ansible is how to cut down on its verbose output, especially how to suppress output for skipped tasks. One solution to this problem is to use tags instead of when. Tags allow you to bypass a task completely, as if it weren’t even in the file. However, there are some caveats. The following snippet demonstrates how this works.

- set_fact:
    skip2: false

- tags: '{{"always" if skip is undefined else "never"}}'
  debug:
    msg: 'Tag skip not skipped ({{skip is undefined}})'

- tags: '{{"always" if skip2 is undefined else "never"}}'
  debug:
    msg: 'Tag skip2 not skipped ({{skip2 is undefined}})'

- when: skip is undefined
  debug:
    msg: 'When skip not skipped ({{skip is undefined}})'

- when: skip2 is undefined
  debug:
    msg: 'When skip2 not skipped ({{skip2 is undefined}})'

If you run this, defining skip at the command line, you see that both the whens are skipped as expected, but they still appear in the output. By contrast, the first skip does not appear at all, which is what we want. Notice, though, that even though skip2 is defined, the second tags debug runs. The tags are evaluated before the file is run, so you need to take this into account when deciding whether you want to use tags to skip a task.

> ansible-playbook skip.yml -e "skip="

TASK [set_fact] ********************************************************************************************************************************************************************
ok: [localhost]

TASK [debug] ***********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Tag skip2 not skipped (False)"
}

TASK [debug] ***********************************************************************************************************************************************************************
skipping: [localhost]

TASK [debug] ***********************************************************************************************************************************************************************
skipping: [localhost]

If you run this without defining skip, you get the output below, which does run the first tags. So it’s clear that you can use tags to get a similar behavior to when but without the undesirable verbosity. There is one more caveat. It appears that you can only use the fact that a variable is bound or not. If you try to use the value of the variable to control the tags, it won’t work.

> ansible-playbook skip.yml

TASK [set_fact] ********************************************************************************************************************************************************************
ok: [localhost]

TASK [debug] ***********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Tag skip not skipped (True)"
}

TASK [debug] ***********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Tag skip2 not skipped (False)"
}

TASK [debug] ***********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "When skip not skipped (True)"
}

TASK [debug] ***********************************************************************************************************************************************************************
skipping: [localhost]

In some situations, the fact that tags are evaluated before the file runs may be desirable behavior. In the example below, I’m including a file recursively twice. The first time through, the include is run because first has not yet be defined when the tags are evaluated. The second time through, it skips the include because first was defined before the second recursive call. If you tried to do this in the exact same way using when, it wouldn’t work since first would be defined by the time the when is evaluated. In this case, you could probably come up with a slightly different way to make this work with when, but the point is that you can achieve different behavior by using tags instead.

- debug:
    msg: 'First attempt ({{first is undefined}})'

- vars:
    first: false
  tags: '{{"always" if first is undefined else "never"}}'
  include_tasks: try_something.yml
TASK [include_tasks] ***************************************************************************************************************************************************************
included: /home/user/try_something.yml for localhost

TASK [debug] ***********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "First attempt (True)"
}

TASK [include_tasks] ***************************************************************************************************************************************************************
included: /home/user/try_something.yml for localhost

TASK [debug] ***********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "First attempt (False)"
}

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top