在角色任务中迭代列表,将每个元素作为变量提供给 include_tasks

Iterate list within role task, provide each element as vars to include_tasks

对 Ansible 还很陌生,所以我的方法或想法可能有误。

我已经指定了角色 common,在该角色的 main.yaml 中,一个迭代列表并包含任务文件的任务,同时提供基于每个列表元素的变量。

在我的剧本中,最后我定义:

roles:
   - role: common
    tags: [ never, common ]

以及 roles/common/tasks/main.yaml

内的任务
- name: Create user accounts
  include_tasks: tasks/create_user.yaml
  vars:
    user: "{{ item.name }}"
    grps: "{{ item.groups }}"
  with_items:
    - { name: user1, groups: group1 }
    - { name: user2, groups: group2 }
  tags: [ never, users ]

并在 tasks/create_user.yaml 内,用于测试迭代和变量是否有效:

---
- name: Print user and groups
  debug:
    msg: "{{ user }} and {{ grps }}"

运行 剧本,针对主机 test-host,我得到:

TASK [common : Create user accounts] ******************************************************************************************************************************************************************************
included: /...path.../tasks/create_user.yaml for test-host
included: /...path.../tasks/create_user.yaml for test-host

没有执行任何任务。

我不确定我做错了什么。感谢任何输入。

请参阅下面的选项,特别是最后的注释。为了测试,下面的任务

    - include_tasks: test-debug.yml
      loop: "{{ users }}"
      vars:
        users: [alice, bob, charlie]
      tags: t1

    - debug:
        msg: End of play.
      tags: t1
shell> cat test-debug.yml
- debug:
    msg: "{{ item }}"

将执行 包含的 调试而不指定标签

shell> ansible-playbook playbook.yml | grep msg
...
  msg: alice
  msg: bob
  msg: charlie
  msg: End of play.

指定标签t1时不会执行included调试,因为included任务不继承标签

shell> ansible-playbook playbook.yml -t t1 | grep msg
...
  msg: End of play.

关于如何解决问题有更多选择。将标签放入包含的任务、导入任务或将标签应用于包含的任务

1) 将标签放入包含的任务中

shell> cat test-debug.yml
- debug:
    msg: "{{ item }}"
  tags: t1
shell> ansible-playbook playbook.yml -t t1 | grep msg
  msg: alice
  msg: bob
  msg: charlie
  msg: End of play.

2) 导入任务

import_taskscannot be used in a loop。可以将列表放入 vars 并在导入的任务

中迭代它
    - import_tasks: test-debug.yml
      vars:
        users: [alice, bob, charlie]
      tags: t1
shell> cat test-debug.yml
- debug:
    msg: "{{ item }}"
  loop: "{{ users }}"
shell> ansible-playbook playbook.yml -t t1 | grep msg
  msg: alice
  msg: bob
  msg: charlie
  msg: End of play.

3) 应用标签

下一个选项是apply标签

    - include_tasks:
        file: test-debug.yml
        apply:
          tags: t1
      loop: "{{ users }}"
      vars:
        users: [alice, bob, charlie]
      tags: t1

    - ansible.builtin.debug:
        msg: End of play.
      tags: t1
shell> cat test-debug.yml
- debug:
    msg: "{{ item }}"
shell> ansible-playbook playbook.yml -t t1 | grep msg
  msg: alice
  msg: bob
  msg: charlie
  msg: End of play.

include_tasksimport_tasks之间的决定是一个权衡。包含任务的主要优点是可以迭代更多任务。缺点是(引用自Comparing includes and imports: dynamic and static re-use):

Note: There are also big differences in resource consumption and performance, imports are quite lean and fast, while includes require a lot of management and accounting.