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

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

根据 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 子句设置所需变量的剧本,然后将它们导入(或包含)到主剧本中。这样,您就可以在一个文件中有条件地定义所有变量。

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

相关内容