根据 group_vars 中定义的变量的值(True/False),我尝试在 vars 文件中定义一些变量。它们的值取决于组 var 的值。
我当前的 var 文件如下所示:
{% if my_group_var %}
test:
var1: value
var2: value
...
varn: value
{% else %}
test:
var1: other_value
var2: other_value
...
varn: other_value
{% endif %}
对于我的每一个角色,我都使用在此文件中定义的变量。
我的测试剧本如下所示:
- name: blabla
hosts: blabla
vars_files:
- <path>/test_vars.yml
roles: blabla
运行剧本后我收到的错误是:
{% if my_group_var %}
^ here
exception type: <class 'yaml.scanner.ScannerError'>
exception: while scanning for the next token
found character that cannot start any token
in "<unicode string>"
我是不是在做蠢事,或者这根本不受支持?我尝试过找到另一种方法来定义这些变量(我有很多),但我没能在这里找到一些有用的功能。有什么建议吗?
答案1
Ansible 允许使用下列形式之一有条件地定义变量:
test:
var1: "{% if my_group_var %}value{% else %}other_value{% endif %}"
var2: "{{'value' if (my_group_var) else 'other_value'}}"
将上述语法与变量查找相结合,我们可以加载复杂变量(在本例中为 map):
test_value_when_my_group_var_is_true:
var1: value
var2: value
test_value_when_my_group_var_is_false:
var1: other_value
var2: other_value
test: "{{ lookup('vars','test_value_when_my_group_var_is_true') if (my_group_var) else lookup('vars','test_value_when_my_group_var_is_false')}}"
还有另一种使用变量查找进行条件树加载的方法。当你需要实现案例逻辑(即条件变量有两个以上的可能值)时,这种方法很方便:
test_value_when_my_group_var_is_foo:
var1: value
var2: value
test_value_when_my_group_var_is_bar:
var1: other_value
var2: other_value
test_value_when_my_group_var_is_baz:
var1: yet_another_value
var2: yet_another_value
test: "{{ lookup('vars','test_value_when_my_group_var_is_' + my_group_var) }}"
答案2
我认为你不能,我通常会创建单独的文件来保存条件变量集合并使用when
条款将其纳入特定条件:
- include_vars: test_environment_vars.yml
when: global_platform == "test"
- include_vars: staging_environment_vars.yml
when: global_platform == "staging"
- include_vars: prod_environment_vars.yml
when:
- global_platform != "test"
- global_platform != "staging"
答案3
尽管这会很好,但恐怕你的方法不可行(或者我不知道正确的方法)。
我建议首先从 jinja 模板准备 vars 文件,然后将其包含在 include_vars 中。请参阅示例剧本:
---
- name: -Test-
hosts: local
vars:
my_group_var: False
# my_group_var: True
tasks:
- name: Prepare vars file from template.
template: src=/tmp/vars.yaml.j2
dest=/tmp/vars.yaml
- name: Include vars
include_vars: "/tmp/vars.yaml"
示例 jinja 模板 /tmp/vars.yaml.j2 的内容为:
{% if my_group_var %}
test:
var1: value
var2: value
{% else %}
test:
var1: other_value
var2: other_value
{% endif %}
答案4
据我所知,您尝试的这个 {} 适用于 Jinja2 模板,而不是 yml 文件。从文档:
ansible 允许在模板中使用 Jinja2 循环和条件,但在剧本中,我们不使用它们。
您可以准备一个单独的 .yml 文件,其中包含一个使用 when 子句设置所需变量的剧本,然后将它们导入(或包含)到主剧本中。这样,您就可以在一个文件中有条件地定义所有变量。
或者:使用角色。我认为角色是解决问题最合适的方法。