Ansible/Jinja2模板编译异常:子模板顶部需加空行才可运行
Ansible/Jinja2 模板渲染类型错误:
dict 和 str 无法执行 += 操作 问题场景
使用lookup('template', ...)加载模板时,必须在子模板顶部添加空行才能避免类型错误;改用template内置模块则无此问题,报错核心提示为unsupported operand type(s) for +=: 'dict' and 'str'。
完整报错信息
TASK [debug template without blank line FAILED] *********************************************** fatal: [localhost]: FAILED! => {"msg": "An unhandled exception occurred while templating '{{ lookup('template', './template_without_blank_line.yml.j2') }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while running the lookup plugin 'template'. Error was a <class 'ansible.errors.AnsibleError'>, original message: Unexpected templating type error occurred on (---\ndata: |\n{% filter indent(width=2, first=true) %}\n{% include 'sub_template_without_blank_line.json.j2' %}\n{% endfilter %}\n): unsupported operand type(s) for +=: 'dict' and 'str'. unsupported operand type(s) for +=: 'dict' and 'str'. Unexpected templating type error occurred on (---\ndata: |\n{% filter indent(width=2, first=true) %}\n{% include 'sub_template_without_blank_line.json.j2' %}\n{% endfilter %}\n): unsupported operand type(s) for +=: 'dict' and 'str'. unsupported operand type(s) for +=: 'dict' and 'str'"}
相关文件内容
Playbook
--- - hosts: localhost gather_facts: no connection: local tasks: - debug: var: rendered_template vars: rendered_template: "{{ lookup('template', './template_without_blank_line.yml.j2') }}" name: debug template without blank line FAILED
主模板 template_without_blank_line.yml.j2
--- json_data: | {% filter indent(width=2, first=true) %} {% include 'sub_template_without_blank_line.json.j2' %} {% endfilter %}
子模板 sub_template_without_blank_line.json.j2
{ "fruit": "Banana" }
原因解析
lookup('template')插件会自动尝试将渲染后的内容解析为YAML/JSON结构化数据,而template模块仅负责输出纯文本。当子模板没有顶部空行时,indent过滤器处理后的JSON内容会直接衔接YAML的|块起始位置,导致Ansible误将整体渲染结果识别为字典与字符串混合的类型,触发类型运算冲突。添加空行后,块内内容被正确识别为纯字符串,避免了类型判断错误。
解决方案
有两种可靠解决方式:
- 方式1:给子模板顶部添加空行
修改sub_template_without_blank_line.json.j2:{ "fruit": "Banana" } - 方式2:改用
template模块替代lookup('template')
调整Playbook任务:- name: debug template with template module template: src: ./template_without_blank_line.yml.j2 dest: ./rendered_output.yml
内容的提问来源于stack exchange,提问作者MARC GIRARD
相关产品推荐
相关产品推荐

