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

emm*_*dee 10 ansible ansible-playbook

安塞布尔2.8.1

在我的剧本tasks/目录中:

main.yml
dev.yml
Run Code Online (Sandbox Code Playgroud)

main.yml我有一个这样的块:

- include_tasks: dev.yml
  when: ec2_tag_env == 'dev'
Run Code Online (Sandbox Code Playgroud)

效果很好


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

例如,以下标记的任务dev.yml

- name: Pull the latest image
  docker_image:
    name: "{{ dev_image }}"
    source: pull
  tags:
    - container
Run Code Online (Sandbox Code Playgroud)

当我用它运行剧本时,-t container 它将不符合资格,因为该include_tasks步骤没有该标签。


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

- include_tasks: dev.yml
  when: ec2_tag_env == 'dev'
  tags:
    - container
Run Code Online (Sandbox Code Playgroud)

问题

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

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

我宁愿不必的事情:

  • 把所有东西都放上main.yml。我在这本剧本中有很多任务,我真的很想将它们组织在文件中。
  • 手动标记我的所有include_tasks块及其所有子标签。听起来像是一场噩梦。

小智 9

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

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

请参阅此示例(从手册复制):

- name: Apply tags to tasks within included file
  include_tasks:
    file: install.yml
    apply:
      tags:
        - install
  tags:
    - always
Run Code Online (Sandbox Code Playgroud)

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


Vla*_*tka 6

问:“Ansible 是否可以‘知道’ include_tasks 块中有哪些任务并提取适用的标签?”

include_task答:包含任务中的内容在控制流到达语句并包含文件后才可用。请参阅下面的示例。例如,此类标签不会包含在可用标签列表中。请参阅ansible-playbook--list-tags的选项。从这个角度来说,答案是否定的。但是,如果也在include_task级别上指定,则此类标记可能可用(在控制流到达语句之后) 。此外,特殊标签始终使此类标签可用。include_task

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

答:有两种选择:

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

  • 或者,使用特殊标签always。Ansible 将始终包含文件中的任务。


为了澄清差异。鉴于以下文件

shell> cat install.yml
- debug:
    msg: Task 2
  tags: t2
- debug:
    msg: Task 3
  tags: t3
Run Code Online (Sandbox Code Playgroud)
  1. 剧本
shell> cat pb1.yml
- hosts: localhost
  tasks:
    - debug:
        msg: Task 1
      tags: t1
    - include_tasks:
        file: install.yml
Run Code Online (Sandbox Code Playgroud)

按预期工作

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 
Run Code Online (Sandbox Code Playgroud)

当使用标签时-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 
Run Code Online (Sandbox Code Playgroud)

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

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

playbook: pb1.yml

  play #1 (localhost): localhost    TAGS: []
      TASK TAGS: [t1]
Run Code Online (Sandbox Code Playgroud)
  1. 始终标记任务include_tasks
shell> cat pb2.yml
- hosts: localhost
  tasks:
    - debug:
        msg: Task 1
      tags: t1
    - include_tasks:
        file: install.yml
      tags: always
Run Code Online (Sandbox Code Playgroud)

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

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

playbook: pb1.yml

  play #1 (localhost): localhost    TAGS: []
      TASK TAGS: [always, t1]
Run Code Online (Sandbox Code Playgroud)

-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
Run Code Online (Sandbox Code Playgroud)
  1. 该标记始终导致当控制流到达include_task语句时始终包含文件install.yml。但此标记仅适用于include_task。它不会被文件内的任务继承。如果要将标签应用到文件内的任务,请使用参数apply。例如
shell> cat pb3.yml
- hosts: localhost
  tasks:
    - debug:
        msg: Task 1
      tags: t1
    - include_tasks:
        file: install.yml
        apply:
          tags: install
      tags: always
Run Code Online (Sandbox Code Playgroud)

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

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

playbook: pb3.yml

  play #1 (localhost): localhost    TAGS: []
      TASK TAGS: [always, t1]
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

但是,应用的标签不会帮助您单独触发包含的任务。最好理解的是,在include_task级别上如果没有相同的标签或特殊标签always,所应用的标签就没有意义。