Last active
December 25, 2023 18:39
-
-
Save rameerez/168a1dbff700b6f4f16982ea2a660a66 to your computer and use it in GitHub Desktop.
AWS Lambda function to send Telegram messages when CloudWatch alarms trigger
This file contains 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
# You need to give the Lambda the following permissions. | |
# Head to the Lambda page, and under Configuration > Permissions > Resource-based policy statements add a new policy statement: | |
# - Select "AWS Service" | |
# - On "Service", choose "Other" | |
# - Statement ID: AlarmAction | |
# - Principal: lambda.alarms.cloudwatch.amazonaws.com | |
# - Source ARN: arn:aws:cloudwatch:us-east-1:YOUR_ACCOUNT_ID:alarm:* | |
# - Action: lambda:InvokeFunction | |
# | |
# The same result can be achieved with `aws-cli`: | |
# ``` | |
# aws lambda add-permission \ | |
# --function-name YOUR_LAMBDA_NAME \ | |
# --statement-id AlarmAction \ | |
# --action 'lambda:InvokeFunction' \ | |
# --principal lambda.alarms.cloudwatch.amazonaws.com \ | |
# --source-account YOUR_ACCOUNT_ID \ | |
# --source-arn arn:aws:cloudwatch:us-east-1:YOUR_ACCOUNT_ID:alarm:* | |
# ``` | |
# | |
# The resulting policy should look like: | |
# ``` | |
# { | |
# "Version": "2012-10-17", | |
# "Id": "default", | |
# "Statement": [ | |
# { | |
# "Sid": "AlarmAction", | |
# "Effect": "Allow", | |
# "Principal": { | |
# "Service": "lambda.alarms.cloudwatch.amazonaws.com" | |
# }, | |
# "Action": "lambda:InvokeFunction", | |
# "Resource": "arn:aws:lambda:us-east-1:YOUR_ACCOUNT_ID:function:YOUR_LAMBDA_NAME", | |
# "Condition": { | |
# "StringEquals": { | |
# "AWS:SourceAccount": "YOUR_ACCOUNT_ID" | |
# }, | |
# "ArnLike": { | |
# "AWS:SourceArn": "arn:aws:cloudwatch:us-east-1:YOUR_ACCOUNT_ID:alarm:*" | |
# } | |
# } | |
# } | |
# ] | |
# } | |
# ``` | |
# | |
# Make sure to replace `YOUR_ACCOUNT_ID` and `YOUR_LAMBDA_NAME` with your actual account ID and Lambda name where necessary. | |
# | |
# Also, make sure to configure the `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID` environment variables in your Lambda. | |
# | |
# Relevant CloudWatch documentation and sample event sent to Lambda: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html | |
import os | |
import requests | |
import json | |
# Set your Telegram Bot token and chat ID here (or use environment variables) | |
TELEGRAM_BOT_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN') | |
TELEGRAM_CHAT_ID = os.environ.get('TELEGRAM_CHAT_ID') | |
def send_telegram_message(message): | |
"""Send a message to the Telegram group.""" | |
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" | |
data = { | |
"chat_id": TELEGRAM_CHAT_ID, | |
"text": message, | |
"parse_mode": "Markdown" | |
} | |
response = requests.post(url, data=data) | |
return response.json() | |
def lambda_handler(event, context): | |
# Parse the CloudWatch alarm data | |
alarm_data = event['alarmData'] | |
# Construct message based on the alarm data | |
alarm_name = alarm_data['alarmName'] | |
alarm_state = alarm_data['state']['value'] | |
alarm_reason = alarm_data['state']['reason'] | |
metric_namespace = alarm_data['configuration']['metrics'][0]['metricStat']['metric']['namespace'] | |
instance_id = alarm_data['configuration']['metrics'][0]['metricStat']['metric']['dimensions'].get('InstanceId', 'Unknown') | |
message = f"*[AWS]* 👀 Heads up! Alarm triggered: {alarm_name}\n" | |
message += f"State: {alarm_state}\n" | |
message += f"Reason: {alarm_reason}\n" | |
message += f"Instance ID: {instance_id}" | |
# Send the message | |
response = send_telegram_message(message) | |
return response |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment