运行Ansible角色而不运行角色元中定义的依赖项

时间:2016-10-12 15:41:30

标签: ansible ansible-playbook

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

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

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

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

有没有办法用角色执行一个Playbook,而不执行角色的依赖?

1 个答案:

答案 0 :(得分: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使用包含文件,则需要在剧本中使用块(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来控制它。但是,与为每个角色调用或任务文件定义标记相比,此类调试/测试逻辑会使您的代码库变得混乱。