미사용 EBS 볼륨과 생성 후 일정 시간이 지난 스냅샷을 탐지하고 자동 정리하는 구성을 만들어 봤습니다.
안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 미사용 EBS 볼륨과 생성 후 일정 시간이 지난 스냅샷을 탐지하고 자동 정리하는 구성을 만들어 봤습니다.
IAM 정책 및 역할 생성
이번 구성에 필요한 IAM 정책과 역할을 준비합시다.
EBS와 스냅샷에 대한 권한을 할당합니다.
그리고 [arn:aws:sns:ap-northeast-2:xxxxxxxxxxxx]에는 SNS의 토픽 Arn을 넣어줍시다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeVolumes",
"ec2:DeleteVolume",
"ec2:DescribeSnapshots",
"ec2:DeleteSnapshot"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": "arn:aws:sns:ap-northeast-2:xxxxxxxxxxxx"
},
{
"Effect": "Allow",
"Action": [
"logs:*"
],
"Resource": "*"
}
]
}
Lambda 함수 생성 및 코드 작성
Lambda 함수의 런타임은 [Python 3.13]입니다.
해당 함수의 역할은 조금 전 생성한 IAM 역할을 지정해 줍시다.
[arn:aws:sns:ap-northeast-2:xxxxxxxxxxxx]에는 SNS의 토픽 Arn을 넣어줍시다.
import boto3
import datetime
ec2 = boto3.client('ec2')
sns = boto3.client('sns')
SNS_TOPIC_ARN = 'arn:aws:sns:ap-northeast-2:xxxxxxxxxxxx'
DELETE_UNUSED = True # True로 바꾸면 실제 삭제 수행
def lambda_handler(event, context):
unused_volumes = []
old_snapshots = []
# 미사용 EBS 볼륨 탐지
volumes = ec2.describe_volumes()['Volumes']
for vol in volumes:
if len(vol['Attachments']) == 0 and vol['State'] == 'available':
unused_volumes.append(vol['VolumeId'])
# 오래된 Snapshot 탐지 (1시간 이상)
snapshots = ec2.describe_snapshots(OwnerIds=['self'])['Snapshots']
threshold_date = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(hours=1)
for snap in snapshots:
if snap['StartTime'] < threshold_date:
old_snapshots.append(snap['SnapshotId'])
# 로그 출력
print(f"Unused Volumes: {unused_volumes}")
print(f"Old Snapshots: {old_snapshots}")
# 삭제 여부 처리
deleted_vols = []
deleted_snaps = []
if DELETE_UNUSED:
for vol_id in unused_volumes:
ec2.delete_volume(VolumeId=vol_id)
deleted_vols.append(vol_id)
for snap_id in old_snapshots:
ec2.delete_snapshot(SnapshotId=snap_id)
deleted_snaps.append(snap_id)
# SNS 알림 전송
message = f"""[EBS Clean-up Report]
미사용 EBS 볼륨: {len(unused_volumes)}개
{unused_volumes}
오래된 Snapshot (1시간+): {len(old_snapshots)}개
{old_snapshots}
삭제 실행 여부: {'Yes' if DELETE_UNUSED else 'No'}
"""
sns.publish(
TopicArn=SNS_TOPIC_ARN,
Subject='[EBS Clean-up] 미사용 자원 정리 보고',
Message=message
)
return {
'statusCode': 200,
'body': 'Check complete.'
}
테스트를 위해 [오래된 Snapshot 탐지 (1시간 이상)]으로 지정했는데, 30일 이상으로 지정하고 싶은 분들은 아래 코드를 사용하면 됩니다.
snapshots = ec2.describe_snapshots(OwnerIds=['self'])['Snapshots']
threshold_date = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=30)
for snap in snapshots:
if snap['StartTime'] < threshold_date:
old_snapshots.append(snap['SnapshotId'])
전송하는 SNS 메시지도 [1시간+]가 아니라 [30일+]로 변경합니다.
# SNS 알림 전송
message = f"""[EBS Clean-up Report]
미사용 EBS 볼륨: {len(unused_volumes)}개
{unused_volumes}
오래된 Snapshot (30일+): {len(old_snapshots)}개
{old_snapshots}
그 외 설정은 Amazon EventBridge Scheduler를 이용해서 정기적으로 실행시킬 시간대를 설정해 주시면 됩니다.
Amazon EventBridge Scheduler에 대한 설명은 아래 블로그를 통해 확인할 수 있습니다.
결과 확인
먼저 테스트용으로 EBS 볼륨을 생성합니다.
스냅샷도 생성해 줍시다.
지정한 시간이 지나면 이메일이 도착하고, 삭제한 EBS 볼륨과 스냅샷에 대한 정보를 확인할 수 있습니다.
마지막으로 CloudTrail에서 이벤트 기록을 확인해 보면, 두 개의 EBS 볼륨과 하나의 스냅샷이 삭제된 것을 확인할 수 있습니다. [사용자 이름]에는 Lambda 함수의 이름이 표시될 것입니다.
본 블로그 게시글을 읽고 궁금한 사항이 있으신 분들은 jaewookkim533@yahoo.com로 보내주시면 감사하겠습니다.
문의 사항은 클래스메소드 코리아로!
클래스메소드 코리아에서는 다양한 세미나 및 이벤트를 진행하고 있습니다.
진행중인 이벤트는 아래 페이지를 참고해주세요.
AWS에 대한 상담 및 클래스 메소드 멤버스에 관한 문의사항은 아래 메일로 연락주시면 감사드립니다!
Info@classmethod.kr