LoginSignup
43
37

More than 5 years have passed since last update.

API Gateway + Lambda で SNS にメッセージ投稿する

Last updated at Posted at 2015-07-10

以前からかなり欲しかった機能だった API Gateway が us-east-1 等いくつかの region で利用可能になったので、早速使ってみました。

Amazon SNS にメッセージ投稿を行うと、

までは作ってあるので、後は 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 を指定してしまったほうが安全でしょう。

IAM_Management_Console.png

Lambda function を作成する

まずは Lambda function の作成です。
package.json や gulpfile.coffee は、これまでのものとほぼ同じなので省略します。

必要な package が aws-sdk になるだけです。

src/index.coffee
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_Gateway.png

API が作成されたので、「Create Resource」を押してリソースを作成します。

API_Gateway.png

/newrelic という endpoint が作成されたので、「Create Method」を押して、POST を選択。

API_Gateway.png

すると、POST メソッドの設定画面になります。
Lambda Function を選択し、region を us-east-1 に、作成した Lambda function 名を入力します。

自動的に function の候補が表示されます。

API_Gateway.png

最後に、以下の様な画面が表示されれば作成完了です。

API_Gateway.png

API のデプロイ

作成した API はデプロイしないと有効になりません。「Deploy API」をクリックし、

API_Gateway.png

適当に stage を作成します。
ここで作成した stage は、API のパスに含まれることになります。

「prod」と入力すると、ttps://xxxxxxxx.us-east-1.execute-api.com/prod/newrelic のようなパスになります。

API_Gateway.png

これで API の利用準備が整いました。
Stages をたどると、API の URL が確認できます。

Lambda function 側の管理画面でも、「API endpoints」を選択すれば確認できます。

API_Gateway.png

NewRelic の設定を行う

NewRelic にログインし、Alerts(beta) から、Notification Channels に行きます。
「New notification channel」から新規の通知チャネルを作成し、Webhook を選択、チャネルの名称及び、API の URL を入力します。

Alerts_by_New_Relic.png

これで、NewRelic からの Alert 情報が POST で API に送信され、それが Amazon SNS に流れるようになります。

補足

現状のままだと、SNS の Message 形式を JSON データにしているため、メールや Slack への投稿時にそのまま JSON データがベタで表示されます。
また、きちんと運用するには Basic 認証等の機構を追加すべきですね。API Gatewayにもその設定がありますので。

NewRelic から投稿されるデータのフォーマットに合わせて、メッセージ内容をうまくカスタマイズすることで、より柔軟な通知が実現できます。

NewRelic から投稿されるデータのフォーマットは、こちらになります。
Customize your webhook payload

43
37
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
37