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 对其进行迭代时,您将迭代顶级键(changedfailedmsg)。

但这完全是错误的做法。您从不使用 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