簡単に言うと、ハンドラーは、notifyディレクティブを介してトリガーされた場合にのみ実行される特別なタスクです。 ハンドラーは、すべてのタスクが終了すると、プレイの最後に実行されます。

Ansibleでは、ハンドラーは通常、サービスの開始、リロード、再起動、および停止に使用されます。 プレイブックに構成ファイルの変更が含まれている場合、変更を有効にするためにサービスを再起動する必要がある可能性が高くなります。 この場合、そのサービスのハンドラーを定義し、そのサービスハンドラーを必要とするすべてのタスクにnotifyディレクティブを含める必要があります。

このシリーズの前のセクションでは、テンプレートを使用してデフォルトのNginxページをカスタムHTMLランディングページに置き換える方法を説明しました。 実際には、Nginx Webサーバーをセットアップするときに、sites-availableディレクトリに新しいサーバーブロックファイルを含めたり、シンボリックリンクを作成したり、サーバーのリロードまたは再起動が必要な設定を変更したりする可能性があります。

このようなシナリオを考慮すると、Nginxサービスを再起動するハンドラーは次のようになります。

...
  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted     

このハンドラーをトリガーするには、Nginxサーバーでの再起動が必要なタスクにnotifyディレクティブを含める必要があります。

次のプレイブックは、組み込みのAnsibleモジュール replace を使用して、Nginxの構成ファイルのデフォルトのドキュメントルートを置き換えます。 このモジュールは、regexpで定義された正規表現に基づいてファイル内のパターンを検索し、見つかった一致をreplaceで定義されたコンテンツに置き換えます。 次に、タスクはRestart Nginxハンドラーに通知を送信して、できるだけ早く再起動します。 つまり、再起動をトリガーする回数は関係ありません。再起動は、すべてのタスクの実行がすでに終了し、ハンドラーの実行が開始された場合にのみ発生します。 さらに、一致するものが見つからない場合、システムに変更は加えられないため、ハンドラーはトリガーされません。

ansible-practiceディレクトリにplaybook-12.ymlという名前の新しいファイルを作成します。

  1. nano ~/ansible-practice/playbook-12.yml

新しいプレイブックファイルに次の行を追加します。

ansible-practice /playbook-12.yml
---
- hosts: all
  become: yes
  vars:
    page_title: My Second Landing Page
    page_description: This is my second landing page description.
    doc_root: /var/www/mypage

  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: latest

    - name: Make sure new doc root exists
      file:
        path: "{{ doc_root }}"
        state: directory
        mode: '0755'

    - name: Apply Page Template
      template:
        src: files/landing-page.html.j2
        dest: "{{ doc_root }}/index.html"

    - name: Replace document root on default Nginx configuration
      replace:
        path: /etc/nginx/sites-available/default
        regexp: '(\s+)root /var/www/html;(\s+.*)?$'
        replace: \g<1>root {{ doc_root }};\g<2>
      notify: Restart Nginx

    - name: Allow all access to tcp port 80
      ufw:
        rule: allow
        port: '80'
        proto: tcp

  handlers:
    - name: Restart Nginx
      service:
        name: nginx
        state: restarted

完了したら、ファイルを保存して閉じます。

ハンドラーを使用する際に留意すべき重要な点の1つは、notifyトリガーを定義するタスクがサーバーに変更を加えた場合にのみハンドラーがトリガーされることです。 このプレイブックを考慮に入れて、replaceタスクを初めて実行すると、Nginx構成ファイルが変更されるため、再起動が実行されます。 ただし、後続の実行では、置き換えられる文字列がファイルに存在しなくなるため、タスクによって変更が発生したり、ハンドラーの実行がトリガーされたりすることはありません。

このプレイブックを実行する場合は、sudo権限が必要なため、-Kオプションを指定することを忘れないでください。

  1. ansible-playbook -i inventory playbook-12.yml -u sammy -K
Output
BECOME password: PLAY [all] ********************************************************************************************** TASK [Gathering Facts] ********************************************************************************** ok: [203.0.113.10] TASK [Install Nginx] ************************************************************************************ ok: [203.0.113.10] TASK [Make sure new doc root exists] ******************************************************************** changed: [203.0.113.10] TASK [Apply Page Template] ****************************************************************************** changed: [203.0.113.10] TASK [Replace document root on default Nginx configuration] ********************************************* changed: [203.0.113.10] TASK [Allow all access to tcp port 80] ****************************************************************** ok: [203.0.113.10] RUNNING HANDLER [Restart Nginx] ************************************************************************* changed: [203.0.113.10] PLAY RECAP ********************************************************************************************** 203.0.113.10 : ok=7 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

出力を見ると、プレイが終了する直前に「RestartNginx」ハンドラーが実行されていることがわかります。 ブラウザにアクセスしてサーバーのIPアドレスにアクセスすると、次のページが表示されます。

Screenshot showing the new landing page after update

このシリーズの次の最後のパートでは、すべての点を接続し、静的HTMLWebサイトをホストするためのリモートNginxサーバーのセットアップを自動化するプレイブックをまとめます。