How to run an Ansible task if *any* host has a fact

Viewed 187

I'm wrapping my head around something that I'm probably overcomplicating.

I need to check if any of my hosts has ansible_virtualization_type == "openvz"

If this is the case, ALL hosts should execute a specific task.

I'm now trying to set a fact (virt_list) containing a list of hosts with their virtualization_type on localhost:

- name: Set fuse on virtualization OpenVZ
  set_fact: 
    virt_list:
    host: "{{item}}"
    type: "openvz"
  when: hostvars[item].ansible_virtualization_type == "openvz"
  with_items: "{{ groups['all'] }}"
  delegate_to: localhost
  delegate_facts: true

but this doesn't work (both hosts in this play are on openvz):

TASK [roles/testvirt : debug vars ansible_virtualization_type ] ****************************
    ok: [host1] => {
        "ansible_virtualization_type": "openvz"
    }
    ok: [host2] => {
        "ansible_virtualization_type": "openvz"
    }

TASK [roles/testvirt : debug vars virt_list ] **********************************************
    ok: [host1] => {
        "msg": [
            {
                "host": "host1",
                "type": "openvz"
            }
        ]
    }
    ok: [host2] => {
        "msg": [
            {
                "host": "host2",
                "type": "openvz"
            }
        ]
    }

There should be a simpler way, maybe using jinjia2 to combine the lists directly.

Anyone has advices?

1 Answers

Q: "If any of my hosts has ansible_virtualization_type == "openvz" ALL hosts should execute a specific task."

A: For example, given the inventory for testing

shell> cat hosts
host1 ansible_virtualization_type=xen
host2 ansible_virtualization_type=xen
host3 ansible_virtualization_type=openvz

extract the variables

    - debug:
        msg: "{{ ansible_play_hosts|
                 map('extract', hostvars, 'ansible_virtualization_type')|
                 list }}"
      run_once: true

gives

  msg:
  - xen
  - xen
  - openvz

Test if the type is present

    - debug:
        msg: OK. ALL hosts should execute a specific task.
      when: "'openvz' in vtypes"
      vars:
        vtypes: "{{ ansible_play_hosts|
                    map('extract', hostvars, 'ansible_virtualization_type')|
                    list }}"
      run_once: true

gives

  msg: OK. ALL hosts should execute a specific task.

If this is working as expected proceed with all hosts

    - set_fact:
        all_hosts_execute_specific_task: true
      when: "'openvz' in vtypes"
      vars:
        vtypes: "{{ ansible_play_hosts|
                    map('extract', hostvars, 'ansible_virtualization_type')|
                    list }}"
      run_once: true
    - debug:
        msg: Execute a specific task.
      when: all_hosts_execute_specific_task|default(false)

gives

TASK [set_fact] ************************************************************
ok: [host1]

TASK [debug] ***************************************************************
ok: [host1] => 
  msg: Execute a specific task.
ok: [host3] => 
  msg: Execute a specific task.
ok: [host2] => 
  msg: Execute a specific task.

The task will be skipped if the type is missing.

Related