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-tags
的ansible-剧本在这方面,答案是否定的。但是,这样的标签可能是可用的(在控制流到达include_task
语句)如果也在级别上指定包括_任务。此外,特殊标签总是使此类标签可用。
问:“实现这一目标的最佳做法是什么?”
答:有两种选择:
要么使用
import_tasks
. 剧本启动时会读取导入内容。或者使用特殊标签总是。Ansible 将始终包含来自该文件的任务。
为了澄清差异。给出以下文件
shell> cat install.yml
- debug:
msg: Task 2
tags: t2
- debug:
msg: Task 3
tags: t3
- 剧本
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]
- 标签总是任务包括任务
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
- 标签总是导致文件安装.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: always
在include_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 download
install
答案3
我推荐 Red Hat 的关于此问题的帖子:https://www.redhat.com/sysadmin/ansible-tags-fast-playbook-runs