Ansible模板循环问题:如何按文件名生成对应内容的配置文件
解决Ansible生成对应内容配置文件的问题
问题场景
现有Ansible变量、模板及任务配置如下:
变量定义
my_list: - filename: something.conf content: hello - filename: else.conf content: asdf
模板文件 conf.j2
{% for item in my_list %} {{ item.content }} {% endfor %}
执行任务
- name: set config template: src: conf.j2 dest: "/tmp/{{ item.filename }}" loop: "{{ my_list }}"
执行后发现/tmp/something.conf和/tmp/else.conf内容完全相同,都包含了所有content的值。需要实现每个文件名对应自己的content内容,且后续my_list新增条目时能自动处理。
问题原因
任务里已经通过loop遍历my_list,为每个条目生成独立文件,但模板又重复遍历了整个my_list,导致每个文件都写入了所有条目的content,所以所有文件内容一致。
解决方案
两种方式都能实现需求,推荐第一种更简洁的方案:
方案1:修改模板(推荐)
既然任务已经在循环处理每个item,模板渲染时直接引用当前循环的item变量即可,无需再遍历整个列表。修改后的conf.j2:
{{ item.content }}
这样每次渲染模板时,只会输出当前循环条目的content,生成的每个文件内容都会对应自己的配置值,后续my_list新增条目时,任务会自动生成对应文件。
方案2:模板添加if判断(不推荐)
如果一定要保留模板的循环逻辑,可以在模板里加if判断,只输出与当前目标文件名匹配的内容。修改后的conf.j2:
{% for entry in my_list %} {% if entry.filename == item.filename %} {{ entry.content }} {% endif %} {% endfor %}
这种方式虽然能达成目标,但做了双重遍历,效率不如方案1,没必要多此一举。
内容的提问来源于stack exchange,提问作者Kevin C
相关产品推荐
相关产品推荐

