To Nha Notes | Dec. 19, 2024, 2:06 p.m.
Amazon CloudWatch alarms support AWS Lambda functions as an alarm state change action. Customers can now choose to invoke a Lambda function directly when a CloudWatch alarm changes to an OK, ALARM or INSUFFICIENT_DATA state. This makes it easier for customers to automate custom actions on alarm state changes.
When you specify a Lambda function as an alarm action, you must create a resource policy for the function to allow the CloudWatch service principal to invoke the function.
One way to do this is by using the AWS CLI, as in the following example:
aws lambda add-permission \
--function-name my-function-name \
--statement-id AlarmAction \
--action 'lambda:InvokeFunction' \
--principal lambda.alarms.cloudwatch.amazonaws.com \
--source-account 111122223333 \
--source-arn arn:aws:cloudwatch:us-east-1:111122223333:alarm:alarm-name
Alternatively, we can define the lambda and its resource based policy in AWS SAM template as blow example.
Resources:
RDSAlarmNotificationFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html
Properties:
FunctionName: !Sub "${DBInstanceId}-notification"
CodeUri: notification/
Handler: app.lambda_handler
Environment:
Variables:
SNS_TOPIC_ARN: !Ref SnsTopicArn
SLACK_INCOMING_WEBHOOK_URL: !Ref SlackIncomingWebhookUrl
PAGERDUTY_INTEGRATION_KEY: !Ref PagerdutyIntegrationKey
Runtime: python3.12
Timeout: 30
Architectures:
- x86_64
# Permission to allow CloudWatch to invoke Lambda
RDSAlarmLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt RDSAlarmNotificationFunction.Arn
Action: lambda:InvokeFunction
Principal: lambda.alarms.cloudwatch.amazonaws.com
SourceArn: !Sub "arn:aws:cloudwatch:${AWS::Region}:${AWS::AccountId}:alarm:*"
When you configure a Lambda function as an alarm action, CloudWatch delivers a JSON payload to the Lambda function when it invokes the function. This JSON payload serves as the event object for the function. You can extract data from this JSON object and use it in your function. The following is an example of an event object from a metric alarm.
{
'source': 'aws.cloudwatch',
'alarmArn': 'arn:aws:cloudwatch:us-east-1:444455556666:alarm:lambda-demo-metric-alarm',
'accountId': '444455556666',
'time': '2023-08-04T12:36:15.490+0000',
'region': 'us-east-1',
'alarmData': {
'alarmName': 'lambda-demo-metric-alarm',
'state': {
'value': 'ALARM',
'reason': 'test',
'timestamp': '2023-08-04T12:36:15.490+0000'
},
'previousState': {
'value': 'INSUFFICIENT_DATA',
'reason': 'Insufficient Data: 5 datapoints were unknown.',
'reasonData': '{"version":"1.0","queryDate":"2023-08-04T12:31:29.591+0000","statistic":"Average","period":60,"recentDatapoints":[],"threshold":5.0,"evaluatedDatapoints":[{"timestamp":"2023-08-04T12:30:00.000+0000"},{"timestamp":"2023-08-04T12:29:00.000+0000"},{"timestamp":"2023-08-04T12:28:00.000+0000"},{"timestamp":"2023-08-04T12:27:00.000+0000"},{"timestamp":"2023-08-04T12:26:00.000+0000"}]}',
'timestamp': '2023-08-04T12:31:29.595+0000'
},
'configuration': {
'description': 'Metric Alarm to test Lambda actions',
'metrics': [
{
'id': '1234e046-06f0-a3da-9534-EXAMPLEe4c',
'metricStat': {
'metric': {
'namespace': 'AWS/Logs',
'name': 'CallCount',
'dimensions': {
'InstanceId': 'i-12345678'
}
},
'period': 60,
'stat': 'Average',
'unit': 'Percent'
},
'returnData': True
}
]
}
}
}
https://aws.amazon.com/about-aws/whats-new/2023/12/amazon-cloudwatch-alarms-lambda-change-action/