Ansible模板中如何正确引用inventory内指定主机的ansible_host
问题说明
需要在Ansible的Jinja2模板中获取inventory定义的服务器IP,用于配置绑定固定IP的监控进程。要求IP仅在inventory中维护,实现一处定义多处复用。本次playbook的执行目标主机并非被引用IP的mqtt-broker节点本身,需要实现按主机名直接匹配对应ansible_host的引用逻辑,不依赖列表索引。
现有配置示例
inventory文件内容:
prod_srv_mqtt: hosts: mqtt-broker-01: ansible_host: 10.10.10.10 mqtt-broker-02: ansible_host: 10.10.10.11
在模板文件my-template.json.j2中最初尝试的引用写法,期望渲染得到ping 10.10.10.10的结果:
ping {{ groups.prod_srv_mqtt.mqtt-broker-01.ansible_host }}
测试过的写法与报错现象
已尝试多种引用语法,测试结果如下:
- 以下写法均无法正常取到IP值
{{ groups.prod_srv_mqtt.mqtt-broker-01 }} {{ hostvars['prod_srv_mqtt'][mqtt-broker-01] }} {{ groups['prod_srv_mqtt'][0] }}:返回结果为mqtt-broker-01,仅能获取主机名,拿不到对应IP{{ groups['prod_srv_mqtt'][0].ansible_host }}:执行直接报错{{ hostvars[groups['prod_srv_mqtt'][0]].ansible_host }}:可以正常返回IP,但依赖列表索引位置,组内主机顺序调整就会取错值,不满足需求{{ hostvars[groups['prod_srv_mqtt']['mqtt-broker-01]].ansible_host' }}:执行抛出异常,通过-vvv参数查看完整栈追踪,报错信息为:ansible.errors.AnsibleUndefinedVariable: 'list object' has no attribute 'mqtt-broker-01'
正确实现方法
报错核心原因:groups['组名']的返回值是该组下所有主机名构成的顺序列表,不是主机名到主机变量的键值对映射,因此无法直接通过主机名作为key从groups中取值。Ansible中所有主机的变量(包括inventory中预定义的ansible_host)统一存储在全局hostvars字典中,字典的key就是inventory中定义的主机名。
按主机名直接取对应IP的正确写法如下,不需要依赖列表索引,也不需要从groups层级嵌套取值:
ping {{ hostvars['mqtt-broker-01'].ansible_host }}
如果需要批量获取该组下所有主机的IP,直接遍历groups返回的主机名列表即可,同样不会受主机顺序变动影响:
{% for mqtt_node in groups['prod_srv_mqtt'] %} # 对应节点{{ mqtt_node }}的监控配置 ping {{ hostvars[mqtt_node].ansible_host }} {% endfor %}
内容的提问来源于stack exchange,提问作者Manticore
相关产品推荐
相关产品推荐

