Jak napisać procedurę obsługi Ansible z wieloma zadaniami?

81

W odpowiedzi na zmianę mam wiele powiązanych zadań, które powinny zostać uruchomione. Jak napisać procedurę obsługi Ansible z wieloma zadaniami?

Na przykład chciałbym, aby program obsługi ponownie uruchamiał usługę tylko wtedy, gdy została już uruchomiona:

- name: Restart conditionally
  shell: check_is_started.sh
  register: result

- name: Restart conditionally step 2
  service: name=service state=restarted
  when: result
timdiels
źródło

Odpowiedzi:

95

Od Ansible 2.2 istnieje prawidłowe rozwiązanie tego problemu.

programy obsługi mogą również „słuchać” tematów ogólnych, a zadania mogą powiadamiać te tematy w następujący sposób:

handlers:
    - name: restart memcached
      service: name=memcached state=restarted
      listen: "restart web services"
    - name: restart apache
      service: name=apache state=restarted
      listen: "restart web services"

tasks:
    - name: restart everything
      command: echo "this task will restart the web services"
      notify: "restart web services"

To użycie znacznie ułatwia wyzwalanie wielu programów obsługi. Oddziela również opiekunów od ich imion, ułatwiając dzielenie się opiekunami między scenariuszami i rolami

W szczególności w przypadku pytania powinno to działać:

- name: Check if restarted
  shell: check_is_started.sh
  register: result
  listen: Restart processes

- name: Restart conditionally step 2
  service: name=service state=restarted
  when: result
  listen: Restart processes

aw zadaniu powiadom obsługę za pomocą opcji „Uruchom ponownie procesy”

http://docs.ansible.com/ansible/playbooks_intro.html#handlers-running-operations-on-change

mkadan
źródło
1
Czy to rozwiązanie pozwoliłoby na użycie block: i rescue: do obsługi błędów poprzez uruchamianie poleceń?
user1767316
3
Czy wiele zadań jest wykonywanych w podanej kolejności? Jeśli jedno zadanie zależy od innego zadania, czy powinienem używać notify-listen wewnątrz programu obsługi?
user26767
@ user26767 z połączonej dokumentacji:Notify handlers are always run in the same order they are defined, not in the order listed in the notify-statement. This is also the case for handlers using listen.
swenzel
55

W pliku obsługi połącz ze sobą różne kroki za pomocą powiadomienia.

- name: Restart conditionally
  debug: msg=Step1
  changed_when: True
  notify: Restart conditionally step 2

- name: Restart conditionally step 2
  debug: msg=Step2
  changed_when: True
  notify: Restart conditionally step 3

- name: Restart conditionally step 3
  debug: msg=Step3

Następnie odwołaj się do tego zadania z notify: Restart conditionally.

Pamiętaj, że możesz powiadomić tylko osoby obsługujące poniżej obecnego. Na przykład Restart conditionally step 2nie mogę powiadomić Restart conditionally.

Źródło: #ansible na irc.freenode.net. Nie jestem pewien, czy to będzie nadal działać w przyszłości, ponieważ nie jest to wymienione jako funkcja w oficjalnej dokumentacji.

timdiels
źródło
Ta metoda pomaga w przypadku faktu, o którym wydaje się, że jest mało literatury: programy obsługi, po powiadomieniu, zostaną wykonane, nawet jeśli jeden z nich zawiedzie. Używanie różnych notifyetykiet dla tych, których możesz nie chcieć uruchamiać, jeśli poprzedni program obsługi zawiedzie, jest dobrym sposobem na „naprawienie” tego, jeśli nie chcesz, aby tak było.
fbicknel
27

Edycja: jeśli masz Ansible 2.2 lub nowszy, użyj odpowiedzi mkadana. Poniższa odpowiedź nie działa w nowszych wersjach Ansible. Zauważ również, że zgodnie z komentarzem Enisa Afgana poniżej, z powodu błędu, ta odpowiedź nie działa z wersjami Ansible między 2.0.2 a 2.1.2.


Począwszy od Ansible 2.0, możesz użyć akcji włączania w programie obsługi, aby uruchomić wiele zadań.

Na przykład umieść swoje zadania w osobnym pliku restart_tasks.yml(jeśli używasz ról, które trafią do podkatalogu zadań, a nie do podkatalogu obsługi):

- name: Restart conditionally step 1
  shell: check_is_started.sh
  register: result

- name: Restart conditionally step 2
  service: name=service state=restarted
  when: result

Twój przewodnik byłby wtedy po prostu:

- name: Restart conditionally
  include: restart_tasks.yml

Źródło: wątek problemowy na github: https://github.com/ansible/ansible/issues/14270

Alexander Klauer
źródło
5
Tylko uwaga, że ​​wersje Ansible między 2.0.2 a 2.1.2 mają błąd, w którym to nie działa: github.com/ansible/ansible/issues/15915
Enis Afgan
1
Dla przyszłych czytelników - to nie działa dla mnie w Ansible 2.9.2. Poprawka została wymianie includez include_tasks.
Martin Melka
@MartinMelka dzięki, dodałem ostrzeżenie w górnej części mojej odpowiedzi, że nie jest to przeznaczone dla wersji Ansible> = 2.2.
Alexander Klauer
Świetnie, dzięki :) Przy projektowaniu nowych handlerów druga odpowiedź jest lepsza. Ale kiedy kod inwentarzowy Ansible jest stary i trzeba wprowadzić tylko niewielkie zmiany (tak jak ja), Twój może być nadal przydatny z tym małym dodatkiem.
Martin Melka