Ansible/Jinja2 模板:for 循环运行两次

Ansible/Jinja2 template : for loop runs twice

我的 Jinja2 文件中的 for 循环有问题。 我使用 Ansible 模板如下:

- name: "Configure syslog-ng-nginx"
  template:
    src: "nginx.conf.j2"
    dest: /etc/syslog-ng/conf.d/nginx.conf
    owner: root
    group: root
    mode: 0640
    backup: yes
  with_dict: "{{ nginx_http_template }}"
  notify: restart syslog-ng

我的字典看起来像这样:

nginx_http_template:
  toto.test.fr:
    conf_file_name: toto.test.fr
    conf_file_location: /etc/nginx/sites-enabled/
    servers:
      server1:
        server_name: 'toto.test.fr'
        listen:
          listen_wildcard:
            ip: '*'
            port: 80
        access_log:
          - name: main
            location: /var/log/nginx/access.toto.test.fr.log
        error_log:
          location: /var/log/nginx/error.toto.test.fr.log
          level: warn
        autoindex: false
        root: /var/www/toto/public
  toto2.test.fr:
    conf_file_name: toto2.test.fr
    conf_file_location: /etc/nginx/sites-enabled/
    servers:
      server1:
        server_name: 'toto2.test.fr'
        listen:
          listen_wildcard:
            ip: '*'
            port: 80
        access_log:
          - name: main
            location: /var/log/nginx/access.toto2.test.fr.log
        error_log:
          location: /var/log/nginx/error.toto2.test.fr.log
          level: warn
        autoindex: false
        root: /var/www/toto2/public

我的 nginx.conf.j2 模板如下所示:

source {{ nginx_syslog_source_name }} {
{% for server in item.value.servers %}
  {% for access_log in item.value.servers[server].access_log %}
    file("{{ access_log.location }}" flags(no-parse) program-override("nginx-access-{{ item.value.servers[server].server_name }}"));
  {% endfor %}
{% endfor %}
};

问题是,每当我 运行 任务时,文件都会写入“toto.test.fr”的信息,但是,而不是“附加”“[=] 的信息37=]”,它覆盖了“toto.test.fr”,我只得到了“toto2.test.fr”中的内容。

让我们看看我的 Ansible 输出:

TASK [syslog : Configure syslog-ng-nginx] ***************************************************************************************************************************************
--- before
+++ after: /home/yanis/.ansible/tmp/ansible-local-251749PRAOO/tmpIR53tK/nginx.conf.j2
@@ -0,0 +1,3 @@
+source s_nginx_toto.test {
+      file("/var/log/nginx/access.toto.test.fr.log" flags(no-parse) program-override("nginx-access-toto.test.fr"));
+  };

changed: [MYHOST] => (item={'value': {u'conf_file_name': u'toto.test.fr', u'conf_file_location': u'/etc/nginx/sites-enabled/', u'servers': {u'server1': {u'error_lo
g': {u'location': u'/var/log/nginx/error.toto.test.fr.log', u'level': u'warn'}, u'server_name': u'toto.test.fr', u'autoindex': False, u'access_log': [{u'name': u'main', u'locati
on': u'/var/log/nginx/access.toto.test.fr.log'}], u'root': u'/var/www/toto/public', u'listen': {u'listen_wildcard': {u'ip': u'*', u'port': 80}}}}}, 'key': u'toto.test.fr'})

--- before: /etc/syslog-ng/conf.d/nginx.conf
+++ after: /home/yanis/.ansible/tmp/ansible-local-251749PRAOO/tmpRaaSpL/nginx.conf.j2
@@ -1,3 +1,3 @@
 source s_nginx_toto_test {
-      file("/var/log/nginx/access.toto.test.fr.log" flags(no-parse) program-override("nginx-access-toto.test.fr"));
+      file("/var/log/nginx/access.toto2.test.fr.log" flags(no-parse) program-override("nginx-access-toto2.test.fr"));
   };

changed: [MYHOST] => (item={'value': {u'conf_file_name': u'toto2.test.fr', u'conf_file_location': u'/etc/nginx/sites-enabled/', u'servers': {u'server1': {u'error_l
og': {u'location': u'/var/log/nginx/error.toto2.test.fr.log', u'level': u'warn'}, u'server_name': u'toto2.test.fr', u'autoindex': False, u'access_log': [{u'name': u'main', u'loc
ation': u'/var/log/nginx/access.toto2.test.fr.log'}], u'root': u'/var/www/toto2/public', u'listen': {u'listen_wildcard': {u'ip': u'*', u'port': 80}}}}}, 'key': u'toto2.test.fr'}
)

如您所见,“toto.test.fr”信息被写入,但是随后,“toto2.test.fr”也被写入并覆盖“toto.test.fr”。

这是他的最终文件:

source s_nginx_toto_test {
      file("/var/log/nginx/access.toto2.test.fr.log" flags(no-parse) program-override("nginx-access-toto2.test.fr"));
  };

我想要的是:

source s_nginx_toto_test {
      file("/var/log/nginx/access.toto.test.fr.log" flags(no-parse) program-override("nginx-access-toto.test.fr"));
  };
      file("/var/log/nginx/access.toto2.test.fr.log" flags(no-parse) program-override("nginx-access-toto2.test.fr"));
  };

有什么想法吗?

你的循环 with_dict: "{{ nginx_http_template }}",使用键 toto.test.fr 生成文件 /etc/syslog-ng/conf.d/nginx.conf 然后生成相同的文件键 toto2.test.fr.

要解决您的问题,请从任务中删除循环:

- name: "Configure syslog-ng-nginx"
  template:
    src: "nginx.conf.j2"
    dest: /etc/syslog-ng/conf.d/nginx.conf
    owner: root
    group: root
    mode: 0640
    backup: yes
  notify: restart syslog-ng

并更新您的模板以直接管理您的变量 nginx_http_template:

source {{ nginx_syslog_source_name }} {
{% for name, config in nginx_http_template.items() %}
    file("{{ config.servers.server1.access_log[0].location }}" flags(no-parse) program-override("nginx-access-{{ name }}"));
{% endfor %}
};