如何在Ansible的列表中查找列表成员身份

时间:2016-01-29 22:49:38

标签: ansible ansible-playbook

我有一个列表,我想用它来查看列表中的任何成员是否在第二个列表中,并在Ansible when子句中使用它。这可以用单线程完成吗?

- name: task include moar ansible
  include: more_tasks.yaml
  when: any_member_of_this_list in some_other_list

2 个答案:

答案 0 :(得分:3)

这很容易。 Ansible introduced some extra Jinja filters,其中一个是intersect,它返回包含在两个列表中的唯一元素。由于空列表是虚假的而且非空列表是真实的,所以没有比这更多的事情了:

when: any_member_of_this_list | intersect(some_other_list)

答案 1 :(得分:2)

我确信可能有一种方法可以在一个游戏中使用很多花哨的jinja2命令,但是你可能不太可能通过使用自己的自定义插件来疯狂。如果您在保存ansible脚本的文件夹的根目录中创建“filter_plugins”目录,Ansible将自动找到它们。这是我的'filter_plugins / contains_any.py'文件:

# lambda gratefully 'borrowed' from:
# https://stackoverflow.com/questions/10668282/one-liner-to-check-if-at-least-one-item-in-list-exists-in-another-list
contains_any = lambda a, b: any(i in b for i in a)
class FilterModule(object):

    def filters(self):
        return {
            'contains_any': contains_any
        }

在您的剧本中,您可以使用'set_fact'模块根据列表之间是否存在匹配来设置True / False值。当你将'the_list'传递给'contains_any'时,它会自动将'the_list'设置为第一个变量,所以你只需要显式传递'the_other_list':

---
- hosts: localhost
  vars:
   the_list: [jane, bill, janet, suzy]
   the_other_list: [jane, steve, bob, sam, turkey]
  tasks:
  - set_fact:
     any_matches: "{{ the_list | contains_any(the_other_list) }}"
  - debug: msg="Success!"
    when: any_matches

这是输出:

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [set_fact] ****************************************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Success!"
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0   

编辑:感谢this answer的lambda函数