I tried notifying CloudWatch alarms to Teams/Chatwork!
table of contents
*Ramen Shin (Ibaraki City, Osaka Prefecture)
Hello!
My name is Hide, the ramen king of Beyond Osaka Office.
This is my fourth post.
In this article, I will introduce a method to notify Teams/Chatwork of CloudWatch alarms, which I recently implemented in a project.
In my previous blog post, I wrote an article about how to study for the AWS certification SAA (Solution Architect Associate), so if you are interested, please take a look!
Configuration diagram
The configuration diagram is shown above.
Obtain EC2 metrics with CloudWatch and notify SNS when an alarm occurs. SNS then sends various values sent from CloudWatch to Lambda.
Lambda formats the value and sends it to each communication tool.
It may seem difficult because it uses various AWS resources, but it is easy to implement, so let's do our best together!
Construction steps
① Create Lambda
①-①:Lambda > Function > Click Create function
①-②: Specify the following information and click [Create function]
● Function name: Please specify a name of your choice
● Runtime: Please specify Python3 series
①-③: Paste the code for each communication tool
*If you do not want to write the webhook URL or authentication token directly in the code, please set environment variables.
● Code for Teams
#!/usr/bin/python3.8 import boto3 import json from urllib.request import Request, urlopen #Substitute WebhookURL HOOK_URL = "https://xxxxxxxxxxxxxxxx" def lambda_handler(event, context): #Production alarm #message = json .loads(event['Records'][0]['Sns']['Message']) #subject = event['Records'][0]['Sns']['Subject'] #Alarm test 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 information 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> Alarm name: %s' %alarm_name + '<br> Status: %s' %new_state + '<br> Alarm reason: %s' %reason + '<br><br> Alarm occurrence time (UTC): %s' %alarm_time + '<br> Account ID: %s' %account_id + '<br> Region: %s' %region + '<br><br> Alarm URL:<br> %s' %alert_url } #Convert dictionary type to string and generate HTTP request req = Request(HOOK_URL, json.dumps(alert_msg).encode('utf-8')) #Send urlopen(req)
● Code for Chatwork
#!/usr/bin/python3.8 import boto3 import json import urllib from urllib.request import Request, urlopen #Specify room ID room_id = 'xxxxxxxxxxx' #Specify token tokun = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx' chatwork_URL = "https:// api.chatwork.com/v2/rooms/%s/messages" %room_id def lambda_handler(event, context): #Production alarm #message = json.loads(event['Records'][0]['Sns'][ 'Message']) #subject = event['Records'][0]['Sns']['Subject'] #Alarm test 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 information 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+ 'Alarm name: %s'%alarm_name +'\n'+ 'Status: %s'%new_state +'\n'+ 'Alarm reason: %s'%reason +'\n'+ 'Alarm occurrence time (UTC): %s'%alarm_time +'\n'+ 'Account ID: %s'%account_id + '\n'+ 'Region: %s'%region +'\n\n'+ 'Alarm URL: %s'%alert_url + '[/info]' } headers = { 'X-ChatWorkToken': '%s ' %tokun } #Generate query string data = urllib.parse.urlencode(alert_msg) #Convert character code data = data.encode('utf-8') #Generate HTTP request req = Request(chatwork_URL, data, headers) #send urlopen(req)
*Supplement: Message notation for each communication tool
● Chatwork
https://developer.chatwork.com/docs/message-notation
● AWS
https://aws.amazon.com/jp/premiumsupport/knowledge-center/sns-lambda-webhooks-chime-slack-teams
①-④: Click [deploy]
①-⑤: Click [Test]
①-⑥: Specify the following information and click [Save]
● Event name: Please specify a name of your choice
● Template-Options: sns-notification
①-⑦: Click [Test]
①-⑧: Check whether the test alarm has been notified
● Teams
● Chatwork
①-⑨: Edit variables as below for actual alarm notification
#Production alarm message = json.loads(event['Records'][0]['Sns']['Message']) subject = event['Records'][0]['Sns']['Subject'] #Alarm test #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)"
② Create SNS
②-①: SNS > Topics > Click Create Topic
②-②: Specify the following information and click [Create topic]
● Type: Standard
● Name: Please enter your favorite name
②-③: Click [Create subscription]
②-④: Specify the following information and click [Create subscription]
● Protocol: Lambda
● Endpoint: *See below
*Lambda ARN information location
The ARN of the function is located on the far right of the created function > Function overview, so copy it from there.
②-⑤: Check status
③ Create CloudWatch
*We will proceed on the assumption that EC2 has been created.
③-①: Cloudwatch > Alarm > Click [Create alarm]
③-②: Select your favorite metrics
③-③: Select alarm condition
*Please set the alarm to occur.
③-④: Notification settings
③-⑤: Specify the alarm name
③-⑥: Click [Create alarm]
④ Alarm notification test
④-①: Check if the alarm is on.
④-②: Check whether the alarm has been notified
● Teams
● Chat Work
*Note:
If you want to check all the alarm information in CloudWatch, you can refer to it by editing the contents of the variable alert_msg as shown below.
■ Teams
alert_msg ={ "text":"%s" %message }
■ Chatwork
alert_msg = { 'body': '%s' %message }
[Output result]
{"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":""}}
summary
thank you for your hard work!
This time, we introduced how to notify each communication tool of alarm content!
Slack can easily notify alarms by using AWS Chatbot, but CloudWatch/SNS does not have the ability to send alarms to Teams/Chatwork, so it is difficult to do so if you want to notify alarms.
You can also edit the code to send messages accordingly. Please make use of it when notifying an alarm!