繁体   English   中英

如何在 AWS Lambda 中使用 python 访问事件对象?

[英]How to access the event object with python in AWS Lambda?

跟进此问题: 过滤 CloudWatch 日志以提取实例 ID

我认为它使问题不完整,因为它没有说明如何使用 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 开发工具包,您可以查询标签。 以下是示例事件

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

这是我想出来的……

请让我知道如何做得更好。 谢谢您的帮助。

# 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)

所以,这里是我如何在我的 Python 代码中为我的 Lambda 函数获取标签。

  ec2 = boto3.resource('ec2')
  instance = ec2.Instance(instanceId)

# get image_id from instance-id
  imageId = instance.image_id
  print(imageId)

  for tags in instance.tags:
    if tags["Key"] == 'Name':
      newName = tags["Value"] + ".mydomain.com"
  print(newName)

因此,使用instance.tags ,然后检查与我的Name标签匹配的"Key"并提取用于创建 FQDN(完全限定域名)的"Value"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM