首页 > 解决方案 > 带有特殊变量的 Ansible 查找插件

问题描述

Ansible 查找插件是否能够支持特殊字符?

例子:

vars:
  stage: prod
debug:
  msg: "{{ lookup('?', 'groups.' + stage + '.index(inventory_hostname)') }}"

如果没有,是否仍然可以通过其他方式解决此问题以获取属于某个组的主机的索引stage

感谢您的帮助。

标签: ansible

解决方案


要获取列表中元素的索引,您确实可以index()在 jinja2 中使用,因为您似乎已经发现了。但是没有必要为此使用查找(并且无论如何都没有命名查找?)。要在您的示例中的动态命名组上执行此操作,这给出了。

debug:
  msg: "{{ groups[stage].index(inventory_hostname) }}"

有关语法的更多信息,请参阅有关访问复杂变量的文档。

同时,您应该注意,如果该值不存在于列表中(即主机不存在于组中),此方法将引发错误,并且无法像使用普通未定义变量一样使用default过滤器恢复它。

因此,如果您的目标主机有可能不在stage组中,您应该添加一些额外的 jinja2 表达式以确保您始终获得没有错误的值(例如,如果主机不在列表中,则返回 -1):

debug:
  msg: "{%if machine in groups[stage] %}{{ groups[stage].index(inventory_hostname) }}{% else %}-1{% endif %}"

既然你提到了查找,还有一个使用indexed_items插件的解决方案。这里的想法是将组列表转换为 ( <index>, <host>) 元组列表,搜索具有等于当前主机的第二个元素的元组,只保留结果的第一个元素,如果结果为空,则默认为虚拟元组并打印保留元组的第一个元素:

debug:
  msg: "{{ (lookup('indexed_items', groups[stage]) | selectattr('1', 'eq', inventory_hostname) | first | default([-1]))[0] }}"

推荐阅读