Ansible脚本执行报set类型对象无法JSON序列化如何解决
错误根因
Ansible的unique过滤器仅针对列表类型输入返回列表,若传入字符串、数字等非列表非None值,会直接返回set类型,而set无法被JSON序列化,因此触发报错。你之前用字符串替换把None转空列表的方案属于临时适配,没有覆盖非列表有效值的场景,所以遇到Name: D的配置就会出错。
修复方案
不需要提前做replace字符串替换,直接在循环的变量定义处增加类型判断逻辑,统一把source、dest的值标准化为列表后再去重,即可覆盖所有场景:
- set_fact: out: "{{ out|d([]) + [{'Name': item.Name, 'source': _src, 'dest': _dst}] }}" loop: "{{ output }}" vars: # 统一标准化source为列表类型 _src_list: >- {% if item.source is iterable and item.source is not string and item.source is not mapping %} {{ item.source }} {% elif item.source is none %} [] {% else %} [{{ item.source }}] {% endif %} _src: "{{ _src_list | unique }}" # 统一标准化dest为列表类型 _dst_list: >- {% if item.dest is iterable and item.dest is not string and item.dest is not mapping %} {{ item.dest }} {% elif item.dest is none %} [] {% else %} [{{ item.dest }}] {% endif %} _dst: "{{ _dst_list | unique }}" - debug: var: out
逻辑说明
- 首先判断输入值是否为「纯列表类型」:可迭代但排除字符串、字典类型,符合条件则直接使用原值
- 若输入为None,直接返回空列表,替代之前的字符串替换方案,不会误伤包含
None字符串的合法值 - 其他非列表的有效值(比如Name:D配置中的字符串
"1.2"、"x")会被包装为单元素列表,再调用unique过滤器会返回列表而非set,彻底解决序列化报错问题
处理后所有配置的输出结果均符合预期:
- Name:A的source去重后为
["a", "b", "c"],dest去重后为["x", "y", "z"] - Name:B的source去重后为
["a", "b", "c"],dest去重后为["x.c", "y", "z", "x"] - Name:C的source和dest均为
[] - Name:D的source为
["1.2"],dest为["x"]
内容的提问来源于stack exchange,提问作者nauto
相关产品推荐
相关产品推荐

