如何在Ansible模板中提取指定主机组所有主机的ansible_fqdn值?
Ansible 提取主机组内所有主机 FQDN 的正确方案
核心问题原因
- 默认
setup模块/gather_facts仅收集当前play目标主机的事实,你需要读取组内所有主机的字段时,未提前对全组执行事实收集,未收集的主机对应字段在hostvars中不存在。 - 你尝试提取
facter_networking下的字段时,未将键名用引号包裹,Jinja 会将facter_networking解析为变量而非字符串类型的键,导致取值失败。
解决步骤
1. 调整 playbook 结构,提前完成全组事实收集
先新增一个空play专门收集所有目标主机的事实,再执行模板生成任务:
# 先收集所有需要用到的主机的事实 - name: 收集全组主机事实 hosts: all # 可替换为你实际的目标主机组名 gather_facts: yes tasks: [] # 再执行原有业务任务 - name: 生成pgpass配置文件 hosts: your_target_hosts # 替换为你实际要部署的主机组 tasks: - name: Create .pgpass template: src: pgpass.j2 dest: /home/postgres/.pgpass owner: postgres group: postgres mode: 0600
2. 模板中使用正确的取值写法
方案A:使用Ansible原生收集的ansible_fqdn(无需额外依赖facter)
{% for host in groups.all %} {# 加default避免个别主机事实收集异常导致任务失败,优先级:fqdn > 配置的ansible_host > inventory主机名 #} {{ hostvars[host].ansible_fqdn | default(hostvars[host].ansible_host, true) | default(host, true) }} {% endfor %}
方案B:使用facter返回的facter_networking下的字段
前提是所有目标主机已安装facter工具,且事实收集正常:
{% for host in groups.all %} {{ hostvars[host]['facter_networking']['fqdn'] }} {# 等效点式写法:{{ hostvars[host].facter_networking.fqdn }} #} {% endfor %}
内容的提问来源于stack exchange,提问作者nbari
相关产品推荐
相关产品推荐

