在子任务上使用带有标签的 Ansible include_tasks

在子任务上使用带有标签的 Ansible include_tasks

Ansible 2.8.1

在我的剧本目录中tasks/

main.yml
dev.yml

main.yml有这样一个块:

- include_tasks: dev.yml
  when: ec2_tag_env == 'dev'

它工作正常


但是,如果我尝试使用标签在 dev.yml 中调用特定任务,则在运行期间它不会限定任务

例如,此标记的任务在dev.yml

- name: Pull the latest image
  docker_image:
    name: "{{ dev_image }}"
    source: pull
  tags:
    - container

当我运行剧本时-t container include_tasks由于该步骤没有该标签,因此它不符合条件。


添加标签include_tasks当然可以解决问题,但是我需要跟踪添加到子任务中的标签,并将它们也添加到这里:

- include_tasks: dev.yml
  when: ec2_tag_env == 'dev'
  tags:
    - container

问题

  • 是否可以让 Ansible 仅“知道”include_tasks块内有哪些任务并提取适用的标签?

  • 实现这一目标的最佳做法是什么?

我希望不是得做:

  • 把所有东西都放进去main.yml。我在这个剧本里有太多的任务,我真的想把它们组织在文件中。
  • 手动标记我的所有include_tasks区块及其所有子标签。听起来管理起来很麻烦。

答案1

问:“是否可以让 Ansible 只‘知道’include_tasks 块内的任务并提取适用的标签?”

答:包含的任务的内容将在控制流到达include_task语句并包含该文件。请参阅下面该行下的示例。例如,此类标签不会包含在可用标签列表中。请参阅选项--list-tagsansible-剧本在这方面,答案是否定的。但是,这样的标签可能是可用的(在控制流到达include_task语句)如果也在级别上指定包括_任务。此外,特殊标签总是使此类标签可用。

问:“实现这一目标的最佳做法是什么?”

答:有两种选择:

  • 要么使用import_tasks. 剧本启动时会读取导入内容。

  • 或者使用特殊标签总是。Ansible 将始终包含来自该文件的任务。


为了澄清差异。给出以下文件

shell> cat install.yml
- debug:
    msg: Task 2
  tags: t2
- debug:
    msg: Task 3
  tags: t3
  1. 剧本
shell> cat pb1.yml
- hosts: localhost
  tasks:
    - debug:
        msg: Task 1
      tags: t1
    - include_tasks:
        file: install.yml

按预期工作

shell> ansible-playbook pb1.yml

PLAY [localhost] *****************************************************************************

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg: Task 1

TASK [include_tasks] *************************************************************************
included: /export/scratch/tmp8/test-828/install.yml for localhost

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg: Task 2

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg: Task 3

PLAY RECAP ***********************************************************************************
localhost: ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

当使用标签时-t t1,t2,标签为 t1 的任务被执行,但是标签为 t2 的任务没有被执行,因为该文件没有被包含

shell> ansible-playbook pb1.yml -t t1,t2

PLAY [localhost] *****************************************************************************

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg: Task 1

PLAY RECAP ***********************************************************************************
localhost: ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

请注意,启动时,应用程序对所包含文件中的标签一无所知

shell> ansible-playbook pb1.yml --list-tags

playbook: pb1.yml

  play #1 (localhost): localhost    TAGS: []
      TASK TAGS: [t1]

  1. 标签总是任务包括任务
shell> cat pb2.yml
- hosts: localhost
  tasks:
    - debug:
        msg: Task 1
      tags: t1
    - include_tasks:
        file: install.yml
      tags: always

启动时,应用程序仍然对包含文件中的标签一无所知,但任务将始终包含在内

shell> ansible-playbook pb2.yml --list-tags

playbook: pb1.yml

  play #1 (localhost): localhost    TAGS: []
      TASK TAGS: [always, t1]

当标签-t t1,t2现在使用标记为 t1 和 t2 的任务都已执行

shell> ansible-playbook pb2.yml -t t1,t2

PLAY [localhost] *****************************************************************************

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg: Task 1

TASK [include_tasks] *************************************************************************
included: /export/scratch/tmp8/test-828/install.yml for localhost

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg: Task 2

PLAY RECAP ***********************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

  1. 标签总是导致文件安装.yml当控制流到达包括_任务语句。但此标签适用于包括_任务仅限。它不会被文件内的任务继承。如果您想将标签应用于文件内的任务,请使用参数申请。 例如
shell> cat pb3.yml
- hosts: localhost
  tasks:
    - debug:
        msg: Task 1
      tags: t1
    - include_tasks:
        file: install.yml
        apply:
          tags: install
      tags: always

请注意,启动时,应用程序对所应用的标签和所包含文件中的标签一无所知

shell> ansible-playbook pb3.yml --list-tags

playbook: pb3.yml

  play #1 (localhost): localhost    TAGS: []
      TASK TAGS: [always, t1]

应用标签的唯一区别是,所有包含的任务都可以由此标签触发,例如

shell> ansible-playbook pb3.yml -t install

PLAY [localhost] *****************************************************************************

TASK [include_tasks] *************************************************************************
included: /export/scratch/tmp8/test-828/install.yml for localhost

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg: Task 2

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg: Task 3

PLAY RECAP ***********************************************************************************
localhost: ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

但是,应用的标签不会帮助您单独触发包含的任务。 还需要理解的是,如果没有相同的标签或特殊标签,应用的标签就没有意义总是,在包括_任务等级。

答案2

这是一个老问题,但对于其他可能因为想要或需要使用include_tasks而不是 而感到困惑的人来说import_tasks。对于那些可以同时使用两者的人,我也强烈建议import_tasks像以前一样使用之前回答过

在官方Ansible 手册,开发人员建议tags: alwaysinclude_tasks其自身上使用,同时将其他标签应用于apply:所包含的任务。

参见此示例(复制从手册中):

- name: Apply tags to tasks within included file
  include_tasks:
    file: install.yml
    apply:
      tags:
        - install
  tags:
    - always

这种方式确保 Ansible 总是(除了使用 调用时--skip-tags always)包含外部任务以便能够查看那些特定标签,因此如果install.yml包含一个任务,那么在使用 调用 Ansible 时(不添加)tags: download将运行此任务。--tags downloadinstall

答案3

我推荐 Red Hat 的关于此问题的帖子:https://www.redhat.com/sysadmin/ansible-tags-fast-playbook-runs

相关内容