从SNS/SQS自动扩展消息中提取EC2InstanceId

3
我正在使用Python Boto3代码,当Auto Scaling组中的实例被终止时,它会通知SNS,SNS将消息发布到SQS。当SNS被通知时,也会触发Lambda,执行一个Boto脚本从SQS中抓取消息。
我正在使用在Amazon SQS中发送和接收消息的参考代码。
以下是代码片段:
if messages.get('Messages'):
  m = messages.get('Messages')[0]
  body = m['Body']

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

结果如下:
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/
}

我只需要终止实例的EC2InstanceId而不是整个消息。 我该如何提取ID?


你可能需要进行正则表达式匹配来提取实例ID。 - Ashan
2个回答

2
如果您的目标是执行一个 AWS Lambda 函数(将 EC2 实例 ID 作为参数),则无需将消息发布到 Amazon SQS 队列。事实上,这样做是不可靠的,因为您无法保证从 SQS 队列检索到的消息与调用 Lambda 函数的匹配。

幸运的是,当自动扩展向 SNS 发送事件并且 SNS 触发 Lambda 函数时,SNS 直接传递必要的信息给 Lambda 函数。

使用以下代码(或类似代码)启动 Lambda 函数:

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']

您的代码可以直接使用 EC2 实例 ID,而无需使用 Amazon SQS。


0

实例 ID 在消息中。它是原始 JSON,您可以使用 json 包解析它并获得信息。

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"])

谢谢。我遇到了这个错误:File "/var/task/lambda_function.py",第20行,在lambda_handler函数中,notification_message = json.loads(body["Message"]),TypeError: 字符串索引必须是整数,而不是字符串。 - Sam
你的问题让人觉得你已经有了一个解析后的 body 对象。如果不是这样的话,你可能也需要对其进行解析。无论哪种情况,你都应该使用 John 的答案。它更完整。 - kichik
谢谢kichik,我正在尝试John的解决方案。 - Sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接