如果*任何*主机有一个事实,如何运行一个Ansible任务

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

我正在思考我可能过于复杂的事情。

我需要检查我的主机是否有 ansible_virtualization_type == "openvz"

如果是这种情况,所有主机都应执行特定任务。

我现在正在尝试设置一个事实 (virt_list),其中包含一个主机列表,其中 virtualization_type 在本地主机上:

- 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

但这不行(这出戏的两台主机都在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"
            }
        ]
    }

应该有更简单的方法,也许直接用jinjia2合并列表。

有人有建议吗?

问:"如果我的任何主机有 ansible_virtualization_type == "openvz" 所有主机都应执行特定任务。"= 38=]

A:例如,给定库存进行测试

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

提取变量

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

给予

  msg:
  - xen
  - xen
  - openvz

测试类型是否存在

    - 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

给予

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

如果这按预期工作,则继续处理所有主机

    - 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)

给予

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.

如果缺少类型,任务将被跳过。