複数のタスクを含むAnsibleハンドラーを作成するにはどうすればよいですか?


81

変更に応じて、実行する必要のある関連タスクが複数あります。複数のタスクを含むAnsibleハンドラーを作成するにはどうすればよいですか?

たとえば、すでに開始されている場合にのみサービスを再起動するハンドラーが必要です。

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

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

回答:


95

Ansible 2.2の時点で、この問題に対する適切な解決策があります。

ハンドラーは一般的なトピックを「リッスン」することもでき、タスクは次のようにそれらのトピックに通知できます。

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"

この使用により、複数のハンドラーをトリガーするのがはるかに簡単になります。また、ハンドラーを名前から切り離し、プレイブックやロール間でハンドラーを簡単に共有できるようにします。

特に質問に対して、これは機能するはずです:

- 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

タスクでは、「プロセスの再起動」を介してハンドラーに通知します

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


1
このソリューションでは、block:およびrescue:を使用して、コマンドを起動してエラーを処理できますか?
user1767316 2018

3
複数のタスクがリストされた順序で実行されていますか?あるタスクが別のタスクに依存している場合、ハンドラー内でnotify-listenを使用する必要がありますか?
user267 6720年

リンクされたドキュメントの@ user26767: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 2010

55

ハンドラーファイルで、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

次に、を使用してタスクからそれを参照しますnotify: Restart conditionally

現在のハンドラーより下のハンドラーにのみ通知できることに注意してください。したがって、たとえば、Restart conditionally step 2通知することはできませんRestart conditionally

出典:irc.freenode.netの#ansible。公式ドキュメントに機能として記載されていないため、これが今後も機能するかどうかはわかりません。


このメソッドは、文献がほとんどないように思われる事実に役立ちます。ハンドラーは、通知されると、それらのハンドラーの1つに障害が発生した場合でも実行されます。notify前のハンドラーが失敗した場合に実行したくないラベルに異なるラベルを使用することは、実行したくない場合にこれを「修正」するための良い方法です。
fbicknel

27

編集: Ansible 2.2以降を使用している場合は、mkadanの回答を使用してください。以下の答えは、Ansibleの新しいバージョンでは機能しません。また、以下のEnis Afganのコメントによると、バグのため、この回答は2.0.2から2.1.2までのAnsibleバージョンでは機能しないことに注意してください。


Ansible 2.0以降、ハンドラーでincludeアクションを使用して、複数のタスクを実行できます。

たとえば、タスクを別のファイルに配置しますrestart_tasks.yml(ロールを使用する場合は、handlersサブディレクトリではなくtasksサブディレクトリに移動します)。

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

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

その場合、ハンドラーは単純に次のようになります。

- name: Restart conditionally
  include: restart_tasks.yml

ソース:githubの問題スレッド:https//github.com/ansible/ansible/issues/14270


5
2.0.2と2.1.2の間のAnsibleバージョンには、これが機能しないバグがあることに注意してください:github.com/ansible/ansible/issues/15915
Enis

1
将来の読者のために-これはAnsible2.9.2では機能しませんでした。修正はに置き換えincludeられていましたinclude_tasks
マーティンメルカ

@MartinMelkaありがとうございます。回答の先頭に、Ansibleバージョン> = 2.2を対象としていないという警告を追加しました。
アレクサンダークラウアー

素晴らしい、ありがとう:)新しいハンドラーを設計するときは、他の答えの方が良いです。しかし、Ansibleインベントリコードが古く、(私が行ったように)小さな変更を加えるだけでよい場合でも、この小さな追加であなたのコードは役に立ちます。
マーティンメルカ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.