Sam
Sam

Reputation: 33

Extracting EC2InstanceId from SNS/SQS Auto Scaling message

I'm using python Boto3 code, when an instance is terminated from Auto Scaling group it notifies SNS which publishes the message to SQS. Lambda is also triggered when SNS is notified, which executes a boto script to grab the message from SQS.

I am using reference code from Sending and Receiving Messages in Amazon SQS.

Here is the code snippet:

if messages.get('Messages'):
  m = messages.get('Messages')[0]
  body = m['Body']

  print('Received and deleted message: %s' % body)

The result is:

START RequestId: 1234-xxxxxxxx Version: $LATEST
 {
  "Type" : "Notification",
  "MessageId" : "d1234xxxxxx",
  "TopicArn" : "arn:aws:sns:us-east-1:xxxxxxxxxx:AutoScale-Topic",
  "Subject" : "Auto Scaling: termination for group \"ASG\"",
  "Message" : "{\"Progress\":50,\"AccountId\":\"xxxxxxxxx\",\"Description\":\"Terminating EC2 instance: i-123456\",\"RequestId\":\"db-xxxxx\",\"EndTime\":\"2017-07-13T22:17:19.678Z\",\"AutoScalingGroupARN\":\"arn:aws:autoscaling:us-east-1:360695249386:autoScalingGroup:fef71649-b184xxxxxx:autoScalingGroupName/ASG\",\"ActivityId\":\"db123xx\",\"EC2InstanceId\":\"i-123456\",\"StatusCode\"\"}",
  "Timestamp" : "2017-07-",
  "SignatureVersion" : "1",
  "Signature" : "",
  "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/..",
  "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/
}

I only need EC2InstanceId of the terminated instance not the whole message. How can I extract the ID?

Upvotes: 3

Views: 1085

Answers (2)

John Rotenstein
John Rotenstein

Reputation: 269276

If your goal is to execute an AWS Lambda function (having the EC2 Instance ID as a parameter), there is no need to also publish the message to an Amazon SQS queue. In fact, this would be unreliable because you cannot guarantee that the message being retrieved from the SQS queue matches the invocation of your Lambda function.

Fortunately, when Auto Scaling sends an event to SNS and SNS then triggers a Lambda function, SNS passes the necessary information directly to the Lambda function.

Start your Lambda function with this code (or similar):

def lambda_handler(event, context):

    # Dump the event to the log, for debugging purposes
    print("Received event: " + json.dumps(event, indent=2))

    # Extract the EC2 instance ID from the Auto Scaling event notification
    message = event['Records'][0]['Sns']['Message']
    autoscalingInfo = json.loads(message)
    ec2InstanceId = autoscalingInfo['EC2InstanceId']

Your code then has the EC2 Instance ID, without having to use Amazon SQS.

Upvotes: 2

kichik
kichik

Reputation: 34704

The instance id is in the message. It's raw JSON, so you can parse it with the json package and get the information.

import json
if messages.get('Messages'):
  m = messages.get('Messages')[0]
  body = m['Body']
  notification_message = json.loads(body["Message"])

  print('instance id is: %s' % notification_message["EC2InstanceId"])

Upvotes: 0

Related Questions