我已经在本地计算机上创建了以下lambda函数,因此我可以每天通过cloudwatch事件cron表达式对其进行部署和运行,以清理所需的AMI及其SnapShots。它还可以处理废弃的EBS SnapShot。
删除AMI的标准是首先找到没有DoNotDelete:true标记的AMI,如果它已存在7天以上,则将其标记为要删除。该功能可免除AWS Launch Configuration当前正在使用的AMI。
我肯定有几种方法可以优化此lambda函数和代码,并且我想知道如何进一步改进/优化它。
import boto3
from datetime import timedelta, datetime, timezone
import logging
import botocore
#Intialize logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def ami_cleanup(event,context):
'''Clean AMIs and its associated SnapShots which are older than 7 Days and without "DoNotDelete=true" tag in a AWS Region
Exempt AMI which is currently being used in AWS Launch Config'''
ec2 = boto3.client('ec2')
autoscaling = boto3.client('autoscaling')
ami_response = ec2.describe_images(Owners=['self'])
snapshot_response = ec2.describe_snapshots(OwnerIds=['self'])
lc_response = autoscaling.describe_launch_configurations()
amis = {}
amidnd = []
for i in ami_response['Images']:
for tag in i.get('Tags',''):
if 'DoNotDelete' in tag.values():
amidnd.append(i.get('ImageId'))
break
for ami in lc_response['LaunchConfigurations']:
if ami['ImageId'] not in amidnd:
amidnd.append(ami['ImageId'])
for i in ami_response['Images']:
if i.get('Tags') == None or i['ImageId'] not in amidnd:
amis[i.get('ImageId')] = i.get('CreationDate')
if not amis:
logger.info('No AMIs and SnapShots found to be deregister')
else:
for ami,cdate in amis.items():
if cdate < (datetime.now(timezone.utc)-timedelta(days=7)).isoformat():
logger.info('De-registering...'+ami)
ec2.deregister_image(ImageId=ami)
for snapshot in snapshot_response['Snapshots']:
if ami in snapshot.get('Description',''):
logger.info('Deleting '+snapshot.get('SnapshotId') + " of "+ami)
ec2.delete_snapshot(SnapshotId=snapshot.get('SnapshotId'))
else:
logger.info('No AMIs and SnapShots found to be older than 7 days')
break
abandon_snap_clean(ami_response,snapshot_response)
def abandon_snap_clean(ami_response,snapshot_response):
'''Clean abandon ebs snapshots of which no AMI has been found'''
snapdndids = []
for i in ami_response['Images']:
for snap in i['BlockDeviceMappings']:
if 'Ebs' in snap.keys():
snapdndids.append(snap['Ebs']['SnapshotId'])
for snapid in snapshot_response['Snapshots']:
if snapid['SnapshotId'] not in snapdndids:
try:
logger.info('Deleting abandon snapshots '+snapid['SnapshotId'])
ec2.delete_snapshot(SnapshotId=snapid['SnapshotId'])
except botocore.exceptions.ClientError as error:
if error.response['Error']['Code'] == 'InvalidSnapshot.InUse':
logger.info('SnapShotId '+snapid['SnapShotId']+' is already being used by an AMI')
else:
raise error
else:
logger.info('No abandon EBS SnapShots found to clean up')
break
else:
logger.info('No SnapShots found')
答案 0 :(得分:2)
这里似乎确实存在逻辑问题,如果遇到的图像不超过7天,则循环会中断,而其他图像可能仍超过7天。将break
切换为continue
if cdate < (datetime.now(timezone.utc)-timedelta(days=7)).isoformat():
logger.info('De-registering...'+ami)
ec2.deregister_image(ImageId=ami)
for snapshot in snapshot_response['Snapshots']:
if ami in snapshot.get('Description',''):
logger.info('Deleting '+snapshot.get('SnapshotId') + " of "+ami)
ec2.delete_snapshot(SnapshotId=snapshot.get('SnapshotId'))
else:
logger.info('No AMIs and SnapShots found to be older than 7 days')
continue