如何使用AWS Lambda中的python访问事件对象?
要跟进这个问题: Filter CloudWatch Logs to extract Instance ID如何使用AWS Lambda中的python访问事件对象?
我认为它留下的问题不完整的,因为它并没有说如何使用Python访问事件对象。
我的目标是:
- 读取被改变运行状态
- 获得与实例
- 开始具有相同标记的所有其他实例相关联的标签值触发实例
的CloudWatch的触发事件是:
{
"source": [
"aws.ec2"
],
"detail-type": [
"EC2 Instance State-change Notification"
],
"detail": {
"state": [
"running"
]
}
}
,我可以看到的例子是这样的:
def lambda_handler(event, context):
# here I want to get the instance tag value
# and set the tag filter based on the instance that
# triggered the event
filters = [{
'Name': 'tag:StartGroup',
'Values': ['startgroup1']
},
{
'Name': 'instance-state-name',
'Values': ['running']
}
]
instances = ec2.instances.filter(Filters=filters)
我可以看到事件对象,但我不知道如何深入到这有它的状态转变为运行实例的标签。
请问,通过哪些对象属性可以从触发实例中获取标签?
我怀疑它是这样的:
myTag = event.details.instance-id.tags["startgroup1"]
在事件的细节部分,你会得到的实例ID的。使用实例ID和AWS SDK您可以查询标签。以下是示例事件
{
"version": "0",
"id": "ee376907-2647-4179-9203-343cfb3017a4",
"detail-type": "EC2 Instance State-change Notification",
"source": "aws.ec2",
"account": "123456789012",
"time": "2015-11-11T21:30:34Z",
"region": "us-east-1",
"resources": [
"arn:aws:ec2:us-east-1:123456789012:instance/i-abcd1111"
],
"detail": {
"instance-id": "i-abcd1111",
"state": "running"
}
}
传递给Lambda的事件数据包含实例ID。您需要致电describe_tags()
以检索标签字典。
import boto3
client = boto3.client('ec2')
client.describe_tags(Filters=[
{
'Name': 'resource-id',
'Values': [
event['detail']['instance-id']
]
}
]
)
John, 我在boto3文档中看到了对客户端对象的引用,但没有看到describe_tags方法。 我已经发布了我的工作(也许不是最好的)代码。它工作的很快,但是当我用一个不存在的实例id进行测试时它会抛出一个错误。我认为这很好,因为我可能不会从不存在的实例列表中启动实例。实际上,我想它可能会被终止,仍在列表中,并且我意外地选择了它。好吧。 – Chrisjx
这是我想出了...
请让我知道如何可以做得更好。谢谢您的帮助。
# StartMeUp_Instances_byOne
#
# This lambda script is triggered by a CloudWatch Event, startGroupByInstance.
# Every evening a separate lambda script is launched on a schedule to stop
# all non-essential instances.
#
# This script will turn on all instances with a LaunchGroup tag that matches
# a single instance which has been changed to the running state.
#
# To start all instances in a LaunchGroup,
# start one of the instances in the LaunchGroup and wait about 5 minutes.
#
# Costs to run: approx. $0.02/month
# https://s3.amazonaws.com/lambda-tools/pricing-calculator.html
# 150 executions per month * 128 MB Memory * 60000 ms Execution Time
#
# Problems: talk to chrisj
# ======================================
# test system
# this is what the event object looks like (see below)
# it is configured in the test event object with a specific instance-id
# change that to test a different instance-id with a different LaunchGroup
# { "version": "0",
# "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
# "detail-type": "EC2 Instance State-change Notification",
# "source": "aws.ec2",
# "account": "999999999999999",
# "time": "2015-11-11T21:30:34Z",
# "region": "us-east-1",
# "resources": [
# "arn:aws:ec2:us-east-1:123456789012:instance/i-abcd1111"
# ],
# "detail": {
# "instance-id": "i-0aad9474", # <---------- chg this
# "state": "running"
# }
# }
# ======================================
import boto3
import logging
import json
ec2 = boto3.resource('ec2')
def get_instance_LaunchGroup(iid):
# When given an instance ID as str e.g. 'i-1234567',
# return the instance LaunchGroup.
ec2 = boto3.resource('ec2')
ec2instance = ec2.Instance(iid)
thisTag = ''
for tags in ec2instance.tags:
if tags["Key"] == 'LaunchGroup':
thisTag = tags["Value"]
return thisTag
# this is the entry point for the cloudwatch trigger
def lambda_handler(event, context):
# get the instance id that triggered the event
thisInstanceID = event['detail']['instance-id']
print("instance-id: " + thisInstanceID)
# get the LaunchGroup tag value of the thisInstanceID
thisLaunchGroup = get_instance_LaunchGroup(thisInstanceID)
print("LaunchGroup: " + thisLaunchGroup)
if thisLaunchGroup == '':
print("No LaunchGroup associated with this InstanceID - ending lambda function")
return
# set the filters
filters = [{
'Name': 'tag:LaunchGroup',
'Values': [thisLaunchGroup]
},
{
'Name': 'instance-state-name',
'Values': ['stopped']
}
]
# get the instances based on the filter, thisLaunchGroup and stopped
instances = ec2.instances.filter(Filters=filters)
# get the stopped instance IDs
stoppedInstances = [instance.id for instance in instances]
# make sure there are some instances not already started
if len(stoppedInstances) > 0:
startingUp = ec2.instances.filter(InstanceIds=stoppedInstances).start()
print ("Finished launching all instances for tag: " + thisLaunchGroup)
谢谢,Vaisakh。 这实际上有很大帮助。我看到事件对象和详细信息部分,但是,请问,如何使用python为此实例标识获取特定标记。 这是一个json解析练习吗?或者这可以通过对象属性来完成吗? 实例的标记值看起来不在事件对象中。 谢谢, 克里斯。 – Chrisjx