You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 }}"

错误原因说明

  1. 遍历字典的默认行为:with_items遍历字典时,默认返回字典的键名而非键值对,因此原Playbook只输出了ansible_dns。
  2. 过滤器使用错误:from_json用于解析JSON格式的字符串,但item是字符串类型的键名,并非JSON字符串,因此会出现解析错误。
  3. 语法混合问题:报错中提到的语法冲突是因为任务混合了k=v简写(debug: var=dns)和YAML格式,建议统一使用标准YAML格式:
- debug:
    var: dns

内容的提问来源于stack exchange,提问作者200_OK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 09:32:04