【发布时间】:2020-12-05 02:00:19
【问题描述】:
我在本地机器上创建了以下 lambda 函数,因此我可以部署它并每天通过 cloudwatch 事件 cron 表达式运行它,以清理所需的 AMI 及其快照。它还负责处理废弃的 EBS 快照。
删除 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')
【问题讨论】:
-
有效吗?如果是这样,则无需改进!
-
是的,按预期工作!我想知道在其中开发 lambda 函数和 python 代码的最佳实践。所以想从社区那里获得想法来改进它。
-
Lambda 函数中的逻辑不能被归类为“最佳实践”——它应该只是做你想让它做的事情。如果您谈论 Lambda 本身的“最佳实践”,它通常会围绕将 Lambda 用于短期功能、是否附加到 VPC、使用后清理
/tmp、使用全局变量在执行之间保留数据并正确使用来自event的数据。这些都与您的用例无关。
标签: python-3.x amazon-web-services aws-lambda boto3