以前からかなり欲しかった機能だった API Gateway が us-east-1 等いくつかの region で利用可能になったので、早速使ってみました。
Amazon SNS にメッセージ投稿を行うと、
- email での通知(標準機能)
- Twilio 経由で電話での通知
- Slack での通知
までは作ってあるので、後は NewRelic 等の監視サービスや独自監視ツールから Amazon SNS にメッセージを投げられれば、Amazon SNS をハブにしていろいろ連携できるようになります。
これまでは、
- 自前で SNS の API を叩く
- Webhook しか対応していないサービスは連携不可
- Zapier 等のハブサービスを利用
- 品質や応答速度がやや心配(見えない)
- サーバを立てて HTTP ラッパーを実装する
- サーバの維持、メンテナンスコストが問題
ぐらいしか選択肢がなかったのですが、API Gateway の登場で、自前でサーバを作らずに HTTP から Lambda を呼び出せるようになったので、AWS のサービスだけで完結できます。
今回は、試しに NewRelic の channel 設定で Webhook を追加し、Alert を Amazon SNS に投げてみます。
Lambda から SNS へ投稿するための Role を作成する
Lambda から Amazon SNS へ Publish するため、Role を新たに作成しておきます。
lambda_basic_execution
を作成しているのであれば、既存のものに追加しても OK ですが、分けておいたほうがいいと思います。
自分は lambda_sns_execution
として作成しました。
通常の権限に加えて、sns:Publish
を有効にしておきます。
resource も特定の Topic を指定してしまったほうが安全でしょう。
Lambda function を作成する
まずは Lambda function の作成です。
package.json や gulpfile.coffee は、これまでのものとほぼ同じなので省略します。
必要な package が
aws-sdk
になるだけです。
topicArn = 'YOUR_TOPIC_ARN'
snsRegion = 'ap-northeast-1'
AWS = require 'aws-sdk'
AWS.config.update region: snsRegion
sns = new AWS.SNS()
exports.handler = (event, context) ->
params =
Message: JSON.stringify(default: JSON.stringify(event))
MessageStructure: 'json'
Subject: event.condition_name
TopicArn: topicArn
sns.publish params, (err, data) ->
if err
context.done null, err
return
context.done null, 'Post succeeded.'
return
gulp build
でさくっと zip を作成、以下のコマンドで function を作成します。
aws --region us-east-1 lambda create-function \
--function-name lambda-newrelic-sns \
--runtime nodejs \
--role arn:aws:iam::xxxxxxxx:role/lambda_sns_execution \
--handler index.handler \
--description 'Send message to Amazon SNS' \
--timeout 3 \
--memory-size 128 \
--zip-file fileb://dist/lambda.zip
Amazon API Gateway から Lambda を呼び出す際、まだ東京リージョンの function は呼び出せませんので、
us-east-1
で作成しておきます。
API Gateway を作成する
まずは、API Gateway に行き、必要であればリージョンを N.Virginia に変更しておきます。
API の作成
新規に API を作成します。
API が作成されたので、「Create Resource」を押してリソースを作成します。
/newrelic
という endpoint が作成されたので、「Create Method」を押して、POST を選択。
すると、POST メソッドの設定画面になります。
Lambda Function を選択し、region を us-east-1 に、作成した Lambda function 名を入力します。
自動的に function の候補が表示されます。
最後に、以下の様な画面が表示されれば作成完了です。
API のデプロイ
作成した API はデプロイしないと有効になりません。「Deploy API」をクリックし、
適当に stage を作成します。
ここで作成した stage は、API のパスに含まれることになります。
「prod」と入力すると、ttps://xxxxxxxx.us-east-1.execute-api.com/prod/newrelic のようなパスになります。
これで API の利用準備が整いました。
Stages をたどると、API の URL が確認できます。
Lambda function 側の管理画面でも、「API endpoints」を選択すれば確認できます。
NewRelic の設定を行う
NewRelic にログインし、Alerts(beta) から、Notification Channels に行きます。
「New notification channel」から新規の通知チャネルを作成し、Webhook を選択、チャネルの名称及び、API の URL を入力します。
これで、NewRelic からの Alert 情報が POST で API に送信され、それが Amazon SNS に流れるようになります。
補足
現状のままだと、SNS の Message 形式を JSON データにしているため、メールや Slack への投稿時にそのまま JSON データがベタで表示されます。
また、きちんと運用するには Basic 認証等の機構を追加すべきですね。API Gatewayにもその設定がありますので。
NewRelic から投稿されるデータのフォーマットに合わせて、メッセージ内容をうまくカスタマイズすることで、より柔軟な通知が実現できます。
NewRelic から投稿されるデータのフォーマットは、こちらになります。
Customize your webhook payload