Ansible:如果满足特定条件,则在vars文件中有条件地定义变量


19

根据在group_vars中定义的变量的值(真/假),我尝试在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>"

我在这里做蠢事还是不支持?我试图找到另一种定义这些var的方法(我有很多),但是我没有在这里得到一些功能。有什么建议么?


这些变量最终在哪里使用?如果您要使用它们的全部只是template模块调用的一部分,则这可能是不必要的。
84104

如果test是组依赖的,则应将其放入group_vars中。
康斯坦丁·苏沃洛夫'18

不幸的是,测试不依赖于组。如描述中所述,测试取决于group_var变量的值。
pandoJohn

Answers:


11

我认为您不能,我通常创建单独的文件来保存条件变量集合,并使用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" 

2
这是我试图避免的事情。我不想使用include var或为我的任务定义2个其他var文件。
pandoJohn

我不明白..当可以在条件中使用include_vars时,为什么不能在条件中定义变量?
GP92 '19

10

Ansible允许以下形式之一有条件地定义变量:

    test:
      var1: "{% if my_group_var %}value{% else %}other_value{% endif %}"
      var2: "{{'value' if (my_group_var) else 'other_value'}}"

结合上面的语法和vars查找,我们可以加载复杂的var(在这种情况下为list):

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')}}"

还有另一种通过vars查找进行条件树加载的方法。当您需要实现案例逻辑(即条件变量具有两个以上的可能值)时,这种方法很方便:

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

尽管这会很好,但恐怕您的方式是不可能的(或者我不知道正确的方式)。

我建议首先从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 %}

我喜欢这样,但问题是从jinja模板生成.yml文件后,该文件不适用于我的剧本中的后续任务。
pandoJohn

为什么?当我试图扩大与调试任务测试的剧本- debug: var=test,我可以看到,有两个定义test.var1,并test.var2与预期值。因此,您应该能够在剧本的其他任务中使用这些变量。
Jaroslav Kucera '18 -4-12

0

AFAIK,您正在尝试的{}是针对Jinja2模板而不是yml文件。从文档中

ansible允许在模板中使用Jinja2循环和条件,但在剧本中,我们不使用它们。

您可以使用播放准备一个单独的.yml文件,该播放使用when子句设置所需的变量,然后将其导入(或包括)在您的主播放簿中。这样,您可以在单个文件中有条件地定义所有var。

或:使用角色。我认为角色是解决问题的最合适方法。


0

我到底做的是建立2个独立var中的文件-我们姑且称之为type_a.ymltype_b.yml-和我定义的一组变量,表示什么文件来使用-有点像type_of_file: a。这是我的剧本现在的样子:

- name: blabla
  hosts: blabla
  vars_files:
     - <path>/type_{{ type_of_file }}.yml
  roles: blabla

感谢所有的答案。我发现它们真的很有帮助。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.