如何在Ansible的Jinja模板中生成正确的列表式YAML结果
问题
给定如下列表:
list: - foo - bar
使用Jinja模板:
{% for key in list %} results: - "{{ key }}" {% endfor %}
生成的输出会重复results:字段:
results: - foo results: - bar
需要修改模板,得到如下正确输出:
results: - foo - bar
要求不使用Ansible的lineinfile模块,复刻Helm中range过滤器的效果(Helm示例如下):
results: {{- range .Values.list }} - {{ . }} {{- end }}
尝试过用join过滤器,但生成的结果存在语法问题:
模板:
results: - "{{ list | join('\n- ') }}"
错误输出:
results: - "foo - bar"
解决方法
方法一:将results:移到循环外部
这是最直接的方式,和Helm的range逻辑完全一致:
results: {% for key in list %} - "{{ key }}" {% endfor %}
如果需要消除多余的空行,可以使用Jinja的空白控制标记-来修剪空格:
results: {%- for key in list %} - "{{ key }}" {%- endfor %}
这样生成的输出会更紧凑,没有循环前后的空行。
方法二:利用to_nice_yaml过滤器直接渲染列表
如果不想写循环,也可以用Ansible的to_nice_yaml过滤器格式化列表,再调整缩进:
results: {{ list | to_nice_yaml(indent=4) | indent(4) }}
这个方法会自动把列表转换成YAML格式,indent(4)用来匹配外层的缩进,确保格式正确。
为什么原模板和join方法不行?
- 原模板的问题是把
results:放在了循环内部,导致每个列表项都会重新输出一次字段名,进而生成重复的results:块。 join方法的问题是把所有列表项拼接成了一个字符串,被包裹在同一个YAML字符串引号内,不符合YAML列表的语法要求。
内容的提问来源于stack exchange,提问作者TJ Zimmerman
相关产品推荐
相关产品推荐

