每个唯一事实值仅运行一次ansible任务

时间:2019-02-21 03:14:45

标签: ansible ansible-facts

我有一个动态清单,为每个主机分配一个“事实”,称为“ cluster_number”。

群集号事先未​​知,但是有一个或多个主机分配了相同的编号。该清单包含数百个主机和2-3个唯一的群集号。

我想为清单中的所有主机运行一个任务,但是我希望每个共享相同“ cluster_number”值的主机组仅执行一次任务。每个组选择哪个特定主机都没有关系。

我觉得应该采用一种比较简单的方法来做到这一点,但是却不知道该怎么做。我看过group_by,when,loop,delegate_to等。但是还没有成功。

2 个答案:

答案 0 :(得分:1)

一个选择是

  • group_by cluster_number
  • run_once遍历集群编号
  • 并从每个组中选择第一位主持人。

例如给出 hosts

type Product {
   test: String
}

type Query {
   getProducts: [Product] // Query returns an array of products
}

以下剧本

[test]
test01 cluster_number='1'
test02 cluster_number='1'
test03 cluster_number='1'
test04 cluster_number='1'
test05 cluster_number='1'
test06 cluster_number='2'
test07 cluster_number='2'
test08 cluster_number='2'
test09 cluster_number='3'
test10 cluster_number='3'
[test:vars]
cluster_numbers=['1','2','3']

给予

- hosts: all
  gather_facts: no
  tasks:
    - group_by: key=cluster_{{ cluster_number }}
    - debug: var=groups['cluster_{{ item }}'][0]
      loop:  "{{ cluster_numbers }}"
      run_once: true

要在目标include_tasks(而不是上面的循环中的调试)和delegate_to目标上执行任务

> ansible-playbook test.yml | grep groups
"groups['cluster_1'][0]": "test01", 
"groups['cluster_2'][0]": "test06", 
"groups['cluster_3'][0]": "test09",

注意:从清单中收集列表集群编号

- set_fact:
    my_group: "cluster_{{ item }}"
- command: hostname
  delegate_to: "{{ groups[my_group][0] }}"

答案 1 :(得分:1)

如果您不介意播放混乱的日志,请采取以下方法:

- hosts: all
  gather_facts: no
  serial: 1
  tasks:
    - group_by:
        key: "single_{{ cluster_number }}"
      when: groups['single_'+cluster_number] | default([]) | count == 0

- hosts: single_*
  gather_facts: no
  tasks:
    - debug:
        msg: "{{ inventory_hostname }}"

serial: 1在第一部剧集中至关重要,它需要为每个主机重新评估when声明。

第一次播放后,每个群集将有N个组,其中只有一个主机。