CloudWatch アラームを Teams・Chatwork に通知してみた!

*らぁめん真(大阪府茨木市)

こんにちは!
株式会社ビヨンド大阪オフィスのラーメン王、ヒデです。
今回が4回目の投稿です。

この記事では、最近僕が案件でも実装した、CloudWatch アラームを Teams・Chatwork に通知する方法ついてご紹介します。

前回のブログ記事では、AWS認定資格 SAA(ソリューションアーキテクト アソシエイト)の勉強方法に関する記事も書いてるので、ぜひ興味ある方は見てくださいね!

【受験者必見】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)

※ 補足:各コミュニケーションツールのメッセージ記法

● Teams
https://docs.microsoft.com/ja-jp/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using?tabs=cURL

● 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 にないため、難しいですがアラームを通知する場合はこのようにします。

また、コードを編集すれば、処理に応じてメッセージを送信することもできます。アラームを通知する際は、ぜひ活用してくださいね!

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
4
読み込み中...
4 票, 平均: 1.00 / 14
7,417
X facebook はてなブックマーク pocket

この記事をかいた人

About the author

ヒデ@インフラエンジニア

超面白かった面接がきっかけで。
大阪のシステムソリューション部に中途入社した人
サーバー・クラウドの構築や運用を業務としています!
一応、LPIC1・AWS SAA・OCI Architect Associateを資格は持っています

実はラーメンが大好きで
大阪では100店舗以上潜入調査済み(。-∀-) ニヒ
ビヨンドのラーメン王を目指し奮闘中!!

Twitterもやっているのでフォローしてね(´∇`)
右角のTwitterマークをクリック!!