Ansible模板渲染含YAML块标量的变量格式异常,需用何种过滤器修复?
解决Ansible模板中YAML块标量保留问题
问题场景
使用Ansible模板渲染含YAML块标量(|)的环境变量时,块标符号丢失,多行内容缩进混乱,输出不符合预期格式。
相关代码片段
- Playbook变量定义
--- - hosts: localhost vars: docker_compose_projects: - name: project_1 services: - service_name: some_service image: some_image:latest environment: CONFIG: | external_url 'https://www.example.com' external_port '9090' USERNAME: root ROOT_PASSWORD: verysecret tasks: - name: template ansible.builtin.template: src: template.yml.j2 dest: "/home/username/{{ item.name }}" loop: "{{ docker_compose_projects }}"
- 原始模板文件(template.yml.j2)
services: {% for service in item.services %} {{ service.service_name }}: image: {{ service.image }} {% if service.environment is defined %} environment: {% for key, value in service.environment.items() %} {{ key }}: {{ value }} {% endfor %} {% endif %} {% endfor %}
- 实际错误输出
services: some_service: image: some_image:latest environment: CONFIG: external_url 'https://www.example.com' external_port '9090' USERNAME: root ROOT_PASSWORD: verysecret
- 期望输出
services: some_service: image: some_image:latest environment: CONFIG: | external_url 'https://www.example.com' external_port '9090' USERNAME: root ROOT_PASSWORD: verysecret
解决方案
方案1:多行字符串判断+手动缩进
修改template.yml.j2,通过判断值是否为多行字符串,分别处理块标量和普通字符串:
services: {% for service in item.services %} {{ service.service_name }}: image: {{ service.image }} {% if service.environment is defined %} environment: {% for key, value in service.environment.items() %} {% if '\n' in value %} {{ key }}: | {{ value | indent(8) | trim }} {% else %} {{ key }}: {{ value }} {% endif %} {% endfor %} {% endif %} {% endfor %}
- 关键逻辑:用
{% if '\n' in value %}识别多行字符串,输出块标符号|后,通过indent(8)将内容缩进至符合YAML层级的位置,trim移除首尾空白避免多余换行。
方案2:直接使用YAML格式化过滤器
利用ansible.utils.to_yaml过滤器渲染整个environment字典,自动保留YAML格式:
services: {% for service in item.services %} {{ service.service_name }}: image: {{ service.image }} {% if service.environment is defined %} environment: {{ service.environment | ansible.utils.to_yaml(indent=4) | indent(4) }} {% endif %} {% endfor %}
- 关键逻辑:
to_yaml负责生成标准YAML格式,indent(4)确保整体缩进匹配当前层级。
验证结果
两种方案均可让渲染输出完全符合期望的YAML格式,块标符号|被保留,多行内容缩进正确。
内容的提问来源于stack exchange,提问作者C-nan
相关产品推荐
相关产品推荐

