如何为 Ansible 任务中的每次循环迭代传递不同的变量集

如何为 Ansible 任务中的每次循环迭代传递不同的变量集

我有一个 Ansible 任务,它循环遍历列表,并为列表中的每个项目运行一个角色,使用include_role。对于循环的每次迭代,我想传递一组不同的变量。目前,我正尝试通过将列表创建为字典列表来实现这一点,该列表可以--extra-vars在运行时使用来指定。

例如我有任务:

- name: Run the test role
  include_role:
    name: test_role
  loop: '{{ input_list }}'

还有input_list

input_list:
  - var1: foo
    var2: bar
    var3: baz
  - var1: hello
    var3: world

但此时我该如何将当前的变量集传递给角色?我最初尝试分别定义每个变量:

- name: Run the test role
  include_role:
    name: test_role
  vars:
    var1: '{{ item.var1 }}'  
    var2: '{{ item.var2 }}'  
    var3: '{{ item.var3 }}'  
  loop: '{{ input_list }}'

这可以工作,但如果缺少一个变量input_list(即应该回退到角色默认值中指定的默认值或剧本开头的变量值),剧本将失败。所以我尝试使用 Jinja2 的default过滤器:

- name: Run the test role
  include_role:
    name: test_role
  vars:
    var1: '{{ item.var1 | default('foo') }}'  
    var2: '{{ item.var2 | default('bar') }}'  
    var3: '{{ item.var3 | default('baz') }}'  
  loop: '{{ input_list }}'

同样,这种方法可行,但有点混乱,因为每个变量都需要定义,而且它不使用角色的默认值。有没有更好的方法来实现这样的效果?

答案1

其中一个选项是创建替代默认值。例如,创建一个用于测试的最小角色

shell> cat roles/test_role/defaults/main.yml
var1: default_1
var2: default_2
var3: default_3

shell> cat roles/test_role/tasks/main.yml 
- debug:
    msg: "{{ var1 }} {{ var2 }} {{ var3 }}"

任务

    - include_role:
        name: test_role

给出

  msg: default_1 default_2 default_3

让我们创建替代默认值,例如

shell> cat roles/test_role/defaults/alt.yml
var1: "{{ alt.var1|default('default_1') }}"
var2: "{{ alt.var2|default('default_2') }}"
var3: "{{ alt.var3|default('default_3') }}"

并在包含中使用它。下面的任务给出了相同的结果

    - include_role:
        name: test_role
        defaults_from: alt.yml

现在,让我们用备用默认值定义字典

    - include_role:
        name: test_role
        defaults_from: alt.yml
      loop: '{{ input_list }}'
      vars:
        alt: "{{ item }}"

给出

  msg: foo bar baz
  msg: hello default_2 world

下一个选项是创建和使用替代变量

shell> cat roles/test_role/vars/alt.yml 
var1: "{{ alt.var1|default('default_1') }}"
var2: "{{ alt.var2|default('default_2') }}"
var3: "{{ alt.var3|default('default_3') }}"

例如,下面的任务给出了相同的结果。唯一的区别是优先权

    - include_role:
        name: test_role
        vars_from: alt.yml
      loop: '{{ input_list }}'
      vars:
        alt: "{{ item }}"

相关内容