Event-Driven Ansible + Zabbix で実現する障害対応の自動化

皆様はEvent-Driven Ansible(以下EDA)をご存知でしょうか?通常のAnsibleでは人がPlaybookをコマンドラインやAutomation Controllerから実行します。一方で、EDAでは他のソフトウェア(監視システム等)からメッセージを受取り、そのメッセージの内容に応じて決められたジョブテンプレート・ワークフローを実行するというものになります。

EDAに関しての詳細は以下の記事をご参照ください。

今回の記事では、このEDAを用いて、日本で人気の高い Zabbix と連携して障害対応を自動化する例についてご紹介いたします。

EDA と Zabbix の連携には以下の特徴があり、非常に簡単に導入することができるのが嬉しい点になっています。

  • Zabbix には EDA連携の機能が含まれている
  • 既存の通知設定を変更するだけでEDAと連携可能になる(メール通知しているところにEDA連携を追加する、など)

ここからはZabbixとEDAの連携について動画を交えつつ、簡単に導入方法を紹介していきます。大まかな流れは以下になります。

  1. EDA環境を構築する → Event-Driven Ansible の始め方 をご参照ください
  2. ZabbixにEDA連携の設定を行う
  3. Zabbixからのメッセージを処理するルールブックと、起動するPlaybookを準備して、EDAでアクティベーションする

EDA環境の構築については、先の記事で紹介されておりますので、ZabbixにEDA連携の設定を行う部分から紹介していきます。

Zabbix の設定

Zabbixから設定方法のドキュメントが準備されていますので、そちらを参考に設定してきましょう。 https://www.zabbix.com/jp/integrations/ansible#event_driven_ansible

まずはEDA連携用のメディアタイプを追加します。

次に通知先のユーザーを作成し、連絡先をEDAサーバーに設定します。この時、EDAサーバーのポート番号はこのあとで作成するEDAのルールブックの中で決めることになります。あらかじめ、どのポートを使って連携するかを決めておきましょう。

最後にトリガーアクションを設定します。トリガーアクションは監視に対して、エラーが起きた場合のアクションを設定することができます。ここにトリガーが起動されたさいにユーザーへのメッセージ通知を行うように設定します。そして通知先のユーザーは先に作成したEDA用のユーザーになります。

Zabbix 側の準備はこれで終了となります。これでトリガーが起動されると、指定したEDAサーバーにメッセージが送信されるようになります。

ルールブックの設定

EDAではZabbixから送信されるメッセージに対応するルールを記述します。

執筆時点での Zabbix は以下のような形式のメッセージを送信してきます。

{'event': {'meta': {'endpoint': 'endpoint',
                         (省略)
                         'payload': {'HTTPProxy': '',
                                     'acknowledged': 'No',
                                     'endpoint': '/endpoint',
                                     'event_date': '2023.10.26',
                                     'event_datetime_timestamp': 1698281140,
                                     'event_id': 35,
                                     'event_name': 'VM2死活監視',
                                     'event_nseverity': 4,
                                     'event_object': 0,
                                     'event_severity': 'High',
                                     'event_source': 0,
                                     'event_tags': {},
                                     'event_time': '00:45:40',
                                     'event_value': 1,
                                     'host_groups': ['Linux servers'],
                                     'host_host': 'demo-hostB',
                                     'host_id': 10602,
                                     'host_ip': '172.31.0.155',
                                     'host_port': '10050',
                                     'monitoring_source': 'Zabbix sever',
                                     'operation_data': '0',
                                     'send_to': '11.22.33.44:8888',
                                     'subject': 'Event ID: 35, Host: '
                                                'demo-hostB, Problem: VM2死活監視',
                                     'trigger_description': '',
                                     'trigger_id': 23415,
                                     'trigger_name': 'VM2死活監視エラー'}}}}

ルールブックでは、このデータを使って判定を行い、対応するジョブテンプレートの起動を行うことになります。 例えば以下のようなルールブックになります。

---
- name: Listen for webhook 8888 and Debug
  hosts: all
  sources:
  - ansible.eda.webhook:
      host: 0.0.0.0
      port: 8888
  rules:
  - name: Trigger action of scenario 1
    condition: >-
      event.payload.host_host == 'demo-agent1'
      and event.payload.trigger_name == 'monitoring1_trigger1'
      and event.payload.event_severity == 'High'
    action:
      run_job_template:
        name: scenario1_action
        organization: Default
        job_args:
          extra_vars:
            z_host_name: "{{ event.payload.host_host }}"
            z_host_id: "{{ event.payload.host_id }}"
            z_event_id: "{{ event.payload.event_id }}"
            z_event_severity: "{{ event.payload.event_severity }}"
            z_trigger_name: "{{ event.payload.trigger_name }}"
  - name: Trigger action of scenario 2
    condition: >-
      event.payload.host_host == 'demo-agent1'
      and event.payload.trigger_name == 'monitoring2_trigger2'
      and event.payload.event_severity == 'High'
      (省略)

ルールブックの全体像

この例では、Zabbixからのメッセージをポート8888で待ち受け、メッセージに含まれる

  • event.payload.host_host 障害が発生したホストの名前
  • event.payload.trigger_name Zabbix側のトリガー名
  • event.payload.event_severity Zabbix側で設定した重要度

この3つを使って識別を行っています。 そして、ルールに合致した場合は、ジョブテンプレート scenario1_action をZabbixから受け取ったデータを引数に起動するようにしています。 逆にルールにマッチしない場合はEDAは何もおこないませんので、既存のZabbix監視に対して徐々に自動対応を行う設定を加えていくことができます(一気にすべてを作らなくてもよい)

あとは、このルールブックをアクティベーションし、対応するジョブテンプレート側を準備すれば完了です。

では実際に動かす例をみてみましょう。

EDA & Zabbix の動作デモ動画

このデモ動画では、EDAが動作した場合にRedmineにチケットを起こして記録するようにしてあります。

設定の確認

自動復旧の例

このデモは以下のような流れで動いています。

  1. Zabbix が障害を検知 → EDA へ通知を行う
  2. EDA が Zabbix からの受け取ったデータをルールブックで判定して、復旧するジョブテンプレートを実行
  3. Automation Controller から復旧を実行して、最後にRedmineへ結果を記載

承認したら自動復旧する例

このデモは以下のような流れで動いています。

  1. Zabbix が障害を検知 → EDA へ通知を行う
  2. EDA が Zabbix からの受け取ったデータをルールブックで判定して、復旧するジョブテンプレートを実行
  3. Automation Controller から復旧を実行するが、状態確認の段階で問題を検知
  4. Automation Controler は問題を検知したため、Redmine へ通知を行い、処理を「実行承認待ち」の状態で待機
  5. Redmine で通知されたチケットを確認する
  6. そのまま復旧を実行して良いと判断し「承認」を行い、停止していたジョブが再開し、障害が復旧
  7. 結果が Redmine へ通知

まとめ

ご紹介した内容の通り、EDA と Zabbix を連携させることで、監視システムが上げるアラートに対する自動対応を実現することが可能となります。 EDAを用いたアラート対応の自動化には、構築していく上で以下の利点があります。

  • 監視システム(Zabbix)と、自動化対応(Ansible)を疎結合にすることができる(監視をする組織と対処する組織の責任分界点を明確にでき、互いのシステムの影響を受けにくい状態を作れる)
  • 既に稼働している既存の監視システムにはほどんど影響がない(通知先にEDAを追加するだけ)
  • 徐々に自動対応の仕組みを作っていくことができる(小さく始められる)

またEDAはWebhookさえ発信してもらえれば連携可能なため、応用範囲がとても広い技術となります。 今回の記事ではZabbixとの連携を紹介しておりますが、他の監視ソフトウェアや、セキュリティ系の製品とも幅広くインテグレーションすることが可能です。

  • ネットワーク機器のコンフィグが変更されたらEDAを起動してAnsibleでNW機器の最新コンフィグを自動でバックアップする
  • セキュリティのアラートを検知したらEDAを起動してAnsibleで特定のIPを遮断する
  • 新しい機器のネットワーク接続を検知したらEDAを起動してAnsibleでCMDBへ登録する

といった活用も可能です。 ぜひともEvent-Driven Ansibleを活用した「自動対応」の仕組みにチャレンジしてみてください。

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。