首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理角色、任务、依赖关系的正确方法?

处理角色、任务、依赖关系的正确方法?
EN

Server Fault用户
提问于 2019-11-13 03:42:52
回答 1查看 2.7K关注 0票数 2

Ansible -处理角色、任务、依赖关系的适当方法?

当作为依赖项列出时,如何防止ansible角色多次运行?相关

这是一个很长的问题。TL;DR -设置角色和任务标记的正确方法是什么,这样依赖关系就可以正常工作,而无需多次运行角色。

参见可测测试装置以获得说明这些问题的游戏手册设置.

我在让剧本很好地处理标签和依赖关系方面遇到了一些困难。一般来说,我想要一本有很多角色的剧本(每个角色都有一些依赖项)来“干净地工作”。这本身就相当容易设置,并且在使用整个剧本中的所有角色时工作得很好。具有依赖关系的角色可以按剧本中的任意顺序定义,这些依赖关系确保它们按照正确的顺序运行。当然,没有依赖项的角色将按照它们在剧本角色:部分中出现的顺序运行。

但有时人们只想运行角色的一个子集,然后就会分崩离析,有些角色会多次运行,顺序也会很奇怪。

因此,我构建了一个测试设置,包含4个角色(A、B、C、D),并使用了多种标记方法。实际上,它是4个角色,有无标记的任务,4个角色有标记的任务.加上一个名为'z‘的角色,它没有任务,只是所有其他角色的依赖关系。它们看起来是这样的:

代码语言:javascript
复制
Role name    Dependencies
----------   ------------
a_tagged     none
b_tagged     a_tagged
c_tagged     b_tagged
d_tagged     c_tagged b_tagged a_tagged
z_tagged     a_tagged b_tagged c_tagged d_tagged
a_untagged   none
b_untagged   a_untagged
c_untagged   b_untagged
d_untagged   c_untagged b_untagged a_untagged
z_untagged   a_untagged b_untagged c_untagged d_untagged

我知道这看起来很麻烦,但我们试着测试4种组合:

代码语言:javascript
复制
Role config         Tasks config
-----------         ------------
Role IS tagged      Tasks are NOT tagged
Role IS tagged      Tasks ARE tagged
Role is NOT tagged  Tasks are NOT tagged
Role is NOT tagged  Tasks ARE tagged

每个角色任务/main.yml如下所示--在本例中,角色"b_tagged“只有一个任务,该任务被标记为”标记: b“

./roles/b_tagged/tasks/main.yml

代码语言:javascript
复制
---
- debug: msg="Role B tagged"
  tags: b

并且相关的meta/main.yml如下所示,因此角色b_tagged依赖于角色a_tagged:

./roles/b_tagged/meta/main.yml

代码语言:javascript
复制
---
dependencies:
  - { role: a_tagged }

相应的b_untagged样式任务是相同的,但没有任务中的“标记:”行。

期望的结果是角色按照A、B、C、D的顺序执行,每个角色只运行一次,如下所示:

代码语言:javascript
复制
    "msg": "Role A ..."
    "msg": "Role B ..."
    "msg": "Role C ..."
    "msg": "Role D ..."

为了提供仅显示调试msg:输出的最小输出,脚本"test.sh“只运行,如下所示。无论您在哪里看到test.sh,它都只是运行这个命令。

ANSIBLE_STDOUT_CALLBACK=minimal ansible-playbook -i hosts test.yml $@ -- | egrep -v "{|}"

有四种主要的方案来运行这些剧本..。

  • 运行每个角色,默认情况下使用./test.sh
  • 使用“z”标记选择每个角色/任务,运行每个角色。请记住,“z”角色只有所有其他角色作为依赖项./test.sh --tags 'z'
  • 只对“c”标记的角色/任务运行每个剧本,这应该只运行角色A、B、C、./test.sh --tags 'c'
  • 只对“b”和“c”标记的角色/任务运行每个剧本--这应该只运行角色A、B、C、./test.sh --tags 'b,c'

剧本文件test.yml中的每一个剧本都是这样的:(这是第一个)

./test.yml

