我如何获得 Ansible 中的子组列表?

How can I get a list of child groups in Ansible?

我有一个清单文件,如下所示:

[master]
host01

[nl]
host02

[us]
host03

[satellites:children]
nl
us

如何获取以 satellites 作为父组的组列表?

我正在寻找与此类似的解决方案:

- debug: msg="{{ item }}"
  with_items: "{{ groups['satellites:children'] }}"

更新:

我能想到的唯一解决方案是:

- debug: {{ item }}
  with_items: "{{ groups }}"
  when: item != "master" and item != "satellites" and item != "all" and item != "ungrouped"

但这不是很灵活。

您可以尝试以下方法:

  vars:
    parent: 'satellites'
  tasks:
      # functional style
    - debug: msg="{{hostvars[item].group_names | select('ne', parent) | first}}"
      with_items: "{{groups[parent]}}"
      # set style
    - debug: msg="{{hostvars[item].group_names | difference(parent) | first}}"
      with_items: "{{groups[parent]}}"

此外,select('ne', parent) 可与 reject('equalto', parent) 互换,具体取决于您更易读的内容。

链接:
set theory operator
select and reject filters


根据评论更新了答案。灵感来自 .

vars:
    parent: 'satellites'
tasks:
    - name: build a subgroups list
      set_fact: subgroups="{{ ((subgroups | default([])) + hostvars[item].group_names) | difference(parent) }}"
      with_items: "{{groups[parent]}}"

    - debug: var=subgroups

输出:

 "subgroups": [
        "nl",
        "us"
    ]

还有另一种方法,您可以使用 bash 命令将文件作为文本文件处理,例如 awk

如果文件的内容类似于

cat /tmp/test.ini
[group1]
host1
host2

[group2]
host3
host4

[first_two_groups:children]
group1
group2

[group3]
host5
host6

[group4]
host7
host8

当文件有 Linux EOL:

时,你可以使用这样的命令
awk "/first_two_groups\:children/,/^$/" /tmp/test.ini | grep -v children
group1
group2

查找其子项的组称为 first_two_groups,它可以在文件中的任何位置。只要在组定义之后有空行用作结束 awk 流的锚点,命令就可以工作。我认为大多数人会在 ansible 清单文件中添加空行以提高可读性,我们可以利用这一事实。

如果文件恰好有Windows EOL那么命令是

awk "/first_two_groups\:children/,/^[\r]$/" /tmp/test.ini | grep -v children

像这样的 ansible 示例:

- name: get group children
  shell: awk "/first_two_groups\:children/,/^$/" /tmp/test.ini | grep -v children
  register: chlldren

#returns list of the children groups to loop through later 
- debug: var=children.stdout_lines

以上内容尚未经过全面测试,但如果出现问题,则最多可能是 shell 模块中特殊字符的转义。请记住 - 当您在 ansible shell 模块中传递特殊字符时,如冒号使用 jinja 扩展 - 而不是 : 使用 {{ ':' }} 此外,为了保持一致的 bash 行为,建议通过在任务结束时添加明确地传递可执行文件

  args:
    executable: /bin/bash