避免在 Ansible 角色中重复使用“with_items”

避免在 Ansible 角色中重复使用“with_items”

我有一个 Ansible 角色,其中包含一些我为多个虚拟主机运行的任务。我的剧本有效,如下所示:

---

- name: Create vhost configuration
  # action
  with_items: vhosts

- name: Ensure vhost is enabled
  # action  
  notify: restart apache2
  with_items: vhosts

# (Many more actions)

有没有办法避免with_items为每个操作编写代码?我可以遍历整个剧本的虚拟主机项,而不是按顺序为所有虚拟主机运行每个命令吗?(就像我使用上面的代码一样)

答案1

从您的询问来看,您似乎只想指定 vhosts 组作为运行特定角色的主机。因此您的剧本应该以如下方式开始:

---
- hosts: vhosts
  name: Tasks run on vhosts
  roles:
    - { role: somerole }

请记住,你的剧本中可以有多个剧本,因此执行以下操作是完全可以的:

---
- hosts: all
  name: Run roles for all servers
  roles:
    - { role: role1 }
    - { role: role2 }
    - etc.

- hosts: vhosts
  name: Run roles specific to vhosts
  roles:
    - { role: vhost-role }

- hosts: all
  name: Post-vhost roles for all servers
  roles:
    - { role: role3 }
    - etc.

如果您有一个剧本,并且想要在不同时间在不同主机组上运行,那么您可以对主机条目使用一个变量:

---
- hosts: "{{ somevar }}"
  name: Run roles against a user specified set of hosts
  roles:
    - { role: foo }

然后您可以通过以下方式之一调用最后一个:

$ ansible-playbook playbook.yml --extra-vars "somevar=vhosts"

$ ansible-playbook playbook.yml --extra-vars "somevar=host1,host2"

答案2

现在可以为列表中的每个项目添加一个角色,方法是使用包括角色循环中。(从 Ansible 2.5 开始,建议用来代替loopwith_items

首先,创建一个角色,该角色对 vhosts 列表中的每个项目进行子角色迭代:

# vhosts/tasks/main.yml

- name: Iterate over all vhosts
  loop: "{{ vhosts }}"
  include_role:
    name: vhost
  vars:
    vhost: "{{ item }}"

对于每个 vhost,vhost都会调用该角色,并使用一个vhost包含其数据的变量进行调用。

然后,您可以编写一系列对此进行操作的任务,如下所示:

# vhost/tasks/main.yml

- name: Create vhost html directory
  file:
    path: "/var/www/vhosts/{{ vhost.domain }}/html"
    state: directory

相关内容