23

I'm trying to parse data with Lambda when an alarm is triggered in Cloudwatch. I am currently using SNS to trigger the lambda; however, I want to know what data is being sent to that Lambda so that I can parse it correctly.

How can I read the JSON alarm data that's passed into Lambda by SNS?

b.b3rn4rd
  • 8,494
  • 2
  • 45
  • 57
wontonsoup
  • 409
  • 1
  • 5
  • 10

3 Answers3

35

The simplest and the most accurate way is to print(event) and actually see what's inside the payload, the official AWS doco provides the following structure for SNS event Amazon SNS Sample Event, reference

{
"Records": [
{
  "EventVersion": "1.0",
  "EventSubscriptionArn": eventsubscriptionarn,
  "EventSource": "aws:sns",
  "Sns": {
    "SignatureVersion": "1",
    "Timestamp": "1970-01-01T00:00:00.000Z",
    "Signature": "EXAMPLE",
    "SigningCertUrl": "EXAMPLE",
    "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
    "Message": "Hello from SNS!",
    "MessageAttributes": {
      "Test": {
        "Type": "String",
        "Value": "TestString"
      },
      "TestBinary": {
        "Type": "Binary",
        "Value": "TestBinary"
      }
    },
    "Type": "Notification",
    "UnsubscribeUrl": "EXAMPLE",
    "TopicArn": topicarn,
    "Subject": "TestInvoke"
  }
}
]
}

also, this CloudWatch specific example could be useful

{
"Records": [
{
  "EventSource": "aws:sns",
  "EventVersion": "1.0",
  "EventSubscriptionArn": "arn:aws:sns:eu-west-1:000000000000:cloudwatch-alarms:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "Sns": {
    "Type": "Notification",
    "MessageId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "TopicArn": "arn:aws:sns:eu-west-1:000000000000:cloudwatch-alarms",
    "Subject": "ALARM: \"Example alarm name\" in EU - Ireland",
    "Message": "{\"AlarmName\":\"Example alarm name\",\"AlarmDescription\":\"Example alarm description.\",\"AWSAccountId\":\"000000000000\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 datapoint (10.0) was greater than or equal to the threshold (1.0).\",\"StateChangeTime\":\"2017-01-12T16:30:42.236+0000\",\"Region\":\"EU - Ireland\",\"OldStateValue\":\"OK\",\"Trigger\":{\"MetricName\":\"DeliveryErrors\",\"Namespace\":\"ExampleNamespace\",\"Statistic\":\"SUM\",\"Unit\":null,\"Dimensions\":[],\"Period\":300,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanOrEqualToThreshold\",\"Threshold\":1.0}}",
    "Timestamp": "2017-01-12T16:30:42.318Z",
    "SignatureVersion": "1",
    "Signature": "Cg==",
    "SigningCertUrl": "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.pem",
    "UnsubscribeUrl": "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:000000000000:cloudwatch-alarms:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "MessageAttributes": {}
  }
}
]
}
Iain Samuel McLean Elder
  • 19,791
  • 12
  • 64
  • 80
b.b3rn4rd
  • 8,494
  • 2
  • 45
  • 57
9

The actual payload sent by Cloudwatch to SNS,

{
  "AlarmName": "Example alarm name",
  "AlarmDescription": "Example alarm description.",
  "AWSAccountId": "000000000000",
  "NewStateValue": "ALARM",
  "NewStateReason": "Threshold Crossed: 1 datapoint (10.0) was greater than or equal to the threshold (1.0).",
  "StateChangeTime": "2017-01-12T16:30:42.236+0000",
  "Region": "EU - Ireland",
  "OldStateValue": "OK",
  "Trigger": {
    "MetricName": "DeliveryErrors",
    "Namespace": "ExampleNamespace",
    "Statistic": "SUM",
    "Unit": null,
    "Dimensions": [],
    "Period": 300,
    "EvaluationPeriods": 1,
    "ComparisonOperator": "GreaterThanOrEqualToThreshold",
    "Threshold": 1
  }
}

If you want to read this event in Lambda,

import json

def lambda_handler(event, context):
    alert_message = json.loads(json.dumps(event))["Records"][0]["Sns"]["Message"]

    return {
        'statusCode': 200,
        'body': json.dumps(alert_message)
    }
Sufiyan Ghori
  • 18,164
  • 14
  • 82
  • 110
-1

The easiest and simple way is to create a new subscription for the SNS Topic to which the cloudwatch sends alarm data, with Email-JSON protocol and enter your email and create subscription.

Confirm the subscription by clicking on the verification link in email. When CloudWatch sends an alarm next time, you will get the JSON data in email and then you can figure out how to parse it correctly.