代码语言:javascript
复制
###########################################################################################
# roles with NO tags and tasks WITH tags, roles defined in reverse order from dependencies.
- hosts: localhost
  gather_facts: false
  become: no

  pre_tasks:
    - debug:
        msg: "=============== untagged roles z d c b a tagged tasks reverse ========"
      tags: always

  roles:
    - role: z_tagged
    - role: d_tagged
    - role: c_tagged
    - role: b_tagged
    - role: a_tagged
###########################################################################################

因为只有角色定义改变了每个剧本(和msg: string),这就是这里列出的test.yml剧本文件中其他剧本的全部内容

代码语言:javascript
复制
* roles with NO tags and tasks with NO tags, roles defined in reverse order from dependencies
    - role: z_untagged
    - role: d_untagged
    - role: c_untagged
    - role: b_untagged
    - role: a_untagged

* roles WITH tags and tasks WITH tags, roles defined in correct order from dependencies
    - { role: a_tagged, tags: a }
    - { role: b_tagged, tags: b }
    - { role: c_tagged, tags: c }
    - { role: d_tagged, tags: d }
    - { role: z_tagged, tags: z }

* roles WITH tags and tasks WITH tags, roles defined in reverse order from dependencies
    - { role: z_tagged, tags: z }
    - { role: d_tagged, tags: d }
    - { role: c_tagged, tags: c }
    - { role: b_tagged, tags: b }
    - { role: a_tagged, tags: a }

* roles WITH tags and tasks with NO tags, roles defined in correct order from dependencies
    - { role: a_untagged, tags: a }
    - { role: b_untagged, tags: b }
    - { role: c_untagged, tags: c }
    - { role: d_untagged, tags: d }
    - { role: z_untagged, tags: z }

* roles WITH tags and tasks with NO tags, roles defined in reverse order from dependencies
    - { role: z_untagged, tags: z }
    - { role: d_untagged, tags: d }
    - { role: c_untagged, tags: c }
    - { role: b_untagged, tags: b }
    - { role: a_untagged, tags: a }

运行上述4种场景将产生以下输出。

./test.sh无论单个任务是否被标记,(只要角色没有标记),结果都是正确的输出(前两次播放)。如果角色确实有标记,那么角色将多次运行(如下面的4个角色所示),顺序取决于它们在剧本中定义的顺序。

正确的示例- role: a_tagged- role: a_untagged角色顺序并不重要

代码语言:javascript
复制
"msg": "=============== untagged roles z d c b a tagged tasks reverse ========"
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role D tagged"
"msg": "=============== untagged roles z d c b a untagged tasks reverse ======"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role D untagged"
"msg": "=============== tagged roles a b c d z tagged tasks =================="
"msg": "Role A tagged"
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role C tagged"
"msg": "Role D tagged"
"msg": "Role D tagged"
"msg": "=============== tagged roles z d c b a tagged tasks reverse =========="
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role D tagged"
"msg": "Role D tagged"
"msg": "Role C tagged"
"msg": "Role B tagged"
"msg": "Role A tagged"
"msg": "=============== tagged roles a b c d z untagged tasks ================"
"msg": "Role A untagged"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role C untagged"
"msg": "Role D untagged"
"msg": "Role D untagged"
"msg": "=============== tagged roles z d c b a untagged tasks reverse ========"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role D untagged"
"msg": "Role D untagged"
"msg": "Role C untagged"
"msg": "Role B untagged"
"msg": "Role A untagged"

./test.sh --tags 'z'在使用'z‘标记选择所有角色/任务时,只有带有标记的角色扮演:在定义中生成正确的输出。如果角色没有被标记,那么该角色中的任务就永远不会执行,不管它们是否被标记。

正确的示例- { role: a_tagged, tags: a }- { role: a_untagged, tags: a }角色顺序并不重要

代码语言:javascript
复制
"msg": "=============== untagged roles z d c b a tagged tasks reverse ========"
"msg": "=============== untagged roles z d c b a untagged tasks reverse ======"
"msg": "=============== tagged roles a b c d z tagged tasks =================="
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role D tagged"
"msg": "=============== tagged roles z d c b a tagged tasks reverse =========="
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role D tagged"
"msg": "=============== tagged roles a b c d z untagged tasks ================"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role D untagged"
"msg": "=============== tagged roles z d c b a untagged tasks reverse ========"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "Role D untagged"

