Datadog で障害検知したら Slack と Backlog に通知しよう
以前、Backlog の課題追加があったら Slack に投げる記事を書きました。
nasrinjp1.hatenablog.com
プロジェクトでお客さんとのやりとりを Backlog にしておけば、プロジェクト管理する上で手作業で WBS ひいたり返信対象のメールを探して状況を確認したり課題管理表を作る手間も省け、通知を逃したとしても Slack に投げ込まれるのでどちらかで拾うことができていいですね。
運用も同じように自動で連携して通知する仕組みがほしいなーと思ったので、勉強がてらがんばって作ってみました。
仕組みの図
こんな感じです。監視システムは Datadog を使いました。前職で使ってたのでとっつきやすかったので。Datadog で障害検知したら Backlog に課題追加しつつ Slack にも通知されるようにしました。グレーの矢印の部分は、飛ばないようにしました。直接 Slack に投げているので二重に通知されてしまうためです。アラートだけは Slack 連携しない、ってことは Integromat なら簡単にできますよ。
Datadog から Slack へ
Datadog の Integration を使えば終わりです。めちゃ簡単です。説明するまでもなくドキュメントもそろってますし、他のブログでも書かれている&楽をしたいので書きませんw
Datadog から Backlog へ
この仕組みを作るのに 16 時間ほどつぶしてしまったので、自分のためにも書いていきます。
Backlog に投げるための情報収集
Backlog API を使って課題登録します。課題登録するにあたって、スペース ID、プロジェクト ID、イシュータイプ ID、apiKey が必要です。apiKey 以外は下記画面の URL のところで見れます。
apiKey は個人を特定して認証するためのキーです。Backlog の↓の画面で登録します。
あと、Datadog からは JSON を POST してくるみたいです。
docs.datadoghq.com
これで情報はそろいました。
Lambda から Backlog に投げるスクリプト
Python3 で requests モジュールを使うので、ローカル環境でモジュールを準備します。
cd <project_directory> python3 -m pip install requests -t .
エラー処理してないとか秘密の情報をべた書きしてるとか、ツッコミどころはありますが、まずは最低限動くところまで持っていきたいので後日修正するとして、↓のようなスクリプトを書きます。
# coding: utf-8 import json import requests def lambda_handler(event, context): title = event['title'] description = event['body'] if event['alert_type'] == 'Warning': severity = 3 else: severity = 2 return createissue(title, description, severity) def createissue(title,description,severity): url = "https://<spaceid>.backlog.com/api/v2/issues" payload = { 'projectId' : '<プロジェクト ID>', 'issueTypeId' : '<イシュータイプ ID>', 'priorityId' : severity, 'summary' : title, 'description' : description, 'apiKey' : '<apiKey>' } response = requests.post(url, params=payload) return response.json()
スクリプトと requests モジュールを一緒に zip で固めて、Lambda にアップロードします。Lambda function の IAM ロールは Cloudwatch ログにログ出力できればいいので、AWSLambdaBasicExecutionRole ポリシーをつけたロールを作成してそれを指定します。あとの設定は好きにしてください。
Function を保存したら、準備のところで書いた Datadog のページにある JSON の例を使ってテストしましょう。エラーなく Backlogに課題登録されましたね。
API Gateway から Lambda への連携
Datadog からの通知を受け付ける API を作成します。
「API の作成」を押します。
API 名とエンドポイントタイプを決めます。
続いてリソースを作成しましょう。
今回は test というリソースを作成します。
次にメソッドを作りましょう。
POST を選んで、Lambda function を指定します。
OK を押すと、Lambda のトリガーとして API Gateway が登録されます。
こんな図が出来上がりましたね。ではテストを押します。
一番下のリクエスト本文のところに POST する JSON を書いて「テスト」を押します。
ステータスが 200 になってることを確認しましょう。
テスト結果に問題がなければデプロイしましょう。
デプロイするステージを指定します。今回は test ステージを作りました。
画面上部の「URL の呼び出し」に、API の URL が書かれています。この URL に POST することで Backlog に課題登録されるようになります。
Datadog から API Gateway へ投げる
では Datadog の設定をしていきましょう。
Integrations から webhook を探してクリックします。
API Gateway で作成した URL の後ろにリソース名を追加した形で URL を指定します。今回だとちょっとぶさいくですが、https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/test/test って形になります。最初の test がステージ名、後ろの test がリソースです。わかりやすいように名前変えようと一瞬だけ思いましたが、気にせず進めます。
@webhook で始まる名前をアラートテキストのところで指定すれば OK です。
テストで監視対象の EC2 インスタンスを停止してみました。しばらくすると、Backlog に課題が登録されました!
Slack にも通知されました!これで一応仕組みができあがりました!
ここに至るまでにつまづいたところ
API Gateway からテストした時は問題なかったのに、Datadog からテストした時は↓このエラーばっかりでて最初悩みまくってました。
{"message":"Missing Authentication Token"}
application/x-www-form-urlencoded をリクエストに含めるとか、リクエストの認証がなしだったらうまくいかないとか、いろんな情報が出てきましたがどれも違ってて、結局 Datadog で指定する Webhook URL の最後の /test がなかっただけ、というオチでした。でもおかげでステージとリソースの関係が理解できたのでよかったです。
あとは、リソースの設定を変更したらそのたびにデプロイしないと反映されないとかも体験できたので、勇気を出して時間かけて API Gateway 使ってみてよかったと思います。
また時間作って Lambda Function の秘密の情報のところをべた書きじゃなくて、Secrets Manager とか Parameter Store とかつかって置き換えていきます!
2018/09/07追記
続編書きました!秘密の情報を Secrets Manager を使って置き換えました!
nasrinjp1.hatenablog.com