【问题标题】:Delete snapshots except those with specific description删除具有特定描述的快照除外
【发布时间】:2019-05-30 07:39:02
【问题描述】:

我正在尝试删除旧的 AWS 快照,但我需要排除任何以“由 CreateImage 创建”开头的描述值。

我尝试了 boto3.resource 和 boto3.client 的变体。

from datetime import datetime, timedelta, timezone

import boto3
client = boto3.client('ec2')
snapshots = client.snapshots.filter(Description!='Created by CreateImage')

def lambda_handler(event, context):
    for snapshot in snapshots:
        start_time = snapshot.start_time
        delete_time = datetime.now(tz=timezone.utc) - timedelta(days=790)
        if delete_time > start_time:
            snapshot.delete()
            print('Snapshot with Id = {} is deleted '.format(snapshot.snapshot_id))

现在我有大约 10 个超过 790 天的快照,其中 5 个的描述以“由 CreateImage 创建”开头,5 个没有。在对此进行测试时,我想删除那些没有描述的快照。

我得到的错误是:

模块初始化错误:“EC2”对象没有属性“快照”

【问题讨论】:

  • 使用 EC2 客户端 describe_snapshots() 方法。并对结果进行自己的过滤 - 您不能使用 boto3 过滤“值!= X”。

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


【解决方案1】:

这是一个可行的版本。

注意OwnerIds=['self'] 的使用,它将结果限制为仅由您的 AWS 账户创建的快照。如果没有这个,它将返回任何 AWS 账户创建的所有公开可用的快照。

from datetime import datetime, timedelta, timezone

import boto3

def lambda_handler(event, context):

    delete_time = datetime.now(tz=timezone.utc) - timedelta(days=790)

    ec2_resource = boto3.resource('ec2', region_name='ap-southeast-2')
    snapshots = ec2_resource.snapshots.filter(OwnerIds=['self'])

    for snapshot in snapshots:
        if not snapshot.description.startswith('Created by CreateImage') and delete_time > snapshot.start_time:
            snapshot.delete()
            print('Snapshot with Id = {} is deleted '.format(snapshot.snapshot_id))

【讨论】:

  • 一个小编辑,我想删除描述中没有“由 CreateImage 创建”的所有快照。我将第 13 行编辑为:'if not snapshot.description.startswith('Created by CreateImage') and delete_time > snapshot.start_time:"
  • @John 对于 boto3 和 python3,snapshot.delete()client.delete_snapshot(SnapshotId=id) 有什么区别
  • 啊!这是resourceclient。基本上,client 方法完全映射 AWS API 调用。 resource 方法是一种更 Pythonic 的遍历数据的方式,而不必解析 JSON。有时使用resource 方法会更容易,但这确实是个人喜好。
  • @JohnRotenstein 两者工作相同吗? ,如果我没有在snapshot.delete() 中传递任何snapshotId,那么它会删除当前id 快照吗?在这里我添加了删除代码,它工作正常吗? :stackoverflow.com/questions/63295917/…
  • 您并没有真正将 SnapshotId“传递”给snapshot.delete()。相反,您将快照作为snapshot 变量中的对象获取,然后对其调用.delete()
【解决方案2】:

您需要使用describe_snapshots 并正确传入过滤器。

此外,结果将是一个字典,而不是对 Snapshot 类的引用,因此您需要更新提取属性和删除快照的方式。

类似:

from datetime import datetime, timedelta, timezone

import boto3
client = boto3.client('ec2')
snapshots = client.describe_snapshots(Filters=[
        {
            'Name': 'description',
            'Values': [
                'Created by CreateImage',
            ]
        },
    ])['Snapshots']

def lambda_handler(event, context):
    for snapshot in snapshots:
        start_time = snapshot['StartTime']
        delete_time = datetime.now(tz=timezone.utc) - timedelta(days=790)
        if delete_time > start_time:
            client.delete_snapshot(SnapshotId=snapshot['SnapshotId'])
            print('Snapshot with Id = {} is deleted '.format(snapshot['SnapshotId']))

参考: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.describe_snapshots

【讨论】:

  • 感谢您的反馈,这很有帮助,但最后我使用了 John Rotenstein 的解决方案。感谢您的宝贵时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-28
  • 2015-03-10
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多