Ansible循环解析fact变量异常:仅获键名而非完整DNS详情
如何在Ansible中循环解析fact变量获取完整DNS详情
问题场景
我编写了如下Ansible Playbook,希望通过循环解析fact变量获取完整的DNS详情,但实际执行后仅输出了键名,尝试使用过滤器解析还出现报错。
原始Playbook
- hosts: rhel tasks: - name: 获取DNS信息 setup: filter: ansible_dns register: dns - debug: var=dns - name: 调试DNS详情 debug: msg: "DNS ====> {{ item }}" with_items: "{{ dns.ansible_facts }}"
执行输出
$ ansible-playbook -i inv get_facts.yaml PLAY [rhel] ******************************************************************************************************************************************** TASK [Gathering Facts] ********************************************************************************************************************************* ok: [rhel8] TASK [获取DNS信息] ***************************************************************************************************************************************** ok: [rhel8] TASK [debug] ******************************************************************************************************************************************* ok: [rhel8] => { "dns": { "ansible_facts": { "ansible_dns": { "nameservers": [ "172.31.0.2" ], "search": [ "ap-south-1.compute.internal" ] } }, "changed": false, "failed": false } } TASK [调试DNS详情] ******************************************************************************************************************************* ok: [rhel8] => (item=ansible_dns) => { "msg": "DNS ====> ansible_dns" } PLAY RECAP ********************************************************************************************************************************************* rhel8 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
期望输出
希望第三个任务输出完整的DNS结构:
"ansible_dns": { "nameservers": [ "172.31.0.2" ], "search": [ "ap-south-1.compute.internal" ] }
尝试的错误方法及报错
尝试使用{{ item | from_json | json_query('ansible_dns') }}解析,出现以下错误:
TASK [调试DNS详情] ******************************************************************************************************************************* fatal: [rhel8]: FAILED! => {"msg": "the field 'args' has an invalid value ({'msg': \"DNS ====> {{ item | from_json | json_query('ansible_dns') }}\"}), and could not be converted to an dict.The error was: Expecting value: line 1 column 1 (char 0) The error appears to be in '/home/vikram/mybooks/get_facts.yaml': line 7, column 15, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: - debug: var=dns ^ here There appears to be both 'k=v' shorthand syntax and YAML in this task. Only one syntax may be used. "}
解决方案
方法1:使用dict2items过滤器遍历键值对
with_items遍历字典时默认只返回键名,使用dict2items可将字典转换为包含key和value的键值对列表,从而获取完整的DNS数据:
- name: 调试DNS详情 debug: msg: "DNS ====> {{ item.key }}: {{ item.value }}" loop: "{{ dns.ansible_facts | dict2items }}"
如果只需要输出值部分,直接使用{{ item.value }}即可。
方法2:直接引用目标变量(无需循环)
如果仅需要ansible_dns的内容,完全不需要循环,直接引用即可:
# 直接输出变量结构 - name: 调试DNS详情 debug: var: dns.ansible_facts.ansible_dns # 格式化输出 - name: 调试DNS详情 debug: msg: "DNS ====> {{ dns.ansible_facts.ansible_dns }}"
错误原因说明
- 遍历字典的默认行为:
with_items遍历字典时,默认返回字典的键名而非键值对,因此原Playbook只输出了ansible_dns。 - 过滤器使用错误:
from_json用于解析JSON格式的字符串,但item是字符串类型的键名,并非JSON字符串,因此会出现解析错误。 - 语法混合问题:报错中提到的语法冲突是因为任务混合了
k=v简写(debug: var=dns)和YAML格式,建议统一使用标准YAML格式:
- debug: var: dns
内容的提问来源于stack exchange,提问作者200_OK
相关产品推荐
相关产品推荐

