Last active
April 14, 2022 14:34
-
-
Save LuizPanariello/1ac1a40786bace306038170a48a48f0b to your computer and use it in GitHub Desktop.
Cloudformation Topic to GoogleChat Webhook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
AWS Alarms Google Chat Webhook notification
The ideia here is that you have a Cloudformation exporting a SNS AlarmTopic.