【问题标题】:Ansible/Jinja2 template : for loop runs twiceAnsible/Jinja2 模板:for 循环运行两次
【发布时间】:2020-10-22 05:47:49
【问题描述】:

我的 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.j2template 看起来像这样:

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”的信息,但是,它不是“附加”“toto2.test.fr”的信息,而是覆盖“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"));
  };

有什么想法吗?

【问题讨论】:

    标签: templates ansible jinja2


    【解决方案1】:

    你的循环with_dict: "{{ nginx_http_template }}",生成文件/etc/syslog-ng/conf.d/nginx.conf 用密钥toto.test.fr 然后用密钥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 %}
    };
    

    【讨论】:

    • 非常感谢!它工作得很好。我不知道 with_dict 会生成一个循环!我了解问题知道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-22
    相关资源
    最近更新 更多