CloudWatch アラームを Teams・Chatwork に通知してみた!
こんにちは!
株式会社ビヨンド大阪オフィスのラーメン王、ヒデです。
今回が4回目の投稿です。
この記事では、最近僕が案件でも実装した、CloudWatch アラームを Teams・Chatwork に通知する方法ついてご紹介します。
前回のブログ記事では、AWS認定資格 SAA(ソリューションアーキテクト アソシエイト)の勉強方法に関する記事も書いてるので、ぜひ興味ある方は見てくださいね!
構成図
構成図は上記になります。
CloudWatch で EC2 のメトリクスを取得して、アラームが発生すれば SNS に通知します。そして、SNS は CloudWatch から送られてきた様々な値を Lambda に送信します。
Lambda はその値を整形して各コミュニケーションツールに送信するという流れになります。
様々な AWS リソースを使うので難しく感じますが、簡単に実装できるので一緒に頑張りましょう!
構築手順
① Lambdaを作成
①-①:Lambda > 関数 > 関数の作成をクリック
①-②:以下情報を指定して【関数の作成】をクリック
● 関数名:お好きな名前を指定してください
● ランタイム:Python3系を指定してください
①-③:コミュニケーションツール別にコードを貼り付ける
*Webhook URL や認証トークンなどをコードに直接書きたくない場合は、環境変数を設定してください
● Teams 用コード
#!/usr/bin/python3.8 import boto3 import json from urllib.request import Request, urlopen #WebhookURLを代入 HOOK_URL = "https://xxxxxxxxxxxxxxxx" def lambda_handler(event, context): #本番アラーム #message = json.loads(event['Records'][0]['Sns']['Message']) #subject = event['Records'][0]['Sns']['Subject'] #アラームテスト message = {"AlarmName":"test-CPUUtilization","AWSAccountId":"xxxxxxxxxxx","NewStateValue":"ALARM","NewStateReason":"Threshold Crossed: 1 out of the last 1 datapoints [1.8083480560463125 (xx/xx/xx xx:xx:xx)] was less than or equal to the threshold (80.0) (minimum 1 datapoint for OK -> ALARM transition).","StateChangeTime":"xxxx-xx-xxTxx:xx:xx.xxx+xxxx","Region":"Asia Pacific (Tokyo)"} subject = "ALARM: test-CPUUtilization in Asia Pacific (Tokyo)" #アラーム情報 alarm_name = message["AlarmName"] new_state = message["NewStateValue"] reason = message["NewStateReason"] alarm_time = message["StateChangeTime"] account_id = message["AWSAccountId"] region = message["Region"] alert_url = "https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#alarmsV2:alarm/%s" %alarm_name alert_msg = { 'title': "%s" %subject, 'text': '<br>アラーム名: %s' %alarm_name + '<br> ステータス: %s' %new_state + '<br> アラーム理由: %s' %reason + '<br><br> アラーム発生時刻(UTC): %s' %alarm_time + '<br> アカウントID: %s' %account_id + '<br> リージョン: %s' %region + '<br><br> アラームURL:<br> %s' %alert_url } #辞書型を文字列に変換してHTTPリクエストを生成 req = Request(HOOK_URL, json.dumps(alert_msg).encode('utf-8')) #送信 urlopen(req)
● Chatwork 用コード
#!/usr/bin/python3.8 import boto3 import json import urllib from urllib.request import Request, urlopen #ルームIDを指定 room_id = 'xxxxxxxxxxx' #トークンを指定 tokun = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx' chatwork_URL = "https://api.chatwork.com/v2/rooms/%s/messages" %room_id def lambda_handler(event, context): #本番アラーム #message = json.loads(event['Records'][0]['Sns']['Message']) #subject = event['Records'][0]['Sns']['Subject'] #アラームテスト message = {"AlarmName":"test-CPUUtilization","AWSAccountId":"xxxxxxxxxxx","NewStateValue":"ALARM","NewStateReason":"Threshold Crossed: 1 out of the last 1 datapoints [1.8083480560463125 (xx/xx/xx xx:xx:xx)] was less than or equal to the threshold (80.0) (minimum 1 datapoint for OK -> ALARM transition).","StateChangeTime":"xxxx-xx-xxTxx:xx:xx.xxx+xxxx","Region":"Asia Pacific (Tokyo)"} subject = "ALARM: test-CPUUtilization in Asia Pacific (Tokyo)" #アラーム情報 alarm_name = message["AlarmName"] new_state = message["NewStateValue"] reason = message["NewStateReason"] alarm_time = message["StateChangeTime"] account_id = message["AWSAccountId"] region = message["Region"] alert_url = "https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#alarmsV2:alarm/%s" %alarm_name alert_msg = { 'body': '[info][title]%s[/title]'%subject+ 'アラーム名: %s'%alarm_name +'\n'+ 'ステータス: %s'%new_state +'\n'+ 'アラーム理由: %s'%reason +'\n'+ 'アラーム発生時刻(UTC): %s'%alarm_time +'\n'+ 'アカウントID: %s'%account_id +'\n'+ 'リージョン: %s'%region +'\n\n'+ 'アラームURL: %s'%alert_url + '[/info]' } headers = { 'X-ChatWorkToken': '%s' %tokun } #クエリ文字列を生成 data = urllib.parse.urlencode(alert_msg) #文字コードを変換 data = data.encode('utf-8') #HTTPリクエストを生成 req = Request(chatwork_URL, data,headers) #送信 urlopen(req)
※ 補足:各コミュニケーションツールのメッセージ記法
● Chatwork
https://developer.chatwork.com/docs/message-notation
● AWS
https://aws.amazon.com/jp/premiumsupport/knowledge-center/sns-lambda-webhooks-chime-slack-teams
①-④:【deploy】をクリック
①-⑤:【Test】をクリック
①-⑥:以下情報を指定して【保存】をクリック
● イベント名:お好きな名前を指定してください
● テンプレート-オプション:sns-notification
①-⑦:【Test】をクリック
①-⑧:テストアラームが通知されているか確認する
● Teams
● Chatwork
①-⑨:本番アラーム通知用に変数を以下のように編集する
#本番アラーム message = json.loads(event['Records'][0]['Sns']['Message']) subject = event['Records'][0]['Sns']['Subject'] #アラームテスト #message = {"AlarmName":"test-CPUUtilization","AlarmDescription":"null","AWSAccountId":"xxxxxxxxxxx","AlarmConfigurationUpdatedTimestamp":"xxxx-xx-xxTxx:xx:xx.xxx+xxxx","NewStateValue":"ALARM","NewStateReason":"Threshold Crossed: 1 out of the last 1 datapoints [1.8083480560463125 (xx/xx/xx xx:xx:xx)] was less than or equal to the threshold (80.0) (minimum 1 datapoint for OK -> ALARM transition).","StateChangeTime":"xxxx-xx-xxTxx:xx:xx.xxx+xxxx","Region":"Asia Pacific (Tokyo)","AlarmArn":"arn:aws:cloudwatch:ap-northeast-1:xxxx:alarm:test-CPUUtilization","OldStateValue":"OK","OKActions":[],"AlarmActions":["arn:aws:sns:ap-northeast-1:xxxxxxxx:test"],"InsufficientDataActions":[],"Trigger":{"MetricName":"CPUUtilization","Namespace":"AWS/EC2","StatisticType":"Statistic","Statistic":"AVERAGE","Unit":"null","Dimensions":[{"value":"i-07876365e6af5774f","name":"InstanceId"}],"Period":300,"EvaluationPeriods":1,"DatapointsToAlarm":1,"ComparisonOperator":"LessThanOrEqualToThreshold","Threshold":80.0,"TreatMissingData":"missing","EvaluateLowSampleCountPercentile":""}} #subject = "ALARM: test-CPUUtilization in Asia Pacific (Tokyo)"
② SNS を作成
②-①:SNS > トピック > トピックの作成をクリック
②-②:以下情報を指定して【トピックの作成】をクリック
● タイプ:スタンダード
● 名前:好きな名前を記入してください
②-③:【サブスクリプションの作成】をクリック
②-④:以下情報を指定して【サブスクリプションの作成】をクリック
● プロトコル:Lambda
● エンドポイント:*以下を参照してください
*lambdaのARN情報場所
作成した関数 > 関数の概要の右端に、関数のARNがあるので、そこからコピーしてください。
②-⑤:ステータスを確認
③ CloudWatch を作成
*EC2は作成している前提で進めていきます。
③-①:Cloudwatch > アラーム >【アラームの作成】をクリック
③-②:お好みのメトリクスを選択
③-③:アラーム条件を選択
③-④:通知設定
③-⑤:アラーム名を指定する
③-⑥:【アラームの作成】をクリック
④ アラーム通知テスト
④-①:アラーム状態になっているか確認する
④-②:アラームが通知されているか確認する
● Teams
● ChatWork
※ 補足:
・CloudWatchのアラーム情報をすべて確認したい場合、以下のように変数 alert_msg の中身を編集すれば、参照することができます。
■ Teams
alert_msg ={ "text":"%s" %message }
■ Chatwork
alert_msg = { 'body': '%s' %message }
【出力結果】
{"AlarmName":"test-CPUUtilization","AlarmDescription":"null","AWSAccountId":"xxxxxxxxxxx","AlarmConfigurationUpdatedTimestamp":"xxxx-xx-xxTxx:xx:xx.xxx+xxxx","NewStateValue":"ALARM","NewStateReason":"Threshold Crossed: 1 out of the last 1 datapoints [1.8083480560463125 (xx/xx/xx xx:xx:xx)] was less than or equal to the threshold (80.0) (minimum 1 datapoint for OK -> ALARM transition).","StateChangeTime":"xxxx-xx-xxTxx:xx:xx.xxx+xxxx","Region":"Asia Pacific (Tokyo)","AlarmArn":"arn:aws:cloudwatch:ap-northeast-1:xxxx:alarm:test-CPUUtilization","OldStateValue":"OK","OKActions":[],"AlarmActions":["arn:aws:sns:ap-northeast-1:xxxxxxxx:test"],"InsufficientDataActions":[],"Trigger":{"MetricName":"CPUUtilization","Namespace":"AWS/EC2","StatisticType":"Statistic","Statistic":"AVERAGE","Unit":"null","Dimensions":[{"value":"i-xxxxxxxxxxxxxx","name":"InstanceId"}],"Period":300,"EvaluationPeriods":1,"DatapointsToAlarm":1,"ComparisonOperator":"LessThanOrEqualToThreshold","Threshold":80.0,"TreatMissingData":"missing","EvaluateLowSampleCountPercentile":""}}
まとめ
お疲れ様でした!
今回はアラーム内容を各コミュニケーションツールに通知する方法をご紹介しました!
Slack は AWS Chatbot を活用すると簡単にアラームを通知できますが、Teams・Chatwork に送信する機能が CloudWatch・SNS にないため、難しいですがアラームを通知する場合はこのようにします。
また、コードを編集すれば、処理に応じてメッセージを送信することもできます。アラームを通知する際は、ぜひ活用してくださいね!