【问题标题】:AWS Lambda function to resize instance by tagAWS Lambda 函数按标签调整实例大小
【发布时间】:2019-08-14 11:49:04
【问题描述】:

我有一个 AWS Lambda 函数可以调整 EC2 实例的大小,但实例 ID 是硬编码的 - 我更喜欢使用标签,但无法让它工作

这是有效的代码:

# lambda function
import boto3
import botocore
import os

# define environment variables
Instance_Type = os.environ['InstanceType']

#define the connections
client = boto3.client('ec2')

RunningInstances = 'i-02a1130833c928708'

def lambda_handler(event, context):
    # Stop the instance
    client.stop_instances(InstanceIds=[RunningInstances])
    waiter=client.get_waiter('instance_stopped')
    waiter.wait(InstanceIds=[RunningInstances])
    print "Stopped", RunningInstances

    # Change the instance type
    client.modify_instance_attribute(InstanceId=RunningInstances, 
    Attribute='instanceType', Value=Instance_Type)
    print RunningInstances, "resized down to", Instance_Type

    # Start the instance
    client.start_instances(InstanceIds=[RunningInstances])
    print "Started", RunningInstances

这是我想做的工作:

import boto3
import botocore
import os

# define environment variables
Instance_Type = os.environ['InstanceType']

#define the connections
client = boto3.client('ec2')

#RunningInstances = 'i-02a1130833c928708'

def lambda_handler(event, context):
    filters=[
            {'Name': 'tag-key', 'Values': ['ResizeDown']},
            {'Name': 'tag-value', 'Values': ['True']},
            {'Name': 'instance-state-name','Values': ['running']}
    ]

    #filter the instances
    instances = client.instances.filter(Filters=filters)

    #locate all running instances
    RunningInstances = [instance.id for instance in instances]

    # Stop the instance
    client.stop_instances(InstanceIds=[RunningInstances])
    waiter=client.get_waiter('instance_stopped')
    waiter.wait(InstanceIds=[RunningInstances])
    print "Stopped", RunningInstances

    # Change the instance type
    client.modify_instance_attribute(InstanceId=RunningInstances, 
    Attribute='instanceType', Value=Instance_Type)
    print RunningInstances, "resized down to", Instance_Type

    # Start the instance
    client.start_instances(InstanceIds=[RunningInstances])
    print "Started", RunningInstances

我得到的错误是:

'EC2' 对象没有属性'instances':AttributeError 回溯(最近一次通话最后): 文件“/var/task/lambda_function.py”,第 21 行,在 lambda_handler 实例 = client.instances.filter(Filters=filters) getattr 中的文件“/var/runtime/botocore/client.py”,第 555 行 self.class.name, item) AttributeError: 'EC2' 对象没有属性 'instances'

【问题讨论】:

    标签: python-2.7 amazon-web-services aws-lambda


    【解决方案1】:

    正如您的错误所说,您的EC2 对象没有属性instances,如果您查看docs,您将不会在那里找到它。您应该能够在您的 boto 客户端上使用您已经设置的过滤器上的 describe_instances 函数,这将像以前一样返回相关实例,即:

    instances = client.describe_instances(Filters=filters)
    

    【讨论】:

    • 感谢您的回复,它修复了错误,但代码不起作用。正如约翰指出的那样,我使用两种不同的方式来引用 aws。我不是 python 程序员,所以我会坚持使用有效的代码。
    【解决方案2】:

    这一行:

    instances = client.instances.filter(Filters=filters)
    

    正在使用 EC2 资源而不是 EC2 客户端的格式。

    你可以使用:

    ec2_resource = boto3.resource('ec2')
    
    instances = ec2_resource.instances.filter(Filters=filters)
    

    基本上,这是引用 AWS 的两种不同方式。 client 方法映射到 AWS API,而 resource 方法更 Pythonic。

    【讨论】:

    • 感谢您指出这一点,可以工作,但之后的代码不能。我选择了 danimal 的答案作为解决方案,因为它修复了错误消息,并且首先,其余代码抛出了很多错误,我坚持使用有效的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 2016-05-27
    • 2021-11-29
    相关资源
    最近更新 更多