for循环中的Ansible Jinja2模板条件

for循环中的Ansible Jinja2模板条件,ansible,jinja2,Ansible,Jinja2,我有一个jinja2模板,用于打印ec2实例的IP地址(标记区域:au): 我的问题是,我一辈子都无法解决如何只包括一个组中存在的主机而不包括另一个组中存在的主机(但是每个主机可能位于两个或多个组中),例如,在python中,以下工作: ( (a in list) and ( a not in list2) ) 但是,以下情况并非如此: {% for (host in groups['tag_region_au']) and (host not in groups['tag_state_liv

我有一个jinja2模板,用于打印ec2实例的IP地址(标记区域:au):

我的问题是,我一辈子都无法解决如何只包括一个组中存在的主机而不包括另一个组中存在的主机(但是每个主机可能位于两个或多个组中),例如,在python中,以下工作:

( (a in list) and ( a not in list2) )
但是,以下情况并非如此:

{% for (host in groups['tag_region_au']) and (host not in groups['tag_state_live']) %}

您知道如何只包含一个组中存在的主机和另一个组中不存在的主机吗?

在这种情况下,您可以使用内置的
组名称
变量
group\u names
变量是当前主机所属的所有组的列表

我的
主机
文件:

[tag_region_au]
host1 
host2
host3

[tag_state_live]
host2
host3
host4
我的模板文件
test.j2

{% for host in groups['tag_region_au'] %}
{% if hostvars[host]['group_names']|length == 1 %}
{{ host }} - {{ hostvars[host]['group_names'] }}
{% endif %}
{% endfor %}
hostvars
是一个dict,其键是ansible hostname,值是dict将变量名映射到值<代码>长度是jinja筛选器返回列表中项目的数量

结果:

host1 - ['tag_region_au']
如果将
==
更改为
,结果是:

host2 - ['tag_region_au', 'tag_state_live']
host3 - ['tag_region_au', 'tag_state_live']
更新: 要检查A组中的主机而不检查B组中的主机,您可以使用
difference
filter。语法是
{{list1|difference(list2)}

以下是示例模板:

{% for host in groups['tag_region_au']|difference(groups['tag_state_live']) %}
{{ host }}
{% endfor %}

结果是:
host1

如果你不介意为模板制作东西开始一个新的游戏,那么一个非常干净的方法就是在游戏目标中使用一个组表达式(这正是他们的目的)。例如:

- hosts: tag_region_au:!tag_state_live
  tasks:
 - template: (bla)

然后在您的模板中,您可以引用
play\u hosts
var来获取筛选的主机列表。

虽然这从技术上回答了这个问题,但如果主机所在的第三个或更多组OP不介意让主机参与,那么它将失败。如果你能明确地说,主机应该在一个特定的组中,而不是在另一个特定的组中,这将是一种有趣的方法。我不知道你在说什么。你能解释一下吗?您可以使用
{%if%}
检查您想要的任何内容。感谢您的回答@nghnam,但是每个主机在任何时候都在两个或多个组中。我真的需要一份声明,上面写着“在a组,而不是在b组”,谢谢你的回答Matt和@nghnam-我将测试并选择一个答案。
- hosts: tag_region_au:!tag_state_live
  tasks:
 - template: (bla)