首页 > 解决方案 > Jinja2 如果定义了变量,则从引用变量的 Ansible 默认设置变量

问题描述

在 Ansible 角色中,如果定义了变量,我将在 Jinja2 模板中进行测试。如果已定义,则应设置来自 Ansible 的 defaults/main.yml 的变量来引用此变量。

只要定义了在 Jinja2 模板中测试的变量,就可以正常工作。如果不是,Ansible 会抱怨一个未定义的变量。

示例角色文件:

$ cat defaults/main.yml
---
database_name: "prefix-{{ database }}"

$ cat tasks/main.yml 
---
- name: Deploy config
  template:
    src: config.j2
    dest: /opt/config
    mode: 0644

$ cat templates/config.j2 
# this works
{% if database is defined %}
Database={{ database }}
{% endif %}

# this is broken
{% if database is defined %}
Database={{ database_name }}
{% endif %}

在测试它是否存在之后直接使用该变量(参见上面的“这有效”)就可以了。
如何使用 defaults/main.yml 中的变量?

标签: ansiblejinja2ansible-2.x

解决方案


长话短说:在defaults/main.yml

database_name: "prefix-{{ database | default('db_does_not_exist') }}"

您可以阅读 ansible 和 jinja2 代码以清楚地理解原因,但基本上,Jinja2 会尝试在解释时读取您的 var,即使在您的 if 条件内结果为假,并找到另一个它尝试再次解释的 var不明确的。

上面的默认值永远不会在您的情况下使用,但会阻止您的模板触发此错误(或使用它的任何其他任务)


推荐阅读