【问题标题】:Conditionally Include Template Lines if Referenced Files from Variable List Exist如果变量列表中的引用文件存在,则有条件地包含模板行
【发布时间】:2021-03-10 13:42:11
【问题描述】:

我想根据变量列表中定义的目录是否存在有条件地在我的 Nginx 虚拟主机中包含一些配置(实际上它也基于下面的变量列表是否存在变量,但我正在尝试在这里保持简单)。

变量如下所示:

nginx:
  sites:
    - name: example.com
      aliases: www.example.com
      tls:
        key: /etc/letsencrypt/live/example.com/privkey.pem
        certificate: /etc/letsencrypt/live/example.com/fullchain.pem
    - name: anotherexample.com
      aliases: www.anotherexample.com
      tls:
        key: /etc/letsencrypt/live/anotherexample.com/privkey.pem
        certificate: /etc/letsencrypt/live/anotherexample.com/fullchain.pem

假设目录/etc/letsencrypt/live/example.com/存在,目录/etc/letsencrypt/live/anotherexample.com不存在。

以上用于以下模板(with_items: nginx.sites):

- name: Nginx Site Templates
  template:
    src: nginx/nginx_site.conf.j2
    dest: /etc/nginx/sites-available/{{ item.name }}.conf
  with_items: "{{ nginx.sites }}"
  notify: reload nginx
  tags:
    - conf

“nginx/nginx_site.conf.j2”是部分:

server {

...

  {% if [MY CONDITION THAT I NEED HELP WITH] %}
  listen 443 ssl;

  ssl_certificate_key {{ item.tls.key }};
  ssl_certificate {{ item.tls.certificate }};
  {% endif %}

...

}

我收集有关nginx.sites[].tls 中引用的目录是否存在的事实,并注册了以下事实:

- name: Register Fact About Available TLS Certificates
  stat:
    path: "/etc/letsencrypt/live/{{ item.name }}"
  register: tls_site_certificates
  changed_when: false
  with_items: "{{ nginx.sites }}"
    - conf
    - facts

对于每个站点,仅当引用的目录存在时,我才希望将这些行包含在模板的 if 条件中。我想我几乎在那里,但我很难弄清楚。到目前为止,我有:

{% if tls_site_certificates.results | select('item.name', 'equalto', item.name) | select('stat.exists') == true %}

【问题讨论】:

    标签: ansible jinja2 ansible-facts


    【解决方案1】:

    select 是过滤列表。 第一次使用select('item.name', 'equalto', item.name) 几乎是正确的:使用selectattr 你只保留与当前项目同名的元素。

    但是您想访问第一个元素的字段,而不是再次过滤(并且无需将布尔值与true 进行比较):

    {% if (tls_site_certificates.results | selectattr('item.name', 'equalto', item.name) | first).stat.exists %}
    

    【讨论】:

    • 谢谢,但这实际上是我尝试过的(我尝试了 这么多 东西,我没有费心将它们全部列出,但也许我应该:/)结果错误:"TemplateRuntimeError: no test named 'item.name'
    • 显示您测试的所有内容和遇到的所有错误可能是一个好主意。我修正了我的答案以使用正确的过滤器selectattr
    • 太好了,谢谢!我不得不稍微改变一下,让事实注册只发生when: item.tls.key is defined,这样我就可以使用item.tls.key作为收集事实时的搜索路径。这意味着我还必须将if item.tls is defined 添加到模板中,但效果很好。
    猜你喜欢
    • 2023-01-21
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多