sorta kinda...

主にAWS関連ですが、これに限らずいろいろ勉強したことや思ったことを書いていきます。

Datadog で障害検知したら Slack と Backlog に通知しよう

API Gateway はじめました、那須です。

以前、Backlog の課題追加があったら Slack に投げる記事を書きました。
nasrinjp1.hatenablog.com

プロジェクトでお客さんとのやりとりを Backlog にしておけば、プロジェクト管理する上で手作業で WBS ひいたり返信対象のメールを探して状況を確認したり課題管理表を作る手間も省け、通知を逃したとしても Slack に投げ込まれるのでどちらかで拾うことができていいですね。

運用も同じように自動で連携して通知する仕組みがほしいなーと思ったので、勉強がてらがんばって作ってみました。

 

仕組みの図

こんな感じです。監視システムは Datadog を使いました。前職で使ってたのでとっつきやすかったので。Datadog で障害検知したら Backlog に課題追加しつつ Slack にも通知されるようにしました。グレーの矢印の部分は、飛ばないようにしました。直接 Slack に投げているので二重に通知されてしまうためです。アラートだけは Slack 連携しない、ってことは Integromat なら簡単にできますよ。
f:id:nasrinjp1:20180905163815p:plain

 

Datadog から Slack へ

Datadog の Integration を使えば終わりです。めちゃ簡単です。説明するまでもなくドキュメントもそろってますし、他のブログでも書かれている&楽をしたいので書きませんw

 

Datadog から Backlog へ

この仕組みを作るのに 16 時間ほどつぶしてしまったので、自分のためにも書いていきます。

Backlog に投げるための情報収集

Backlog API を使って課題登録します。課題登録するにあたって、スペース ID、プロジェクト ID、イシュータイプ ID、apiKey が必要です。apiKey 以外は下記画面の URL のところで見れます。
f:id:nasrinjp1:20180905165537p:plain

apiKey は個人を特定して認証するためのキーです。Backlog の↓の画面で登録します。
f:id:nasrinjp1:20180905170246p:plain

あと、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 の作成」を押します。
f:id:nasrinjp1:20180905172636p:plain

API 名とエンドポイントタイプを決めます。
f:id:nasrinjp1:20180905172650p:plain

続いてリソースを作成しましょう。
f:id:nasrinjp1:20180905172704p:plain

今回は test というリソースを作成します。
f:id:nasrinjp1:20180905172716p:plain

次にメソッドを作りましょう。
f:id:nasrinjp1:20180905172728p:plain

POST を選んで、Lambda function を指定します。
f:id:nasrinjp1:20180905172740p:plain

OK を押すと、Lambda のトリガーとして API Gateway が登録されます。
f:id:nasrinjp1:20180905203950p:plain

こんな図が出来上がりましたね。ではテストを押します。
f:id:nasrinjp1:20180905172805p:plain

一番下のリクエスト本文のところに POST する JSON を書いて「テスト」を押します。
f:id:nasrinjp1:20180905172846p:plain

ステータスが 200 になってることを確認しましょう。
f:id:nasrinjp1:20180905172858p:plain

テスト結果に問題がなければデプロイしましょう。
f:id:nasrinjp1:20180905172910p:plain

デプロイするステージを指定します。今回は test ステージを作りました。
f:id:nasrinjp1:20180905172920p:plain

画面上部の「URL の呼び出し」に、API の URL が書かれています。この URL に POST することで Backlog に課題登録されるようになります。
f:id:nasrinjp1:20180905172930p:plain

 

Datadog から API Gateway へ投げる

では Datadog の設定をしていきましょう。

Integrations から webhook を探してクリックします。
f:id:nasrinjp1:20180905174400p:plain

API Gateway で作成した URL の後ろにリソース名を追加した形で URL を指定します。今回だとちょっとぶさいくですが、https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/test/test って形になります。最初の test がステージ名、後ろの test がリソースです。わかりやすいように名前変えようと一瞬だけ思いましたが、気にせず進めます。
f:id:nasrinjp1:20180905175228p:plain

@webhook で始まる名前をアラートテキストのところで指定すれば OK です。
f:id:nasrinjp1:20180905174433p:plain

テストで監視対象の EC2 インスタンスを停止してみました。しばらくすると、Backlog に課題が登録されました!
f:id:nasrinjp1:20180905175629p:plain

Slack にも通知されました!これで一応仕組みができあがりました!
f:id:nasrinjp1:20180905175811p:plain

 

ここに至るまでにつまづいたところ

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