Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

run ansible task only if tag is NOT specified

Tags:

tags

ansible

Say I want to run a task only when a specific tag is NOT in the list of tags supplied on the command line, even if other tags are specified. Of these, only the last one will work as I expect in all situations:

- hosts: all
  tasks:
    - debug:
        msg: 'not TAG (won't work if other tags specified)'
      tags: not TAG

    - debug:
        msg: 'always, but not if TAG specified (doesn't work; always runs)'
      tags: always,not TAG

    - debug:
        msg: 'ALWAYS, but not if TAG in ansible_run_tags'
      when: "'TAG' not in ansible_run_tags"
      tags: always

Try it with different CLI options and you'll hopefully see why I find this a bit perplexing:

ansible-playbook tags-test.yml -l HOST
ansible-playbook tags-test.yml -l HOST -t TAG
ansible-playbook tags-test.yml -l HOST -t OTHERTAG

Questions: (a) is that expected behavior? and (b) is there a better way or some logic I'm missing?

I'm surprised I had to dig into the (undocumented, AFAICT) variable ansible_run_tags.


Amendment: It was suggested that I post my actual use case. I'm using ansible to drive system updates on Debian family systems. I'm trying to notify at the end if a reboot is required unless the tag reboot was supplied, in which case cause a reboot (and wait for system to come back up). Here is the relevant snippet:

- name: check and perhaps reboot
  block:
  - name: Check if a reboot is required
    stat:
      path: /var/run/reboot-required
      get_md5: no
    register: reboot
    tags: always,reboot

  - name: Alert if a reboot is required
    fail:
      msg: "NOTE: a reboot required to finish uppdates."
    when:
      - ('reboot' not in ansible_run_tags)
      - reboot.stat.exists
    tags: always

  - name: Reboot the server
    reboot:
      msg: rebooting after Ansible applied system updates
    when: reboot.stat.exists or ('force-reboot' in ansible_run_tags)
    tags: never,reboot,force-reboot

I think my original question(s) still have merit, but I'm also willing to accept alternative methods of accomplishing this same functionality.

like image 467
crimson-egret Avatar asked Jan 29 '19 20:01

crimson-egret


2 Answers

For completeness, and since only @paul-sweeney has offered any alternative solution, I'll answer my own question with my current best solution and let people pick / up-vote their favorite:

---
- name: run only if 'TAG' not specified
  debug:
    msg: 'ALWAYS, but not if TAG in ansible_run_tags'
  when: "'TAG' not in ansible_run_tags"
  tags: always
like image 58
crimson-egret Avatar answered Oct 05 '22 13:10

crimson-egret


I know it's an old(ish) question, but I had a similar requirement.

It's probably something best implemented another way ... but ... sometimes it can be useful.

I'd achieve it by setting a fact if the tag IS specified, then outputting the message only if the fact is not set, something like:

---
- name: "test task runs only if tag missing"
  hosts: all
  tasks:
    - name: "suppress message if tag given"
      set_fact: suppress_message=yes
      tags: reboot,never

    - name: "message"
      debug:
        msg: "You didn't say 'reboot'"
      when: suppress_message is not defined
like image 40
Paul Sweeney Avatar answered Oct 05 '22 14:10

Paul Sweeney