【问题标题】:How to run an Ansible task if *any* host has a fact如果 *any* 主机有事实,如何运行 Ansible 任务
【发布时间】:2021-08-17 10:37:19
【问题描述】:

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

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

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

我现在正在尝试设置一个事实 (virt_list),其中包含主机列表及其虚拟化类型在 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

但这不起作用(本剧中的两个主机都在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 ansible-facts ansible-template


    【解决方案1】:

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

    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.
    

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

    【讨论】:

    • 就是这样!谢谢!我可以问一下你为什么要设定一个事实,然后才做任务?直接对调试任务进行检查不是更快吗?
    • 不客气!任务中的条件将针对每个节点进行评估,即在示例中,将评估三次,因为存在三个节点(host1、host2、host3)。每个主机都有自己的变量all_hosts_execute_specific_task 的副本。 (您可能想对其进行测试。)。由于run_once: trueset_fact 只运行一次,即在这种情况下,哪个节点实际运行 set_fact 并不重要。所有节点都会收到相同的变量all_hosts_execute_specific_task。答案是否定的,直接在调试任务中检查会使其变慢。
    猜你喜欢
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2022-11-19
    相关资源
    最近更新 更多