What is in the JSON payload Cloudwatch sends to SNS? How can I read that data?

11,028

Solution 1

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": {}
  }
}
]
}

Solution 2

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)
    }
Share:
11,028
wontonsoup
Author by

wontonsoup

Updated on June 14, 2022

Comments

  • wontonsoup
    wontonsoup almost 2 years

    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?

  • wontonsoup
    wontonsoup over 5 years
    This was the most resourceful answer. Thank you.