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

Ansible: хост появляется более чем в одной группе, и в обеих группах есть одинаковые задачи; какой способ запустить задачи один раз?

У меня есть сценарий, который выглядит примерно так:

---
- hosts: group1
  roles:
    - role1
    - role2

- hosts: group2
  roles:
    - role2
    - role3

Теперь предположим, что у меня есть файл hosts с такой записью:

[group1]
host1.example.com

[group2]
host1.example.com

Ansible будет запускать задачи в role2 ДВАЖДЫ для host1.example.com, потому что он представлен в 2 группах, и каждой из них назначена role2.

Как я могу заставить Ansible понять, что одна и та же роль включена дважды, и поэтому он должен запускать ее только один раз?

Как уже упоминалось, это сделано специально. Ansible выполняет только одну игру за раз. Ваш playbook состоит из двух пьес (два элемента в списке YAML корневого уровня, определенном файлом playbook). Первая игра применяет role1 и role2 к group1. Эта игра выполняется первой, и только после ее завершения начинается вторая игра. Но Ansible не пытается логически объединить пьесы. В конце концов, вы можете захотеть, чтобы задачи в role2 выполнялись дважды.

Что касается решения проблемы, вы можете обойти ее несколькими способами, и выбор зависит от деталей групп и ролей.

Если все задачи в role2 являются идемпотентными, т.е. если они могут выполняться несколько раз и каждый раз приводить к одному и тому же результату, то все, что вы действительно теряете, - это время, и можно позволить ролям повторяться. Если на применение ролей уходит очень много времени или если вы не можете сделать их идемпотентными, рассмотрите следующие идеи:


Вы можете разделить сценарий на три пьесы и применять роли индивидуально:

---
- hosts: group1
  roles:
    - role1

- hosts: group1:group2
  roles:
    - role2

- hosts: group2
  roles:
    - role3

Или, если ваши роли необходимо сгруппировать вместе, вы можете создать третью группу для серверов, которым нужны все три роли. Их не нужно исключать из двух других групп. Вы можете создать группу в файле инвентаря следующим образом:

[group1and2:children]
group1
group2

Затем в своей книге вы можете снова разделиться на три пьесы, но используйте третью группу, чтобы избежать повторения ролей:

---
- hosts: group1:!group1and2
  roles:
    - role1
    - role2

 - hosts: group1and2
   roles:
     - role1
     - role2
     - role3

 - hosts: group2:!group1and2
   roles:
     - role2
     - role3

Это довольно некрасиво, но в некоторых случаях может быть полезно.

Это сделано намеренно. Единственный способ - применить role2 только в одной playbook к одной конкретной группе, а не использовать role2 в любой другой playbook в группе, которая может иметь общих членов, как здесь.