Wie schreibe ich einen Ansible-Handler mit mehreren Aufgaben?

80

Als Reaktion auf eine Änderung habe ich mehrere verwandte Aufgaben, die ausgeführt werden sollten. Wie schreibe ich einen Ansible-Handler mit mehreren Aufgaben?

Zum Beispiel möchte ich einen Handler, der einen Dienst nur neu startet, wenn er bereits gestartet ist:

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

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

Antworten:

94

Ab Ansible 2.2 gibt es eine geeignete Lösung für dieses Problem.

Handler können auch allgemeine Themen „anhören“, und Aufgaben können diese Themen wie folgt benachrichtigen:

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"

Diese Verwendung erleichtert das Auslösen mehrerer Handler erheblich. Außerdem werden Handler von ihren Namen entkoppelt, wodurch es einfacher wird, Handler zwischen Spielbüchern und Rollen zu teilen

Speziell für die Frage sollte dies funktionieren:

- 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

und benachrichtigen Sie in der Aufgabe die Handler über "Prozesse neu starten".

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

mkadan
quelle
1
Würde diese Lösung die Verwendung von Block: und Rescue: zur Behandlung von Fehlern durch Starten von Befehlen ermöglichen?
user1767316
3
Werden die mehreren Aufgaben in der angegebenen Reihenfolge ausgeführt? Wenn eine Aufgabe von einer anderen Aufgabe abhängt, sollte ich im Handler notify-listen verwenden?
user26767
@ user26767 aus der verlinkten Dokumentation: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

Verketten Sie in Ihrer Handler-Datei die verschiedenen Schritte mit notify.

- 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

Dann beziehen Sie sich auf eine Aufgabe mit notify: Restart conditionally.

Beachten Sie, dass Sie nur Handler unter dem aktuellen benachrichtigen können. So kann zum Beispiel Restart conditionally step 2nicht benachrichtigen Restart conditionally.

Quelle: #ansible bei irc.freenode.net. Ich bin mir nicht sicher, ob dies auch in Zukunft funktionieren wird, da dies in der offiziellen Dokumentation nicht erwähnt wird.

timdiels
quelle
Diese Methode hilft bei einer Tatsache, für die es anscheinend wenig Literatur gibt: Handler werden nach Benachrichtigung ausgeführt, selbst wenn einer dieser Handler ausfällt. Die Verwendung unterschiedlicher notifyBeschriftungen für diejenigen, die Sie möglicherweise nicht ausführen möchten, wenn ein vorheriger Handler ausfällt, ist eine gute Möglichkeit, dies zu "beheben", wenn Sie dies nicht möchten.
fbicknel
27

Bearbeiten: Wenn Sie Ansible 2.2 oder höher haben, verwenden Sie die Antwort von mkadan. Die folgende Antwort funktioniert nicht mit neueren Versionen von Ansible. Beachten Sie auch, dass diese Antwort gemäß dem Kommentar von Enis Afgan aufgrund eines Fehlers nicht mit Ansible-Versionen zwischen 2.0.2 und 2.1.2 funktioniert.


Ab Ansible 2.0 können Sie eine Include-Aktion in Ihrem Handler verwenden, um mehrere Aufgaben auszuführen.

Legen Sie Ihre Aufgaben beispielsweise in einer separaten Datei ab restart_tasks.yml(wenn Sie Rollen verwenden, werden diese in das Unterverzeichnis "Aufgaben" und nicht in das Unterverzeichnis "Handler" verschoben):

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

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

Ihr Handler wäre dann einfach:

- name: Restart conditionally
  include: restart_tasks.yml

Quelle: Issue-Thread auf Github: https://github.com/ansible/ansible/issues/14270

Alexander Klauer
quelle
5
Nur ein Hinweis, dass Ansible-Versionen zwischen 2.0.2 und 2.1.2 einen Fehler haben, bei dem dies nicht funktioniert: github.com/ansible/ansible/issues/15915
Enis Afgan
1
Für zukünftige Leser - das hat bei Ansible 2.9.2 bei mir nicht funktioniert. Das Update wurde ersetzt includemit include_tasks.
Martin Melka
@MartinMelka danke, ich habe oben in meiner Antwort eine Warnung hinzugefügt, dass sie nicht für Ansible-Versionen> = 2.2 gedacht ist.
Alexander Klauer
Großartig, danke :) Beim Entwerfen neuer Handler ist die andere Antwort besser. Aber wenn der Ansible-Inventarcode alt ist und man nur kleine Änderungen vornehmen muss (wie ich), kann Ihr Code mit dieser kleinen Ergänzung trotzdem nützlich sein.
Martin Melka