Ansible: check supplied tags are valid before running a playbook

ansiblelogging

I suspect that this is trying to be too clever (and failing), but –
especially in development of a PB, it's really useful to use tags to limit the roles which are run – so for example we have: (snippet of the playbook)

 - { role: yum,      tags: [ 'yum' ] }
 - { role: proxy,    tags: [ 'proxy' ]  }
 - { role: firewall, tags: [ 'firewall' ] }

Now occasionally, I run with a misspelled tag – eg

$ ansible-playbook servername, user=fred  my_playbook --tags=firewal

And pre-tasks get run, as do post tasks, which makes it appear that something is happening, but of course, no task matches the incorrectly-entered tag. I do pick this up in logging ( every role does this:

- include_tasks: includes/log_role_completion.yml this_role={{ role_name }}

which resolves to this:

- name: "Setup completed_roles list"
  set_fact:
    completed_roles: "{{ this_role }}"
  changed_when: false
  when: completed_roles is not defined

- name: "Add role to list of completed roles"
  set_fact:
    completed_roles: "{{ completed_roles }} {{ this_role }}"
  changed_when: false
  when: completed_roles != this_role

Then, a post_tasks role writes the list of completed roles – or a message saying that none were run possibly because of a misspelt tag. This works nicely – and I know that ansible writes logs, but they are either verbose, or cryptic, and I like to have /var/log/ansible on the target with something like this:

Ansible version 2.6.2 run commenced at 2018-08-31: 20:23:40 GMT using account vmw-user
Ansible version 2.6.2 run completed at 2018-08-31: 20:23:40 GMT for roles chrony, proxy, and log_complete

That's really useful, BUT (and here's the question,finally) I'd rather have the playbook check if a tag is supplied which doesn't match any tag used in the playbook, and stop – thus warning me that I've misspelt something. this would also prevent a playbook from being incompletely run – the role with the misspelled tag would not run at all, which could cause a problem.

The variable vars.ansible_run_tags contains the user-supplied tags: is there some way of seeing which tags are set in a playbook? I don't want to run in check-mode first, and manually parse the output – I'd like it to be automatic.

Best Answer

IMHO there is no such variable to "see which tags are set in a playbook". There are only ansible_run_tags and ansible_skip_tags. I'm afraid the only option would be to write an ansible-playbook wrapper to check if the supplied tags are present in the playbook ("to run in check-mode first, and manually parse the output").

BTW. Below is a simplified list of completed roles

completed_roles: "{{ completed_roles|default('') }} {{ this_role }}"

To avoid "pre-tasks get run, as do post tasks, which makes it appear that something is happening" you might want to use import_roles and when condition instead of tags. Below is an example where role3.yml and role4.yml print a message only.

play.yml

- hosts:
    - localhost
  tasks:
    - import_role: name=role3
      when: selector|default('') in [ 'role3', 'all_roles' ]
    - import_role: name=role4
      when: selector|default('') in [ 'role4', 'all_roles' ]

.

> ansible-playbook -e selector=role4 play.yml | grep msg
    "msg": "role4"

.

> ansible-playbook -e selector=all_roles play.yml | grep msg
    "msg": "role3"
    "msg": "role4"