It's a best practice for Ansible to check ansible version in playbook if that playbook uses some unusual features of Ansible. Sometime there is a subtle breakage which render playbook messing up production for real.
There can be other reasons to have a piece of code to run on every launch no matter what execution options are. Run it with any --limit, run it with any --tags, etc.
One part of the puzzle is easy to solve, just add tags: [always] and job is done.
Not really.
- You need to be really careful with `
hosts` definition. If your--limitis not within your list, your task is ignored. And 'all' is not a solution:--limit localhostwill ignore yourhosts: all. Buhaha. - Even if you are a smart cookie and say
hosts: all, localhost, you'll get a lot of repeated code for big inventories. Most of the time it's not the thing you want.
Complete solution
- hosts: all, localhost
gather_facts: false
run_once: true
tasks:
- name: Check if numbers are not string
assert:
that: 11 > 9
success_msg: 'Ansible is sane'
fail_msg: 'Javascript is everywhere'
tags:
- always
- number_checkAs you can see, there are few tricks here:
run_oncehelp us to reduce verbositygather_facts: falsedisable fact gathering (if you don't need facts at this stage it will greatly speeds everything)- We use tag
alwaysto make it run in all situations, except if user uses--skip-tag=alwaysor--skip-tag=number_check. - We add second tag to
alwaysto help user to skip only our task. Any workflow with--skip-tag=alwaysis strictly against best practices. Everyalwaystask should have a separate tag to allow localized skips without mass destruction weapon (It's said that--skip-tag=alwaysis Ansible equivalent of atomic bomb).
How to use this guard
As you can see, there are quiet a lot of lines in this snippet. If you want to run this snippet for real for all possible cases, you need to put it into every playbook you have in your project.
That's done by placing a 'guard' snippet into something like guard.yaml or failsafe.yaml, and import_playbook it into every other playbook as the first two lines:
- name: Safeguard checks
import_playbook: failsafe.yamlMost big projects have site.yaml which import other playbooks. Each of them should have failsafe check on top (if you have those checks in the first place), and this is another reason why you want it to be as fast as possible.