使用 var 文件中的值从同一个 Jinja2 模板创建多个文件

Create multiple files from the same Jinja2 Template using values from a var file

提问人:Arun Karthick V 提问时间:8/31/2023 最后编辑:ZeitounatorArun Karthick V 更新时间:9/1/2023 访问量:165

问:

我需要创建多个文件,其中包含 Jinja2 模板文件 (server.properties) 的 var 文件中声明的值。我已经尝试了已知的方法来实现文件生成,但问题只是第一个变量更改。其他文件不会反映到此模板中,但文件创建得很完美。我在这篇文章中附加了必要的文件。

Main.yml

---
- name: Create server properties files
  hosts: localhost
  become: yes
  become_user: root
  gather_facts: true
  vars:
    t_file: server.properties
    t_dir: /path/to/save/newfiles
  tasks:
    - name: Include vars file
      include_vars:
        file: common.yml
        name: common

    - name: Creating template file - server.properties.j2
      template:
        src: "{{ t_file }}"
        dest: 'server.properties.j2'

common.yml

---
server:
  - server_no: 1
  - server_no: 2
node_id:
  - node_id: 1
  - node_id: 2
cqvoters:
  - cq_voters: [email protected]:8080,[email protected]:8081,[email protected]:8082
  - cq_voters: [email protected]:8080,[email protected]:8081,[email protected]:8082
listeners:
  - listeners: SASL_SSL://web.example.com:18080,CONTROLLER://web.example.com:8080
  - listeners: SASL_SSL://web.example.com:18081,CONTROLLER://web.example.com:8081
advertised:
  - advertised_listeners: SASL_SSL://web.example.com:18080
  - advertised_listeners: SASL_SSL://web.example.com:18081
log_dir:
  - log_dir: /tmp/server1/kraft-combined-logs
  - log_dir: /tmp/server2/kraft-combined-logs

server.properties:

node.id= "{{ node_id }}"
controller.quorum.voters= "{{ cqvoters }}"
############################# Socket Server Settings #############################
listeners= "{{ listeners }}"
advertised.listeners= "{{ advertised }}"
############################# Log Basics #############################
log.dirs= "{{ log_dir }}"

根据上面给出的内容,我需要创建 2 个文件(即 和 ) 替换为 ,例如,作为示例,最终输出应为:server.propertiesserver1.propertiesserver2.propertiescommon.ymlserver1.properties

node.id= 1
controller.quorum.voters= [email protected]:8080,[email protected]:8081,[email protected]:8082
Socket Server Settings #############################
listeners= SASL_SSL://web.example.com:18080,CONTROLLER://web.example.com:8080
advertised.listeners= SASL_SSL://web.example.com:18080
Log Basics #############################
log.dirs= /tmp/server1/kraft-combined-logs
ansible jinja2 ansible模板

评论

1赞 Zeitounator 9/1/2023
以上没有实现任何循环,也没有显示任何在 var 文件中使用不同值的尝试。在这里,你应该展示你诚实地尝试过的东西。虽然了解您的确切问题很明显,但对于您的下一个问题,请提供一个正确的最小可重现示例
1赞 Zeitounator 9/1/2023
你是在做同样的功课,还是这只是百万分之一的巧合?

答:

1赞 Zeitounator 9/1/2023 #1

你用一个不适应的数据结构让你的生活变得艰难。这是一个最小的例子,有一个更好的例子来实现你的总体目标。适应您的确切需求。

项目结构:

$ tree
.
├── playbook.yml
├── templates
│   └── server.properties.j2
└── vars
    └── common.yml

2 directories, 3 files

vars/common.yml:

---
properties_by_nodes:
  - node_id: 1
    cqvoters: [email protected]:8080,[email protected]:8081,[email protected]:8082
    listeners: SASL_SSL://web.example.com:18080,CONTROLLER://web.example.com:8080
    advertised: SASL_SSL://web.example.com:18080
    log_dir: /tmp/server1/kraft-combined-logs
  - node_id: 2
    cqvoters: [email protected]:8080,[email protected]:8081,[email protected]:8082
    listeners: SASL_SSL://web.example.com:18081,CONTROLLER://web.example.com:8081
    advertised: SASL_SSL://web.example.com:18081
    log_dir: /tmp/server2/kraft-combined-logs

templates/server.properties.j2:

node.id= "{{ node_id }}"
controller.quorum.voters= "{{ cqvoters }}"
############################# Socket Server Settings #############################
listeners= "{{ listeners }}"
advertised.listeners= "{{ advertised }}"
############################# Log Basics #############################
log.dirs= "{{ log_dir }}"

playbook.yml:

- name: Create different properties files from variable
  hosts: localhost
  gather_facts: false

  vars_files:
    - common.yml

  tasks:
    - name: Create a properties file for each entry in properties_by_nodes
      vars:
        node_id: "{{ item.node_id }}"
        cqvoters: "{{ item.cqvoters }}"
        listeners: "{{ item.listeners }}"
        advertised: "{{ item.advertised }}"
        log_dir: "{{ item.log_dir }}"
      ansible.builtin.template:
        src: server.properties.j2
        dest: "/tmp/server{{ node_id }}.properties"
      loop: "{{ properties_by_nodes }}"

运行 playbook 会给出(请注意,使用具有正确内容的现有文件再次运行将报告“ok”而不是“changed”)

$ ansible-playbook playbook.yml 

PLAY [Create different properties files from variable] ***********************

TASK [Create a properties file for each entry in properties_by_nodes] ********
changed: [localhost] => (item={'node_id': 1, 'cqvoters': '[email protected]:8080,[email protected]:8081,[email protected]:8082', 'listeners': 'SASL_SSL://web.example.com:18080,CONTROLLER://web.example.com:8080', 'advertised': 'SASL_SSL://web.example.com:18080', 'log_dir': '/tmp/server1/kraft-combined-logs'})
changed: [localhost] => (item={'node_id': 2, 'cqvoters': '[email protected]:8080,[email protected]:8081,[email protected]:8082', 'listeners': 'SASL_SSL://web.example.com:18081,CONTROLLER://web.example.com:8081', 'advertised': 'SASL_SSL://web.example.com:18081', 'log_dir': '/tmp/server2/kraft-combined-logs'})

PLAY RECAP *******************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

现在,我们可以检查文件是否已创建内容是否正确:

$ for f in /tmp/server*.properties; \
do echo -e "content of $f\n----"; cat $f; echo; done

content of /tmp/server1.properties
----
node.id= "1"
controller.quorum.voters= "[email protected]:8080,[email protected]:8081,[email protected]:8082"
############################# Socket Server Settings #############################
listeners= "SASL_SSL://web.example.com:18080,CONTROLLER://web.example.com:8080"
advertised.listeners= "SASL_SSL://web.example.com:18080"
############################# Log Basics #############################
log.dirs= "/tmp/server1/kraft-combined-logs"

content of /tmp/server2.properties
----
node.id= "2"
controller.quorum.voters= "[email protected]:8080,[email protected]:8081,[email protected]:8082"
############################# Socket Server Settings #############################
listeners= "SASL_SSL://web.example.com:18081,CONTROLLER://web.example.com:8081"
advertised.listeners= "SASL_SSL://web.example.com:18081"
############################# Log Basics #############################
log.dirs= "/tmp/server2/kraft-combined-logs"