【问题标题】:AWS Lambda - EBS available volume snapshot execution using tag criteria boto3AWS Lambda - 使用标签标准 boto3 执行 EBS 可用卷快照
【发布时间】:2020-01-07 17:31:10
【问题描述】:

我是 Python 编程新手,正在尝试开发 AWS Lambda。它是用 Python 3.6 编写的,可以创建可用 EBS 卷的快照,以便稍后使用 boto3 调用进行删除。我希望 Lambda 的逻辑遍历卷标签。如果标签列表中有特定标签,则根据要删除的卷的日期处理一些评估逻辑。如果集合中不存在指定的标签,或者标签为无,则继续创建快照。

我的 Lambda 将使用指定标签的逻辑并正常创建快照。我正在努力使用正确的循环语法来处理所有卷标签作为字典。它希望单独循环遍历卷的每个标签,而不是一次作为一个集合。

    for vol in ec2.volumes.all():
        if vol.state == 'available':
            volid = vol.id
            tags = {}
            for tag in vol.tags:
                if tag['Key'] == 'DeleteMeAfter':
                    print("===================")
                    print(", ".join((
                        volid,
                        tag['Key'],
                        tag['Value']
                    )))
                    ### Process additional logic on tag['Value'] ###

当我将 elif/else 语句添加到 if 标记语句时,它会尝试创建同一卷的多个快照。

“调用 CreateSnapshot 操作时发生错误 (SnapshotCreationPerVolumeRateExceeded):已超出每个卷的最大 CreateSnapshot 请求速率。”

任何帮助将不胜感激!

【问题讨论】:

  • 您是在尝试创建快照还是删除快照?
  • 如此令人困惑的问题,但错误让您知道您已达到极限。
  • 只需在这个 Lambda 中创建快照。一旦我创建了一个成功的快照,有一个单独的 Lambda 将删除该卷。问题是我迄今为止编写代码的方式,它遍历标签试图创建同一卷的多个快照。因此遇到了错误。

标签: python-3.x amazon-web-services amazon-ec2 aws-lambda boto3


【解决方案1】:
  • 这应该可以工作
  • 附上博客blog
# Backup all in-use volumes in all regions

import boto3

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')

    # Get list of regions
    regions = ec2.describe_regions().get('Regions',[] )

    # Iterate over regions
    for region in regions:
        print "Checking region %s " % region['RegionName']
        reg=region['RegionName']

        # Connect to region
        ec2 = boto3.client('ec2', region_name=reg)

        # Get all in-use volumes in all regions  
        result = ec2.describe_volumes( Filters=[{'Name': 'status', 'Values': ['in-use']}])

        for volume in result['Volumes']:
            print "Backing up %s in %s" % (volume['VolumeId'], volume['AvailabilityZone'])

            # Create snapshot
            result = ec2.create_snapshot(VolumeId=volume['VolumeId'],Description='Created by Lambda backup function ebs-snapshots')

            # Get snapshot resource 
            ec2resource = boto3.resource('ec2', region_name=reg)
            snapshot = ec2resource.Snapshot(result['SnapshotId'])

            volumename = 'N/A'

            # Find name tag for volume if it exists
            if 'Tags' in volume:
                for tags in volume['Tags']:
                    if tags["Key"] == 'Name':
                        volumename = tags["Value"]

            # Add volume name to snapshot for easier identification
            snapshot.create_tags(Tags=[{'Key': 'Name','Value': volumename}])

【讨论】:

  • 这是使用 boto3 客户端,ec2 = boto3.client('ec2') 和 result = ec2.describe_volumes()。我试图坚持使用 ec2 = boto3.resource('ec2') 和 volume = ec2.Volume('id') 的原始代码。 boto3.amazonaws.com/v1/documentation/api/latest/reference/…
  • 抱歉@amittn 我想我对您在评论中发布的内容以及博客中的内容感到困惑。当我尝试这个时,它无法识别 DeleteMeAfter 标签。 if 'Tags' in vtags: for tag in vtags['Tags']: if tag['Key'] == 'DeleteMeAfter': volumename = tag['Value']
  • 我能够让逻辑为if tag is None 工作。现在我只是仍然想念如何通过一次迭代所有标签来在标签字典中不存在指定标签时创建快照。
  • @hawk3yez 确实 client.describe_tags 方法可能会有所帮助。两个 ec2 实例可以具有相同的标签,如此处所示。希望对你有帮助docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html
  • @hawk3yez 希望上面发布的答案对您有所帮助
【解决方案2】:

我能够使用以下代码使其正常工作。感谢朋友的帮助和@amitn 的博客/帖子。

def examine_volumes():
    try:
        first_call = True;
        next_token = 'bc6ed4ae04d2'
        while next_token is not None:
            if first_call:
                first_call = False
                r = ec2_client.describe_volumes(Filters=[{'Name': 'status', 'Values': ['available']}])
            else:
                r = ec2_client.describe_volumes(NextToken=next_token)
            next_token = r.get('NextToken', None)
            for vol in r.get('Volumes', []):
                if is_interesting(vol):
                    logger.info(f'working on:')
                    #logger.info(json.dumps(vol, indent=2, default=date_converter))
                else:
                    logger.info(f'volume is not interesting')
                    volid = vol['VolumeId']
                    make_snapshots(volid)
    except Exception

def is_interesting(volume):
    for tag in volume.get('Tags', []):
        if (tag.get('Key', None)) == 'DeleteMeAfter':
            print(", ".join((volume['VolumeId'], tag['Key'], tag['Value'])))
            ### Process logic for tag-value ###
            make_snapshots(volid)

我根据“VolumeId”调用另一个函数 make_snapshots(volid)。这样,它将根据我使用日期时间逻辑识别的标签值创建快照,如果未准备好则跳过该卷,并且仍然对没有“DeleteMeAfter”标签的其他卷进行快照。感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 2016-07-09
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多