Skip to content

Instantly share code, notes, and snippets.

@LuizPanariello
Last active April 14, 2022 14:34
Show Gist options
  • Save LuizPanariello/1ac1a40786bace306038170a48a48f0b to your computer and use it in GitHub Desktop.
Save LuizPanariello/1ac1a40786bace306038170a48a48f0b to your computer and use it in GitHub Desktop.
Cloudformation Topic to GoogleChat Webhook
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Alarms to GoogleChat'
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: General
Parameters:
- Environment
- Label:
default: Referenced Stacks
Parameters:
- AlarmStack
- Label:
default: Alerts
Parameters:
- HangoutsHookUrl
Parameters:
AlarmStack:
Description: Stack tht
Type: String
AllowedPattern: ^$|^[a-zA-Z][-a-zA-Z0-9]*$
HangoutsHookUrl:
Description: Hook url to send alerts to hangouts
Type: String
NoEcho: true
Conditions:
AlarmStackOn: !Not [!Equals [!Ref AlarmStack,'']]
Resources:
AlarmLambdaRole:
Type: "AWS::IAM::Role"
Properties:
Path: "/"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Sid: "AllowLambdaServiceToAssumeRole"
Effect: "Allow"
Action:
- "sts:AssumeRole"
Principal:
Service:
- "lambda.amazonaws.com"
AlarmLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
Code:
ZipFile: |
from __future__ import print_function
import boto3
import json
import logging
import os
from base64 import b64decode
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
HOOK_URL = os.environ['HookUrl']
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def handler(event, context):
logger.info("Event: " + json.dumps(event))
message = json.loads(event['Records'][0]['Sns']['Message'])
alarm_name = message['AlarmName']
alarm_description = message['AlarmDescription']
old_state = message['OldStateValue']
new_state = message['NewStateValue']
reason = message['NewStateReason']
if (old_state == new_state):
logger.info("State did not change for %s.", alarm_name)
return
if HOOK_URL == '':
logger.info("State change from %s to %s for alarm %s, but notification url not set.", old_state, new_state, alarm_name)
return
request_headers = { 'Content-Type': 'application/json; charset=UTF-8'}
font_color = '#008000' if new_state == 'OK' else '#FF0000'
status = '<b><font color="' + font_color + '">' + new_state + '</font></b>'
link = 'https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#alarmsV2:alarm/' + alarm_name + '?'
message = {
"cards": [{
"sections": [{
"widgets": [{
"keyValue": {
"topLabel": "Status",
"content": "%s" % (status),
"contentMultiline": True
}
},{
"keyValue": {
"topLabel": "Description",
"content": "%s" % (alarm_description),
"contentMultiline": True
}
},{
"keyValue": {
"topLabel": "Alarm Name",
"content": "%s" % (alarm_name),
"contentMultiline": True
}
},{
"keyValue": {
"topLabel": "Alarm Reason",
"content": "%s" % (reason),
"contentMultiline": True
}
}]
},{
"widgets": [{
"buttons": [{
"textButton": {
"text": "Abrir no console",
"onClick": {
"openLink": {
"url": "%s" % (link)
}
}
}
}]
}]
}]
}]
}
req = Request(HOOK_URL, data=json.dumps(message).encode('utf-8'), headers=request_headers)
try:
response = urlopen(req)
response.read()
logger.info("Message posted to %s", HOOK_URL)
except HTTPError as e:
logger.error("Request to %s failed: %d %s", HOOK_URL, e.code, e.reason)
except URLError as e:
logger.error("Server connection to %s failed: %s", HOOK_URL, e.reason)
Description: Sends alerts to mythbusters at hangouts
Environment:
Variables:
HookUrl: !Ref 'HangoutsHookUrl'
Handler: index.handler
MemorySize: 128
Role: !GetAtt ['AlarmLambdaRole', Arn]
Runtime: python3.8
Timeout: 3
TracingConfig:
Mode: PassThrough
AlertsSnsTopicAlarmLambdaFunctionSubscription:
Type: AWS::SNS::Subscription
Condition: AlarmStackOn
Properties:
Endpoint: !GetAtt [AlarmLambdaFunction, Arn]
Protocol: lambda
TopicArn:
Fn::ImportValue:
!Sub "${AlarmStack}-AlarmTopic"
AlarmLambdaInvokePermission:
Type: AWS::Lambda::Permission
Condition: AlarmStackOn
Properties:
Action: lambda:InvokeFunction
Principal: sns.amazonaws.com
SourceArn:
Fn::ImportValue: !Sub "${AlarmStack}-AlarmTopic"
FunctionName: !Ref AlarmLambdaFunction
@LuizPanariello
Copy link
Author

AWS Alarms Google Chat Webhook notification

The ideia here is that you have a Cloudformation exporting a SNS AlarmTopic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment