背景: AWS 中国区的报警机制短信有局限性,弯道转移至其他机制
操作记录
基本逻辑:
cloudwatch 触发 SNS 服务,并且由SNS服务触发lambda函数执行Python脚本,进行发送钉钉通知。
1. 创建SNS 主题,用于接收cloudwatch 触发的报警。
比较简单,过程省略。。。
2. 配置 cloudwatch 触发SNS 通知
下图实例中,配置了 状态变更为警报时触发SNS以及 状态变更为正常时 触发SNS
image.png
3. 创建lambda角色
在【IAM】 点击 创建【角色】,【AWS产品】下选择 【lambda】,点击 【下一步】,搜索 权限 【AWSLambdaExecute】,点击【审核】 创建
4.创建函数
下面示例是创建函数并且赋予制定权限。
image.png
下面实例是配置 lambda触发器。
image.png
Python 示例代码:
# -*- coding: utf-8 -*-
import json
from botocore.vendored import requests
def lambda_handler(event,context): # text type
url="https://oapi.dingtalk.com/robot/send?access_token=wefwefwefwefsdgfdgwqwef4"
message = event['Records'][0]['Sns']
Timestamp=message['Timestamp']
Subject=message['Subject']
if "ALARM" in Subject:
title="警报!!警报!!"
elif "OK" in Subject:
title="故障恢复"
pagrem={
"msgtype":"markdown",
"markdown": {"title":"AWS"+title,
"text":"## "+title+"\n ### 时间:"+Timestamp+" \n ### 内容:"+Subject+" \n"
},
"at":{
"atMobiles":[
"185xxxxxxxx"
]
},
"isAtAll": "true"
}
headers={
'Content-Type':'application/json'
}
requests.post(url,data=json.dumps(pagrem),headers=headers)
额外注意:
lambda的Python 函数模块较常用的有些区别,所以导入模块时注意 AWS lambda专属的模块列表,请参照下面列表。
https://gist.github.com/gene1wood/4a052f39490fae00e0c3#file-list_aws_lambda_modules-py-L14
lambda日志存放位置:
image.png
这里有个lambda的测试 功能,即将手动设置一个数据输入,来测试lambda函数是否书写正确。
image.png
配置测试模板实例(即cloudwatch 触发的SNS 的数据源输入格式):
image.png
测试数据源代码
{
"Records": [
{
"EventSource": "aws:sns",
"Sns": {
"MessageAttributes": {},
"SignatureVersion": "1",
"Type": "Notification",
"Message": "{\"AlarmName\":\"RC-[HIGH]-grafana-group unhealthy>1\",\"AlarmDescription\":\"Created from EC2 Console\",\"AWSAccountId\":\"xxxxxx\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 out of the last 1 datapoints [1.0 (10/10/18 11:52:00)] was greater than or equal to the threshold (1.0) (minimum 1 datapoint for OK -> ALARM transition).\",\"StateChangeTime\":\"2018-10-10T11:53:08.426+0000\",\"Region\":\"China (Ningxia)\",\"OldStateValue\":\"OK\",\"Trigger\":{\"MetricName\":\"UnHealthyHostCount\",\"Namespace\":\"AWS/ApplicationELB\",\"StatisticType\":\"Statistic\",\"Statistic\":\"MAXIMUM\",\"Unit\":null,\"Dimensions\":[{\"name\":\"LoadBalancer\",\"value\":\"app/nx-rc-rancher-inner/0689e303d72560ff\"},{\"name\":\"TargetGroup\",\"value\":\"targetgroup/grafana-ec2-rc-ops/8xxxxx\"}],\"Period\":60,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanOrEqualToThreshold\",\"Threshold\":1.0,\"TreatMissingData\":\"\",\"EvaluateLowSampleCountPercentile\":\"\"}}",
"UnsubscribeUrl": "https://sns.cn-northwest-1.amazonaws.com.cn/?Action=Unsubscribe&SubscriptionArn=arn:aws-cn:sns:cn-northwest-1:xxxxx:SMS-TEST:46a6b2a2-c594-4d56-ae2f-56243292bdc0",
"TopicArn": "arn:aws-cn:sns:cn-northwest-1:xxxxx:SMS-TEST",
"Signature": "YwtAajUhBLhS/Rtwv8dCCcKwVpglHX1hzLa0gnfRdaQ/EH5zdQk9tCAFDxvT/9z+7jiBnIZgZrNX2pCoYgU61ONYuEZ74chbxjwKfF43YxHeTIsuyPBcsTyXLsJhwE+Tem2aXRllmABC4yO0tbDIwTCSSNF8fMwlm5aOc4HO28VhVOLnuqRP1XnAglO7sJfhD6oWjN+vVvyydmkFxbC8NpxgTpuwAwT6zKsUEHWvzmhRe9bhuxwIdg/Agyip6zgGVs0rDLBbh0Tu61RgqgrDxbUp9JPklkbLR5i+ILBd110msHH8rX43KypYuzgjLtvab3YQuioqUotrdJE+/G8MeQ==",
"SigningCertUrl": "https://sns.cn-northwest-1.amazonaws.com.cn/SimpleNotificationService-23551b0f4cfca4c8a720c40328560ad3.pem",
"Timestamp": "2018-10-10T11:53:08.484Z",
"Subject": "OK: \"RC-[HIGH]-grafana-group unhealthy>1\" in China (Ningxia)",
"MessageId": "99cc6911-5be6-5ae1-bc5d-3d26b182f2ba"
},
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws-cn:sns:cn-northwest-1:415056052465:SMS-TEST:46a6b2a2-c594-4d56-ae2f-56243292bdc0"
}
]
}
通知实例:
image.png
image.png
遇到的坑
- requests 模块不能直接导入,需要像示例中导入才能使用
- def 的函数name好像是固定的,不能修改
后续继续研究 cloudwatch直接触发lambda函数是如何处理以及Python自建包能否导入使用.
这个纯属学习AWS lambda的入门,AWS 这个lambda自称伟大到可以实现无服务器架构,这个还要继续深入学习