こんにちは!インフラの自動化とオブザーバビリティの追求にロマンを感じる、君の身近な先輩エンジニアです。
夜中にスマホが鳴り響き、「Zabbixからアラートです」という通知で叩き起こされる……。そして、慌ててPCを開いたら、すでにその障害は勝手に直っていて「なんだ、一過性の負荷か」とため息をつく。そんな不毛な経験、君はないかい?
僕たちは、アラートの奴隷になるためにエンジニアになったわけじゃない。「機械が検知し、機械が整理し、人間は本質的な解決にだけ集中する」。そんなモダンなオブザーバビリティの思想を、実は古くからある信頼の巨塔「Zabbix」でも実現できるんだ。
今回は、Zabbixの「Webhookメディアタイプ」をフル活用して、チャット(SlackやMicrosoft Teamsなど)へのリッチな通知、そしてPagerDutyやJira Service Managementといったインシデント管理ツールとの完全自動連携(チャットOps&自動起票・自動クローズ)を構築する方法を、魂を込めて解説しよう。
これをマスターすれば、毎日の運用作業が劇的に楽になるだけでなく、チームのMTTR(平均修復時間)を劇的に縮めることができる。さあ、一緒に扉を開けよう!
—
1. なぜ「従来のメール・古いスクリプト通知」を捨て、Webhookを使うのか?
まず、Zabbixの歴史を少し振り返ろう。昔のZabbixは、アラート飛躍の際にOS上でシェルスクリプトやPythonスクリプトをキックして、APIを叩かせていた。
これには、「ZabbixサーバーのOS内にスクリプトファイルを配置・管理しなきゃいけない」「依存ライブラリ(requestsなど)のバージョン管理が面倒」「複数環境へのデプロイがつらい」という、地味だけど確実なエンジニアのストレスがあったんだ。
Zabbixの「Webhookメディアタイプ(バージョン4.4以降で本格導入)」は、この悩みを一撃で解決する。
Zabbixサーバーの内部(JavaScriptエンジン)だけで完結してHTTPリクエストを飛ばせるため、外部スクリプトのファイル管理が一切不要になった。つまり、設定画面(UI)だけで完結するスマートなポータビリティを手に入れたというわけさ。
—
2. 全体アーキテクチャの理解:イベント駆動の自動化フロー
今回目指す世界線は以下の通りだ。
1. 障害検知 (Trigger): Zabbixが異常を検知。
2. Webhook発火 (Media Type): Zabbixの内蔵JSが走り、ペイロード(JSON)を組み立てる。
3. 外部連携 (API):
- チャット(Slack等): 誰が見ても一目でわかるリッチなカード通知を飛ばす。
- インシデント管理(PagerDuty / Jira): 自動でチケット/インシデントを起票し、担当者をアサインする。
4. 自動復旧 (Recovery): Zabbix側で障害が自動復旧(OK)すると、Webhookが「解決シグナル」を飛ばし、PagerDutyやJiraのインシデントを自動クローズする。
人間が「あ、直ったからJiraのステータスを『完了』にして……」とポチポチする手作業は、今日で卒業だ。
—
3. 実践!Webhookメディアタイプの設定と「心臓部」のJavaScript
百聞は一見にしかず。さっそくZabbixの管理画面をいじってみよう。
ここでは例として、汎用的なHTTPエンドポイント(またはチャット/PagerDuty等)へJSONを投げるための「基礎セットアップ」を解説する。
ステップ1: メディアタイプの作成
1. Zabbixフロントエンドにログインし、[管理 (Administration)] > [メディアタイプ (Media types)] に移動。
2. 右上の [メディアタイプの作成 (Create media type)] をクリック。
3. 以下のように設定する:
- 名前: `Modern Webhook Integrator`
- タイプ: `Webhook`
- パラメータ: 後述するJavaScriptに渡す変数を定義する。
【パラメータの定義例】
| 名前の設定 (Name) | 値の設定 (Value) |
| :— | :— |
| `url` | `https://api.pagerduty.com/incidents` (または連携先のWebhook URL) |
| `token` | `Bearer your-api-key-here` (認証トークン) |
| `event_source` | `{EVENT.SOURCE}` |
| `event_value` | `{EVENT.VALUE}` |
| `event_update_status` | `{EVENT.UPDATE.STATUS}` |
| `host` | `{HOST.NAME}` |
| `trigger_name` | `{TRIGGER.NAME}` |
| `event_id` | `{EVENT.ID}` |
—
ステップ2: 魂のJavaScriptコードを書く
メディアタイプ設定画面の下部にある「スクリプト (Script)」欄に、以下のコードを貼り付けてほしい。これは、障害発生(1)と復旧(0)、さらに更新イベントをハンドリングする、まさに心臓部だ。
// Zabbix Webhook Script: PagerDuty / Jira / Slack Unified Integration
try {
// 1. Zabbixから渡されたパラメータの取得
Z.debug(“Params raw: ” + JSON.stringify(value));
var params = JSON.parse(value);
var req = new HttpRequest();
// ヘッダーの設定(認証やコンテンツタイプ)
req.addHeader(‘Content-Type: application/json’);
if (params.token) {
req.addHeader(‘Authorization’, params.token);
}
// 2. ペイロード(送信データ)の構築
var payload = {};
// 障害発生時の処理 (Value: 1 = 障害, 0 = 復旧)
if (params.event_value === ‘1’ && params.event_update_status === ‘0’) {
payload = {
action: ‘trigger’,
summary: ‘[ALERT] ‘ + params.host + ‘: ‘ + params.trigger_name,
severity: ‘high’,
source: params.host,
custom_details: {
event_id: params.event_id,
source_system: ‘Zabbix’
}
};
}
// 復旧時の処理 (Value: 0 = 復旧)
else if (params.event_value === ‘0’) {
payload = {
action: ‘resolve’,
summary: ‘[RESOLVED] ‘ + params.host + ‘: ‘ + params.trigger_name,
custom_details: {
event_id: params.event_id
}
};
}
// 既知のアラートに対するコメント追加などのアップデート時
else {
// 必要に応じてコメント追加などのペイロードをここに書く
return ‘Update event ignored in this demo.’;
}
// 3. HTTP POST リクエストの実行
Z.debug(“Sending payload: ” + JSON.stringify(payload));
var resp = req.post(params.url, JSON.stringify(payload));
// レスポンスのハンドリング
if (req.getStatus() < 200 || req.getStatus() >= 300) {
throw ‘HTTP Failed with status: ‘ + req.getStatus() + “, response: ” + resp;
}
return ‘Successfully sent via Webhook. Response: ‘ + resp;
} catch (error) {
Z.error(“Webhook execution failed: ” + error);
// Zabbixのアクションログにエラーとして出力させる
throw ‘Webhook failed: ‘ + error;
}
> 先輩からのワンポイント解説:
> このスクリプトの美しいところは、`try…catch` でしっかりとエラーをキャッチし、Zabbixのエラーログ(監査ログ)に綺麗に残す設計にしている点だ。「なぜか通知が飛ばない」という現場でありがちなミステリーも、Zabbixのサーバーログを見れば一発で原因が特定できる。
—
4. PagerDuty / Jira Service Managementとの連携の神髄
個別のツール(PagerDutyやJira)と連携させる場合、先ほどのJavaScript内の `payload` のJSON構造を、それぞれの公式API仕様に合わせるだけでいい。
- PagerDuty連携のコツ:
PagerDuty Events API v2を使う場合、`payload` の中に `routing_key`(Integration Key)や `event_action: “trigger”` / `”resolve”` を含める必要がある。Zabbixの `{EVENT.ID}` をPagerDutyの `dedup_key` として利用するのが、自動クローズを完璧に動作させるための極意だ。これにより、Zabbig側で復旧イベント(`event_value = 0`)が起きた際、同じ `dedup_key` を指定して `event_action: “resolve”` を投げれば、PagerDuty側のインシデントが自動的に「Resolved(解決済)」になる。
- Jira Service Management連携のコツ:
JiraのREST APIを使う場合も同様に、障害発生時には `POST /rest/api/2/issue` で課題を起票し、その際に返却された `issue key`(例: `OPS-1234`)をZabbixのイベントタグやカスタムデータベースに保持させる。そして復旧時には、ステータス遷移トランジションを実行するAPIを叩く、あるいは課題をクローズするリクエストを送ることで、チケットの放置を防げる。
—
5. 精度高い「HelloWorld」的動作確認の手順
さあ、設定が終わったら実際に正しく動くかテストしよう。焦る必要はない。Zabbixには最高のテスト機能がついている。
1. メディアタイプの編集画面に戻り、一番下にある [テスト (Test)] ボタンを押す。
2. モーダル画面が開くので、先ほど定義したパラメータ(`url`, `token`, `event_value: 1` など)にダミーの値を入力する。
3. [テスト] を実行!
4. 画面下部に「Successfully sent via Webhook…」というレスポンスが表示されれば大成功だ!
もしここでエラーが出ても怖がるな。たいていはURLのタイポか、認証トークンのプレフィックス(`Bearer ` の有無など)のミスだ。デバッグログを見ながら一つずつ潰していこう。
最後に、実際のトリガーにこのメディアを割り当て、ダミーでCPU負荷を上げるなどして「実発火テスト」を行ってみてほしい。チャットにリッチなアラートが飛び、課題が起票され、負荷が下がったら綺麗にクローズされる——その瞬間を見たとき、君はきっと、インフラ監視の新しい扉を開けた快感に震えるはずだ。
—
おわりに:自動化の先にある未来
今回はZabbixのWebhookメディアタイプを活用した、チャットOpsとインシデント管理ツール連携の基礎と実装を解説した。
この仕組みを取り入れることで、夜間対応の精神的負荷は劇的に下がり、チーム全体で「どうやって障害を防ぐか」「どうやってシステムをより堅牢にするか」という生産的な議論に時間を使えるようになる。
手を動かして仕組みを作り上げる楽しさを、ぜひ今日の仕事に持ち帰ってみてほしい。
それじゃあ、また次の現場で会おう!