【问题标题】:Run Ansible role without running dependencies defined in the role's meta运行 Ansible 角色而不运行角色元数据中定义的依赖项
【发布时间】:2017-02-21 12:04:53
【问题描述】:

我有一个角色 wp-vhost,它依赖于一个角色:

// roles/wp-vhost/meta/main.yml
---
dependencies:
  - { role: nginx }

每次我运行wp-vhostnginx 角色也会运行。我知道这很好,这是一种理想的行为。

但是,在我的本地开发过程中,运行nginx 角色会不必要地浪费时间,因为我知道wp-vhosts 之前已经运行过并设置了wp-vhosts 中定义的任务。 wp-vhost 的必要环境。

有没有办法执行带有角色的剧本,而不执行角色的依赖关系?

【问题讨论】:

    标签: ansible ansible-playbook


    【解决方案1】:

    我这样做的方法是使用Ansible tags 并将它们应用于您的“wp-vhost”特定代码。

    假设您的wp-vhost 角色的主要剧本在main.yml 中,一个好的模式是将实际任务拆分成一个名为wp-vhost.yml 的子剧本,包含在main.yml 中,因此非nginx代码获得了一个没有应用到 nginx 角色的标签。在这种情况下:

    - include: wp-vhost.yml
      tags: wp-vhost
    

    为了对每块 Ansible 代码(无论是包含的任务文件还是角色)使用标签,请尝试编写 dependencies 中提到的每个角色,如下所示:

    - role: nginx
      tags: nginx
    

    在测试模式下,您可以像这样只运行 wp-vhost 特定部分:

     $ ansible-playbook --tags wp-vhost main.yml 
    

    或者你可以运行整个剧本,包括像这样的任何依赖项 - 默认是运行所有忽略标签的东西:

     $ ansible-playbook main.yml 
    

    这使得在测试时快速运行一组复杂的级联角色和包含文件的部分变得容易,并且还可以在其他角色的依赖项中正常使用 wp-vhost 角色。

    对角色结构的影响

    谨慎使用标签根本不会影响角色结构或使用,您通常只会将标签用于测试。

    对于更复杂的角色,通常在任何情况下将任务构造成单独的文件,保持 main.yml 简单,如下所示:

    - name: Set up base OS
      include: base_os.yml
      tags: base_os
    
    - name: Ensure logs are rotated
      include: logrotate.yml
      tags: logrotate
    
    - name: Create users and groups
      include: users_groups.yml
      tags: users_groups
    

    没有包含文件的解决方案

    如果您不想更改 wp-vhosts 对包含文件的使用,则需要使用 playbook 中的块(Ansible 2.0+):

    - hosts: all
    
      roles:
        - role: nginx
          tags: nginx
    
      tasks:
        - block:  
            - debug: msg=hello
            - someaction: ...
          tags: wp-vhosts
    

    请注意,最后的 tags:block: 对齐,因此适用于该块中的所有任务。这比将剧本分成多个剧本更干净。

    非标签替代

    您可以在 wp-vhost 角色依赖项中使用when: 条件on the role invocation,并定义诸如debug_mode 之类的变量来控制它。但是,与为每个角色调用或任务文件定义标签相比,这样的调试/测试逻辑会使您的代码库变得混乱。

    【讨论】:

    • 嗨@RichVel,上述方法本质上不等同于在角色元数据中为wp-vhost 角色定义任何依赖项吗?如果我将wp-vhostrole 变成一个单独的任务手册,它不再是一个可以共享、导入、定义为依赖项等的角色。我的目的是将wp-vhostnginx 维护为单独的角色而不是而不是单独的剧本/包含任务的集合。也许,我想要实现的目标(偶尔运行一个没有依赖关系的角色)在 Ansible 中是不容易实现的。除非我出错了。。
    • @luqo33 - 如果您不指定任何标签,则角色“按设计”与 nginx 依赖项一起工作。通常,仅当您希望使用快捷方式来运行角色/任务的一部分时才指定标签 - 标签是完全可选的,并且不会停止将角色用作依赖项。我已经用最后的例子更新了答案。
    • 再次感谢,我发现您的方法允许我在没有依赖关系的情况下运行角色。但是,有一点需要注意,主要是,如果主手册列出了角色而不是这样的任务:- {role: wp-vhosts, tags: [vhosts]},运行“vhosts”标签将始终运行角色依赖项,因为在这里,标签适用于整个角色(及其依赖项)。所以解决方案是去掉主剧本文件中的标签,而是将标签应用于该角色的各个任务(最好使用建议的包含语句)。因此,会对角色结构产生影响。
    • 这是有道理的,因为单个游戏将其标签级联到其中的角色和任务。我已经编辑了我的答案,以展示如何使用块来完成此操作,因此只有任务获得标签,而不会在每个任务上分配容易出错的标签。
    • 我个人投票赞成大量使用when:。您只需检查系统上是否存在 nginx(甚至是特定版本),如果是,则将跳过该依赖项。如果版本不匹配,则将擦除旧版本并安装新版本。恕我直言,这是一种更具“战略性”的方法。
    猜你喜欢
    • 1970-01-01
    • 2017-02-12
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多