我有一个 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 开始,建议用来代替loop
。with_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