./test.sh --tags 'c'只运行一个选定的角色(及其依赖项),唯一正确的输出是对角色进行标记,而任务没有标记(最后两种情况)。

正确的示例- { role: a_untagged, tags: a }角色的顺序并不重要

代码语言:javascript
复制
"msg": "=============== untagged roles z d c b a tagged tasks reverse ========"
"msg": "Role C tagged"
"msg": "=============== untagged roles z d c b a untagged tasks reverse ======"
"msg": "=============== tagged roles a b c d z tagged tasks =================="
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "Role C tagged"
"msg": "=============== tagged roles z d c b a tagged tasks reverse =========="
"msg": "Role C tagged"
"msg": "Role A tagged"
"msg": "Role B tagged"
"msg": "Role C tagged"
"msg": "=============== tagged roles a b c d z untagged tasks ================"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"
"msg": "=============== tagged roles z d c b a untagged tasks reverse ========"
"msg": "Role A untagged"
"msg": "Role B untagged"
"msg": "Role C untagged"

./test.sh --tags 'b,c'只运行两个选定的角色(以及它们的依赖项),没有正确的输出。

注意:所有配置都不会产生只运行角色"A“

所需的结果

代码语言:javascript
复制
    "msg": "=============== untagged roles z d c b a tagged tasks reverse ========"
    "msg": "Role B tagged"
    "msg": "Role C tagged"
    "msg": "=============== untagged roles z d c b a untagged tasks reverse ======"
    "msg": "=============== tagged roles a b c d z tagged tasks =================="
    "msg": "Role A tagged"
    "msg": "Role B tagged"
    "msg": "Role B tagged"
    "msg": "Role C tagged"
    "msg": "Role C tagged"
    "msg": "=============== tagged roles z d c b a tagged tasks reverse =========="
    "msg": "Role B tagged"
    "msg": "Role C tagged"
    "msg": "Role A tagged"
    "msg": "Role C tagged"
    "msg": "Role B tagged"
    "msg": "=============== tagged roles a b c d z untagged tasks ================"
    "msg": "Role A untagged"
    "msg": "Role B untagged"
    "msg": "Role B untagged"
    "msg": "Role C untagged"
    "msg": "=============== tagged roles z d c b a untagged tasks reverse ========"
    "msg": "Role A untagged"
    "msg": "Role B untagged"
    "msg": "Role C untagged"
    "msg": "Role B untagged"

结论..。处理这两种依赖关系(运行整个剧本(所有角色)或只运行角色子集)的唯一方法是确保用于选择的标记仅在角色定义中,而不是在任务本身上。例如:

代码语言:javascript
复制
    - { role: a_untagged, tags: a }

任务上的任何标记只应用于任务,而不应用于任何角色选择。即使如此,这只在选择一个角色/标签通过-标记'c‘运行时才能运行,并且在最后一个示例显示的多个带标签'b,c’的情况下失败。

在test.yml剧本文件中,这是最后两个剧本(角色顺序不重要)。所有其他变体都不会产生正确的结果。似乎没有理由使用标记:在任务本身上,至少如果您希望角色/任务选择能够处理依赖关系,而不需要多次执行的话。

EN

回答 1

Server Fault用户

发布于 2019-11-19 15:09:14

我没有确切的答案给你,但是“不要像木偶一样抱着Ansible”;-)

我可以想象这种依赖关系的需求,但您也可能想一想:我可以自己管理依赖关系吗?

我也经历过这样的经历:一本加载角色logstashtomcat的剧本。两者都需要角色java。我们的Java角色也有元依赖关系。因此,角色java将在主机部署中执行两次(以及我们的java-角色的依赖性)。

代码语言:javascript
复制
---
- hosts: myhost
  roles:
    - role: logstash
    - role: tomcat8

我们通过这样做解决了这个问题:

代码语言:javascript
复制
---
- hosts: myhost
  roles:
    - role: java
    - role: logstash
    - role: tomcat8

将角色java的依赖关系从角色logstashtomcat中删除。这样,java get只在运行剧本时推出一次。

当您知道和控制您自己的工具并且希望保持它简单,而不是复杂时,这个解决方案可能会有所帮助。

票数 1
EN
页面原文内容由Server Fault提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://serverfault.com/questions/991605

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档