Назад | Перейти на главную страницу

Избегайте повторения with_items в роли Ansible

У меня есть роль Ansible с несколькими задачами, которые я выполняю для нескольких виртуальных хостов. Моя playbook работает и выглядит так:

---

- 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 за каждое действие? Могу ли я перебирать элементы vhost для всей playbook, а не запускать каждую команду для всех vhosts последовательно? (как и я с приведенным выше кодом)

Судя по тому, что вы спрашиваете, похоже, что вы просто хотите указать группу vhosts в качестве хостов для выполнения определенной роли. Итак, ваша playbook должна начинаться примерно так:

---
- 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"

В настоящее время можно включить роль для каждого элемента в списке, используя include_role в петле. (Начиная с 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/tasks/main.yml

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