播放过程中无法识别 Ansible 标签?

Ansible tags not recognized during a play?

$ ansible --version
ansible 2.10.8

我有一个名为 site.yml 的剧本,其中仅包含其他剧本。有些剧本我只想在使用 --tags update 标签时运行,但有些剧本我想一直 运行,但只有某些任务被适当标记。在我下面的示例中,我希望 prepare-update.yml 剧本上的所有任务仅在 update 标签上 运行,而我希望 运行 postgresql.yml 剧本全部时间。然后我想在我的 postgresql 角色

中控制一些任务 运行 或不
- import_playbook: prepare-update.yml
  tags: update
- import_playbook: postgresql.yml

posgresql.yml 剧本仅包含一个 postgresql 角色

---
- hosts: "{{ var_host | default('exa_site') }}"
  become_method: runas

  roles:
    - postgresql

现在我的 postgresql 角色的 tasks/main.yml

---
# tasks file for postgresql
- include_tasks: install_postgresql.yml
- include_tasks: run_postgresql_queries.yml
- include_tasks: install_pgadmin4.yml

我的 install_postgresql.yml 任务有这些任务。如您所见,我使用了 3 个不同的标签,即 new_installupdateuninstall

- block:
  - name: Download app
    win_get_url: ...
  - name: Install app
    win_shell: ...
  tags: new_install

- name: Start service
  win_service: ...
  tags:
  - new_install
  - update

- block:
  - name: Stop service
    win_service: ...
  - name: Delete service
    win_file: ...
  tags: uninstall

当我 运行 以下内容时,我希望某些任务 运行 基于它们的标签。

$ ansible-playbook -i hosts.yml -e var_host=my_host --tags new_install site.yml

然而,我只是得到这个,什么都没有运行s。

PLAY [10.227.x.x] *******************************************************

TASK [Gathering Facts] **************************************************
ok: [10.227.x.x]

PLAY RECAP **************************************************************
10.227.x.x               : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

为什么我的任务被标记为 new_install 而不是 运行?

发生这种情况是因为您的 include_tasks 被跳过了,因为它们不包含任何匹配 new_install.

的标签

如果您不想在 include_tasks 上重复较低级别的标签,您可以使用特殊标签 always.

来标记它们

因此,您角色的 main.yml 任务变为:

## Using a block, so we can tag them all at once.
- block:
    - include_tasks: install_postgresql.yml
    - include_tasks: run_postgresql_queries.yml
    - include_tasks: install_pgadmin4.yml
  tags: always

另一种方法是 导入 你的任务,因为这是 import_*include_* 模块之间的主要区别。

因此,您角色的 main.yml 任务再次更改为:

- import_tasks: install_postgresql.yml
- import_tasks: run_postgresql_queries.yml
- import_tasks: install_pgadmin4.yml

注意两个模块概要中的措辞差异:

  • import_tasks:导入任务列表,添加到当前playbook,供后续执行。 source
  • include_tasks:包含一个文件,其中包含要在当前剧本中执行的任务列表。 source

因此,当一个 “盲目” 导入以进一步执行时,另一个包含它们并同时 运行 它们。
考虑到这一点,如果缺少正确的标签,后者 include_tasks 将被跳过是有道理的,当第一个将任务放入剧本中,然后在剧本执行时,标签在导入的任务将按照您的预期进行评估。

(解决方案在@β.εηοιτ.βε的另一个答案中描述)

要理解这个问题的逻辑,有两点很重要:

  1. 引用自Includes: dynamic re-use

"Ansible processes included files and roles as they come up in a playbook."

  1. 引用自Adding tags to includes

"... tags on an include_* task apply only to the include itself, not to any tasks within the included file or role."

因此,当声明 --tags 时(在 command-line 或其他地方)如果标签(在此声明),播放将跳过任何 include_* 语句include_* 语句)不匹配。换句话说,在这种情况下,剧本在到达包含语句之前不知道包含内容,并且永远不会学习,因为它将被跳过。