将其他角色的任务包括在可玩剧本中


72

我正在设计一种具有个别任务的剧本库

所以在通常的角色仓库中,我有类似以下内容:

roles
├── common
│   └── tasks
│       ├── A.yml
│       ├── B.yml
│       ├── C.yml
│       ├── D.yml
│       ├── login.yml
│       ├── logout.yml
│       └── save.yml
├── custom_stuff_workflow
│   └── tasks
│       └── main.yml
└── other_stuff_workflow
    └── tasks
        └── main.yml

我的custom.stuff_workflow中的main.yml然后包含以下内容:

---

- include: login.yml
- include: A.yml
- include: C.yml
- include: save.yml
- include: logout.yml

而另一个工作流程中的这个:

---

- include: login.yml
- include: B.yml
- include: A.yml
- include: D.yml
- include: save.yml
- include: logout.yml

我找不到自然的方法:一种可行的方法是将所有任务都放在一个角色中,并在包含custom_stuff_workflow的同时标记相关任务

我的问题是无法在调用的剧本中设置标签:只能在命令行中设置标签,因为我正在与公司中的许多人一起分发此可访问的仓库,我不能依靠命令行调用(最好#!在yml中有一个标头供ansible-playbook命令处理)

我还可以在每个工作流程中复制相关任务(在上一棵树的内部),但是我不想重复这些任务

有人可以看到解决方案来实现我想要的功能,而无需在不同角色上重复执行任务吗?

我想我的问题的基石是我将任务定义为个人,并且看起来不自然。

非常感谢

PS:请注意,工作流中的任务必须按特定顺序完成,抽象的唯一自然步骤就是登录和保存/注销

PPS:我已经看到了这个问题,如何在Ansible中从另一个角色中调用一个角色?但这并不能解决我的问题,因为它调用的是完整角色,而不是角色中的部分任务


根据coderwall.com/p/dlsjya/executable-playbooks,我们可以在yml文件顶部添加一个Shebang注释,但是同样,没有什么阻止某些同事直接ansible-playbook在文件上运行而不是将其作为可执行文件运行(在便携性问题)
路易(Louis

也许命令行可以是一个帮助者。我使用perl脚本来运行不同的剧本。(不完全相同)。脚本中的调用看起来像:ansible-playbook name_of_playbook --extra-vars "lots of vars" ,如果您可以指定同事的使用方式,那也许就是一种方式。
ThoFin 2015年

确实stackoverflow.com/users/4503915/thofin,但如果我能找到一个本地解决方案,那就更好了
路易(Louis)

Answers:


65

万一其他人碰到了这个问题,Ansible的2.2版现在有了include_role。您现在可以执行类似的操作。

---
- name: do something
  include_role:
    name: common
    tasks_from: login

此处查看文档。


1
这在处理程序内部不起作用。对于这些,您仍然需要使用tehK答案中的第(2)部分。
spiffytech '18

谢谢!那正是我想要的。使用此命令,我们现在可以创建一种共享任务库。现在,Ansible中还有更多的DRY原则。
realmaniek

1
现在,处理程序已包含在Ansible 2.8中
-bacrossland

您还可以在一个特设的方式与使用ansible ... -m include_role -a "name=common tasks_from=login"
埃德柯克

46

是的,Ansible不太喜欢将任务作为单独的组件。我认为它希望您使用角色,但是我可以明白为什么您不想将角色用于简单的可重用任务。

我目前看到两种可能的解决方案:

1.使这些任务文件成为角色并使用依赖项

然后您可以在custom_stuff_workflow中做类似的事情

dependencies:
  - { role: login }

请参阅:https//docs.ansible.com/playbooks_roles.html#role-dependencies

2.将包含与任务文件的“硬编码”路径一起使用

- include: ../../common/tasks/login.yml

在我刚刚做的一本简短的测试剧本中,效果很好。请记住,您还可以在其中包括参数等。

请参阅:http : //docs.ansible.com/ansible/latest/playbooks_reuse.html

我希望我正确理解了这个问题,对您有帮助。


5
感谢您的回答,我已经尝试了这两种解决方案,但显然它可能并不完美,我可能会选择第二种解决方案,但是硬编码路径的确不那么吸引人
路易(Louis)

第一种选择确实很好。很明显,每个角色都扮演什么角色,并迫使您将项目分解为较小的模块
-jonatan

5
如果我理解正确的话,依赖关系是不灵活的:它们角色之前运行。使用“包含”,您可以在角色内部的任何步骤运行包含的代码。
FuzzyAmi

包括支持参数。但是有什么办法可以使用registerinclude吗?
Shiplu Mokaddim 2015年

2
阅读了你们的尝试后,我将符号链接任务文件,而不是对路径进行硬编码。我错过了任何明显的缺点吗?
alanjds

0

使用include_role:with选项tasks_from是个好主意。但是,这仍然包括部分角色。例如,它加载角色变量和元依赖关系。如果apply用于应用于tags包含的文件,则将相同的标签应用于meta依赖项。另外,ansible输出在其输出中将其列为包含的角色名称,这很令人困惑。

可以使用来动态定位角色并包含文件first_found。可以找到角色路径搜索DEFAULT_ROLES_PATH并从tasks文件夹中加载文件。在存储角色时,Ansible使用相同的变量,只要角色在Ansible可以找到的路径中,就会加载文件。

这种方法include_role与with选项一样动态tasks_from

例:

- name: Include my_tasks.yml from my_ansible_role
  include_tasks: "{{lookup('first_found', params)}}"
  vars:
    params:
      files: my_ansible_role/tasks/my_tasks.yml
      paths: "{{ lookup('config', 'DEFAULT_ROLES_PATH') }}"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.