2017-09-14 44 views
1

要跟進這個問題: 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"] 

回答

0

在事件的細節部分,你會得到的實例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" 
    } 
} 
+0

謝謝,Vaisakh。 這實際上有很大幫助。我看到事件對象和詳細信息部分,但是,請問,如何使用python爲此實例標識獲取特定標記。 這是一個json解析練習嗎?或者這可以通過對象屬性來完成嗎? 實例的標記值看起來不在事件對象中。 謝謝, 克里斯。 – Chrisjx

0

傳遞給Lambda的事件數據包含實例ID。您需要致電describe_tags()以檢索標籤字典。

import boto3 
client = boto3.client('ec2') 

client.describe_tags(Filters=[ 
     { 
      'Name': 'resource-id', 
      'Values': [ 
       event['detail']['instance-id'] 
      ] 
     } 
    ] 
) 
+0

John, 我在boto3文檔中看到了對客戶端對象的引用,但沒有看到describe_tags方法。 我已經發布了我的工作(也許不是最好的)代碼。它工作的很快,但是當我用一個不存在的實例id進行測試時它會拋出一個錯誤。我認爲這很好,因爲我可能不會從不存在的實例列表中啓動實例。實際上,我想它可能會被終止,仍在列表中,並且我意外地選擇了它。好吧。 – Chrisjx

0

這是我想出了...

請讓我知道如何可以做得更好。謝謝您的幫助。

# 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) 
相關問題