Mackerel のイベント通知をAWSへ連携しやすくなったので試してみた【Amazon EventBridge】

昨年発表されたAmazon EventBridgeに、我らがMackerelもさっそうと対応を開始しました! さっそく試してみたのでご報告します。mackerel-agentのcheck-portプラグイン(TCPポート監視)のアラートをひろってEC2インスタンスを再起動してみます。
2020.01.29

先週、Mackerel が Amazon EventBridge に対応したことが発表されました!

簡単に言うと、Mackerel のアラート通知を AWS 側に送信・連携処理がしやすくなったということです。
AWS 側では Mackerel からのアラートを受けて、EC2 に対する定型処理を実行したり、Lambda や AWS Systems Manager などで処理したりすることが可能です。

何はともあれ、いちどやってみました!

概要 - EventBridge について

Amazon EventBridge についてはここでは詳しく説明しません。下記資料・ BlackBelt をご覧ください。

Mackerel との連携は「パートナーイベント」ということで、図にすると下記の部分が該当します。

(※こちら「仕組み」の図 に加筆させてもらいました)

ドキュメントはこちらですね。

ちなみに Mackerel からは現在、以下をトリガーに EventBridge にイベントを飛ばすことが可能です。

  • アラート通知・アラートグループ通知
  • ホストステータス変更(Working,Standby,Maintenance,Power Off)
  • ホスト登録
  • ホスト退役
  • 監視ルールの操作

つまり、Mackerel の検知したアラートや、ホストに対する何かしらの操作をトリガーに AWS で何か処理をさせることが可能ということですね。
ぱっと思いつくところだと、アラート検知で EC2 インスタンス再起動とか、ホストのステータス変更によって ELB から外したり戻したり。。みたいな感じでしょうか。実際に組もうとすると難しいところもある(後述します)のですが、これまでに比べて格段と Mackerel - AWS 連携がしやすくなったのではないでしょうか。

手順

それではざっくり説明しつつやってみます。ひとまず「ホスト ec2host001 において、ポート監視失敗を検知したら、EC2 を再起動 (Reboot) する」ということをやってみたいと思います。
手順は以下の 3 ステップになります。

  1. パートナーイベントソースの作成
  2. パートナーイベントバスを作成、パートナーイベントソースと関連付け
  3. イベントのルールを作成

このうち 1. が Mackerel での操作、2.と 3.が AWS での操作になります。
ちなみに既に、ポート監視(25/TCP)のチェック監視は設定済みとします。

1. パートナーイベントソースの作成

Mackerel の場合、以下の手順になります。

  • 通知チャネル(Amazon EventBridge)を作る
  • 作った通知チャネルを、検知する監視ルールが所属する通知グループに所属させる

通知チャネルの作成については、下記のドキュメントに従って作成します。

今回は「mackerel-ec2-reboot-ec2host001」という名前で作成しました。
イベントソース名(Event source name)も同じくmackerel-ec2-reboot-ec2host001にしています。

今回は他の通知とごちゃ混ぜになるのを避けるため、ポート監視のためのチェック監視 tcp_localhost_25 だけが所属する監視グループを作成しました。

2. パートナーイベントソースとイベントバスの関連付け

ここから AWS 側の設定になります。
上の手順が完了していれば、Amazon EventBridge > イベント > パートナーイベントソース のところに、以下の名前でパートナーイベントソースが出来ているかと思います。

  • aws.partner/mackerel.io/<オーガニゼーション名>/mackerel-ec2-reboot-ec2host001

もし出てきていないようなら、画面を再読み込みしたり少し待ったりしてみてください。
AWS アカウント ID やリージョンに誤りがないかの確認も行うといいですね。

ステータスが「保留中」となっていると思うので、イベントバスと関連付けます。アクセス許可などの設定変更は不要なので、そのまま関連付けて下さい。

3. イベントのルールを作成

それではルールを作成します。
Amazon EventBridge > イベント > ルール の画面で、イベントソースに作ったばかりのイベントバスを選択します。

続いて「ルールを作成」をクリックします。
ルール作成画面がひらくので、ここでルールを作っていきます。

名前は適当に、ここでは Mackerel 側と関連がわかりやすいように mackerel-ec2-reboot-ec2host001 としました。

パターンとしてはイベントパターンを選択。
残念ながらまだ Mackerel 用の事前定義パターンは内容なので('20/01 現在)、カスタムパターンを選択します。

このパターンは、送信されてきた JSON の特定の項目 (Key) に、事前に設定した値 (Value) が定義されているかどうかで判断されます。
ここではホストが Working ステータスかどうか、アラートが Open したときの通知かどうか、の 2 つだけチェックします。こちらのドキュメント に書かれている JSON の内容がdetailキーの値として入ってきますので、ルールとしては下記のようになります。

{
  "detail": {
    "host": {
      "status": [ "working" ]
    },
    "alert": {
      "isOpen": [ true ]
    }
  }
}

イベントバス(パートナーイベントバス)は、先ほど作成したものを指定。

ターゲットですが、当初の予定通り EC2 RebootInstances API 呼び出しを選択します。インスタンス ID として、Mackerel で監視しているホストのインスタンス ID を記入します。

ロールについては、今回は初めての実行なので、「新しいロールを作成する」を選択しましょう。タグについては任意で大丈夫です。

問題なければ作成をクリックして下さい。

試してみる

では、実際に 25/TCP ポートをダウンさせてみましょう!
該当のインスタンスにログインして、25/TCP を LISTEN しているサービス(Postfix)を終了してみます。

$ sudo service postfix stop
Redirecting to /bin/systemctl stop postfix.service
$
Shared connection to xxx.xxx.xxx.xxx closed.

いきなり OS がリブートしてセッションからたたき出されたら成功です!(乱暴

CloudTrail にて確認すると、確かに EventBridge から RebootInstances API が叩かれていることが分かりますね。

まとめと所感

Amazon EventBridge 経由で、Mackerel の通知を受信して EC2 インスタンスを再起動してみました。

実は Mackerel から送信される情報に AWS 固有の情報(インスタンス ID など)が含まれておらず、これらを利用したいとなった場合は、AWS Lambda なりで改めて Mackerel の API を叩く必要があります。そういった作り込みを回避しようとすると、今回のようにそれぞれイベントソース〜ルールを個別につくって決め打つ必要があり、若干使いにくいかな。。。と思うところがないわけではありません。

一方でアラートだけでなくホストのステータス変更が通知出来たり、AWS 側は AWS 側で AWS Lambda だけでなく、AWS Systems Manager などとも連携できるため、自動化以外にもいろいろな応用が効きそうな気配があります。ぱっと思いつくところだと、Mackerel 側でステータスを変更することで AWS Systems Manager の定型処理を実行する。。といった仕組みは、比較的手軽に構築できるのではないでしょうか。
面白い応用方法がみつかったらまたブログにしてみたいと思いますが、みなさんも是非活用してみて下さい!