AWS CloudWatch AlarmsからのメッセージをGoogle Hangouts Chatに通知したいことがあるかと思います。
今回はその構成をCDKで作成してみました。
環境
CDK CLI: 1.32.0
ローカルのNode: 11.15.0
構成
今回は、trigger-chat-cdk
というLambda関数を監視対象とし、「1分間に2回以上、関数が呼び出されたらエラーを挙げる」という条件を設定します。
以下は手順になりますが、このリポジトリをcloneすれば、手順の3,4は省略できるので、より速攻で作れるかと思います。
1. Hangouts ChatのWebhook URLを作成する
まず前準備として、Hangouts ChatのWebhook URLを作成する必要があります。
作成は以下リンク先の「準備」を参照すれば可能です。
https://qiita.com/iitenkida7/items/3c8f9f8f6ee1e809558d#%E6%BA%96%E5%82%99
2. Webhook URLをパラメータストアに設定する
AWSマネジメントコンソールを開き、
System Manager→パラメータストア→パラメータの作成
と進み、
名前:HANGOUTS_CHAT_WEBHOOK_URL
値:取得したWebhook URL
種類:SecureString
で設定します。
3. CDKでスタックの作成
ここまでの準備ができたら、CDKのスタックを定義していきます。
import * as cdk from '@aws-cdk/core'
import * as sns from '@aws-cdk/aws-sns'
import * as subs from '@aws-cdk/aws-sns-subscriptions'
import * as cw from '@aws-cdk/aws-cloudwatch'
import * as lambda from '@aws-cdk/aws-lambda'
import * as iam from '@aws-cdk/aws-iam'
import * as cw_actions from '@aws-cdk/aws-cloudwatch-actions'
export class CdkAlarmStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const layer = new lambda.LayerVersion(this, 'node-fetch', {
code: lambda.Code.asset('layer/forChat'),
compatibleRuntimes: [
lambda.Runtime.NODEJS_10_X,
lambda.Runtime.NODEJS_12_X
],
layerVersionName: 'node-fetch'
})
const triggerFunction = new lambda.Function(this, 'triggerFunction', {
runtime: lambda.Runtime.NODEJS_12_X,
handler: 'index.handler',
code: lambda.Code.asset('lambda/trigger-chat-cdk'),
functionName: 'trigger-chat-cdk'
})
const sendChatFunction = new lambda.Function(this, 'sendChatFunction', {
runtime: lambda.Runtime.NODEJS_12_X,
handler: 'index.handler',
code: lambda.Code.asset('lambda/send-chat-cdk'),
functionName: 'send-chat-cdk',
layers: [
layer
]
})
sendChatFunction.addToRolePolicy(new iam.PolicyStatement({
actions: [
'sts:AssumeRole',
'ssm:GetParameter'
],
resources: [
'*'
]
}))
const topic = new sns.Topic(
this,
'sendChatTopic',
{
displayName: 'send chat',
topicName: 'sendChatTopicCdk'
}
)
topic.addSubscription(new subs.LambdaSubscription(sendChatFunction))
const alarm = new cw.Alarm(this, 'sendChatAlarm', {
evaluationPeriods: 1,
metric: triggerFunction.metricInvocations(),
threshold: 2,
period: cdk.Duration.minutes(1),
alarmName: 'sendChatCdk'
})
alarm.addAlarmAction(new cw_actions.SnsAction(topic));
}
}
triggerFunction
を別のリソースに書き換えれば、アラームの監視対象を変えることができますし、alarm
を書き換えれば、アラームの定義を自由に設定することができます。
4. Chatにメッセージを送るLambda関数を書く
今回はLambda関数として
- 監視対象となる
trigger-chat-cdk
- Chatにメッセージを送る
send-chat-cdk
の2つを定義する必要がありますが、trigger-chat-cdk
の中身は正直なんでも良いので、説明を省略します。
send-chat-cdk
の中身は以下の通りです。
const fetch = require('node-fetch')
const AWS = require('aws-sdk')
exports.handler = async (event, context, callback) => {
const ssm = new AWS.SSM()
const res = await ssm.getParameter({ Name: 'HANGOUTS_CHAT_WEBHOOK_URL', WithDecryption: true }).promise()
const fromSNS = event.Records[0].Sns.Message
const data = JSON.stringify({
text: `${fromSNS}`
})
fetch(res.Parameter.Value, {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=UTF-8'
},
body: data
})
callback(null, event)
}
この関数で、node-fetch
というモジュールをインポートしているので、このモジュールを使えるようにします。
5. Layerで使用するモジュールをインストールする
今回使用するモジュールはLayerにセットします。
そのため、lambda/layer/forChat/nodejs
というディレクトリを作成し、このディレクトリで
$ npm i node-fetch
を実施し、インストールします。
6. デプロイ
ここまで完了したら、
$ cdk deploy
で、スタックをデプロイします。
7.実行テスト
AWSのマネジメントコンソールから、Lambdaのtrigger-chat-cdk
の管理画面を開き、適当なテストイベントを2回以上実行します。
1分ほど待って、作成したHangouts ChatのチャットルームにCloudWatchからのエラーメッセージが届けば成功です!
メッセージ文の内容は、Lambdaの中身を適宜アレンジして頂ければと思います。
以上、ありがとうございました。