Ansible 从 jinja 文件写入文件
Ansible write on file from jinja file
我想启动一个应用程序:
command=/usr/bin/toto --config /var/toto/conf1.json /var/toto/conf2.json /var/toto/conf3.json
配置文件位于 /var/toto 目录
task.yml
- name: Ansible find file
find:
paths: "/var/toto"
register: found_files
- name: print files
debug:
msg: "{{ found_files['files'] | map(attribute='path') | map('regex_replace','^.*/(.*)$','\1') | list }}"
register: file_name
- name: Create the Jinja2 based template
template:
src: "etc/control/config.conf.j2"
dest: "/etc/control/config.conf"
with_dict: "{{ file_name }}"
config.conf.j2
command=/usr/bin/toto --config {% for item in file_name %} /var/toto/{{ item }} {% endfor %}
但是,我的档案里有这个
/etc/control/config.conf
command=/usr/bin/toto --config /var/opt/msg /var/opt/failed /var/opt/changed
varfile_name :
"msg": [ "conf1.json", "conf2.json", "conf3.json"
]
您正在遍历 file_name
中的字典,这是一个任务结果。如果您将其打印出来,您会发现它包含如下内容:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
"file_name": {
"changed": false,
"failed": false,
"msg": [
"file1",
"file2",
"file3"
]
}
}
因此,当您使用 for item in file_name
对其进行迭代时,您将迭代顶级键(changed
、failed
、msg
)。
但这完全是错误的做法。您从不使用 debug
模块来创建变量;这就是 set_fact
的用途。你想要这样的东西:
- name: build list of files
set_fact:
file_name: "{{ found_files['files'] | map(attribute='path') | map('regex_replace','^.*/(.*)$','\1') | list }}"
- name: Create the Jinja2 based template
template:
src: "config.conf.j2"
dest: "config.conf"
在set_fact
任务之后,变量file_name
将包含一个
文件名列表。
看起来您正在使用该正则表达式来获取基本名称
在您的 find
任务中找到的文件数量。有一个 basename
过滤器
可以用更少的复杂性做到这一点:
- name: print files
set_fact:
file_name: "{{ found_files['files'] | map(attribute='path') | map('basename') | list }}"
- name: Create the Jinja2 based template
template:
src: "config.conf.j2"
dest: "config.conf"
这是我用来在本地测试的剧本:
- hosts: localhost
gather_facts: true
tasks:
- name: find files
find:
paths: /tmp/example
register: found_files
- name: print files
set_fact:
file_name: "{{ found_files['files'] | map(attribute='path') | map('basename') | list }}"
- name: Create the Jinja2 based template
template:
src: "config.conf.j2"
dest: "config.conf"
在此之前 运行我 运行:
mkdir /tmp/example
touch /tmp/exampe/file{1,2,3}
这会生成一个 config.conf 文件,如下所示:
command=/usr/bin/toto --config /var/toto/file3 /var/toto/file2 /var/toto/file1
我想启动一个应用程序:
command=/usr/bin/toto --config /var/toto/conf1.json /var/toto/conf2.json /var/toto/conf3.json
配置文件位于 /var/toto 目录
task.yml
- name: Ansible find file
find:
paths: "/var/toto"
register: found_files
- name: print files
debug:
msg: "{{ found_files['files'] | map(attribute='path') | map('regex_replace','^.*/(.*)$','\1') | list }}"
register: file_name
- name: Create the Jinja2 based template
template:
src: "etc/control/config.conf.j2"
dest: "/etc/control/config.conf"
with_dict: "{{ file_name }}"
config.conf.j2
command=/usr/bin/toto --config {% for item in file_name %} /var/toto/{{ item }} {% endfor %}
但是,我的档案里有这个
/etc/control/config.conf
command=/usr/bin/toto --config /var/opt/msg /var/opt/failed /var/opt/changed
varfile_name :
"msg": [ "conf1.json", "conf2.json", "conf3.json"
]
您正在遍历 file_name
中的字典,这是一个任务结果。如果您将其打印出来,您会发现它包含如下内容:
TASK [debug] *********************************************************************************************************************************************************************************
ok: [localhost] => {
"file_name": {
"changed": false,
"failed": false,
"msg": [
"file1",
"file2",
"file3"
]
}
}
因此,当您使用 for item in file_name
对其进行迭代时,您将迭代顶级键(changed
、failed
、msg
)。
但这完全是错误的做法。您从不使用 debug
模块来创建变量;这就是 set_fact
的用途。你想要这样的东西:
- name: build list of files
set_fact:
file_name: "{{ found_files['files'] | map(attribute='path') | map('regex_replace','^.*/(.*)$','\1') | list }}"
- name: Create the Jinja2 based template
template:
src: "config.conf.j2"
dest: "config.conf"
在set_fact
任务之后,变量file_name
将包含一个
文件名列表。
看起来您正在使用该正则表达式来获取基本名称
在您的 find
任务中找到的文件数量。有一个 basename
过滤器
可以用更少的复杂性做到这一点:
- name: print files
set_fact:
file_name: "{{ found_files['files'] | map(attribute='path') | map('basename') | list }}"
- name: Create the Jinja2 based template
template:
src: "config.conf.j2"
dest: "config.conf"
这是我用来在本地测试的剧本:
- hosts: localhost
gather_facts: true
tasks:
- name: find files
find:
paths: /tmp/example
register: found_files
- name: print files
set_fact:
file_name: "{{ found_files['files'] | map(attribute='path') | map('basename') | list }}"
- name: Create the Jinja2 based template
template:
src: "config.conf.j2"
dest: "config.conf"
在此之前 运行我 运行:
mkdir /tmp/example
touch /tmp/exampe/file{1,2,3}
这会生成一个 config.conf 文件,如下所示:
command=/usr/bin/toto --config /var/toto/file3 /var/toto/file2 /var/toto/file1