如何通过测试ansible playbook中的'lookup(';dig';,…)'是否相等,习惯性地筛选主机名列表

如何通过测试ansible playbook中的'lookup(';dig';,…)'是否相等,习惯性地筛选主机名列表,ansible,jinja2,Ansible,Jinja2,为了从给定列表中找到(尚未)解析为inventory\u主机名ip地址的主机名,我在得到了一些帮助后,想出了这个小“美人”: 这是在我第一次尝试使用更惯用的过滤器和ansible/jinja2模板测试之后,失败了,比如 {{ hosts | reject( "eq", ... ) }} 但是,我无法确定如何对其进行参数化,以便我能够正确地在那里进行查找(“dig”,…)调用 我试着首先通过映射过滤器对主机数组进行管道传输,但这失败了,因为显然,查找不是jinja2的过滤器 {{ hosts

为了从给定列表中找到(尚未)解析为
inventory\u主机名
ip地址的主机名,我在得到了一些帮助后,想出了这个小“美人”:

这是在我第一次尝试使用更惯用的过滤器和ansible/jinja2模板测试之后,失败了,比如

{{ hosts | reject( "eq", ...  ) }}
但是,我无法确定如何对其进行参数化,以便我能够正确地在那里进行
查找(“dig”,…)
调用

我试着首先通过
映射
过滤器对
主机
数组进行管道传输,但这失败了,因为显然,
查找
不是jinja2的过滤器

{{ hosts | map( "lookup", "dig" ) | ... }}
jinja2.exceptions.TemplateRuntimeError:没有名为“lookup”的筛选器

我现在所拥有的一切都很有效;但事实证明,这是一个相当脆弱的解决方案。也就是说,对
hosts\u failed
模板定义的最轻微的不小心更改似乎能够改变ansible/jinja是将其结果解释为我想要的数组,还是仅仅将其解释为字符串(上面的
debug
任务中的
|列表
将很快揭示其中的内容)

因此,问题是,是否有一种更简单、更好、更干净、更稳健的方法来实现这一点



想要这样做的背景是为主机名列表断言,在为其提供
certbot
SSL证书之前,这些主机名都解析到正在构建的站点,如果没有,则报告没有解析的主机名。

我可能会使用循环任务,而不是一些奇特的模板解决方案。例如:

---
- hosts: localhost
  gather_facts: false
  vars:
    hosts:
      - google.com
      - myhost.example.com
      - hackaday.com
    addr: 192.168.1.13
  tasks:
    - name: "find hosts that don't map to {{ addr }}"
      set_fact:
        failed_hosts: "{{ failed_hosts|default([]) + [item] }}"
      when: addr != lookup("dig", item)
      loop: "{{ hosts }}"

    - debug:
        var: failed_hosts
这将产生如下输出:

PLAY [localhost] *************************************************************************************************************************************************************

TASK [find hosts that don't map to 192.168.1.13] ******************************************************************************************************************************
ok: [localhost] => (item=google.com)
skipping: [localhost] => (item=myhost.example.com) 
ok: [localhost] => (item=hackaday.com)

TASK [debug] *****************************************************************************************************************************************************************
ok: [localhost] => {
    "failed_hosts": [
        "google.com",
        "hackaday.com"
    ]
}

PLAY RECAP *******************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

在这里,我在
localhost
上运行任务,并显式设置目标地址,但这部分是因为我不清楚您想要完成什么。如果有必要,如果您能稍微澄清一下您的问题,我们当然可以重新设计此解决方案。

我的印象是,与变量相反,一旦设置了事实,就无法改变事实,但如果这样做有效,是的,循环任务至少将是一种更健壮的方法。主机名列表来自
nginx-T
config,目标是在为其提供
certbot
SSL证书之前声明它们都解析到正在构建的主机,如果没有,报告那些没有改变的。注意你没有改变一个事实。您将重复创建一个新值,该值将覆盖以前的值。
PLAY [localhost] *************************************************************************************************************************************************************

TASK [find hosts that don't map to 192.168.1.13] ******************************************************************************************************************************
ok: [localhost] => (item=google.com)
skipping: [localhost] => (item=myhost.example.com) 
ok: [localhost] => (item=hackaday.com)

TASK [debug] *****************************************************************************************************************************************************************
ok: [localhost] => {
    "failed_hosts": [
        "google.com",
        "hackaday.com"
    ]
}

PLAY RECAP *******************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0