AWS Lambda를 통해 암호화 되지 않은 EBS를 정기적으로 감지하는 구성을 만들어 봤습니다.
안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 AWS Lambda를 통해 암호화 되지 않은 EBS를 정기적으로 감지하는 구성을 만들어 봤습니다.
AWS Config을 이용하여 EBS 암호화를 감지하고 자동으로 암호화 시키는 구성에 대해서는 아래 블로그를 통해 확인할 수 있습니다.
이번 구성은 단순하게 Lambda로 코드를 작성하여 이메일을 통지하는 것 뿐이므로 되도록이면 상기 AWS Config을 이용한 구조를 사용하는 것을 추천드립니다.
※ 이번 블로그에서는 Lambda 함수를 이용해 보다 많은 것을 해 볼 수 있다는 취지에 작성 되었습니다.
IAM 정책 및 역할 생성
먼저 Lambda 함수에 EBS에 대한 권한과 SNS, CloudWatch에 대한 권한을 할당합니다.
[arn:aws:sns:ap-northeast-2:xxxxxxxxxx]에는 SNS 토픽 Arn을 입력합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeVolumes"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": "arn:aws:sns:ap-northeast-2:xxxxxxxxxx"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
Lambda 함수 코드 작성
Lambda 함수의 런타임은 [Python 3.13]을 지정합니다.
[arn:aws:sns:ap-northeast-2:xxxxxxxxxx]에는 SNS 토픽 Arn을 입력합니다.
import json
import boto3
ec2 = boto3.client('ec2')
sns = boto3.client('sns')
SNS_TOPIC_ARN = 'arn:aws:sns:ap-northeast-2:xxxxxxxxxxx'
def lambda_handler(event, context):
print("🔍 Checking all EBS volumes for encryption status...")
unencrypted_volumes = []
# 모든 EBS 볼륨 조회
response = ec2.describe_volumes()
volumes = response['Volumes']
for volume in volumes:
volume_id = volume['VolumeId']
encrypted = volume.get('Encrypted', False)
print(f"Volume {volume_id} encrypted: {encrypted}")
if not encrypted:
unencrypted_volumes.append(volume_id)
# 알림 전송
if unencrypted_volumes:
message = (
"🔒 다음 EBS 볼륨이 암호화되어 있지 않습니다:\n\n" +
"\n".join(unencrypted_volumes)
)
print(message)
sns.publish(
TopicArn=SNS_TOPIC_ARN,
Subject="🚨 Unencrypted EBS Volumes Detected",
Message=message
)
else:
print("✅ 모든 EBS 볼륨이 암호화되어 있습니다.")
return {
'statusCode': 200,
'body': f"암호화되지 않은 볼륨 개수: {len(unencrypted_volumes)}"
}
EventBridge 스케줄 설정
EventBridge 스케줄에 대해서는 특별한 설정은 필요 없습니다. 시간을 설정하고, 조금 전 생성한 Lambda 함수를 선택합니다.
보다 상세한 EventBridge 스케줄에 대한 설명은 아래 블로그를 참고해 주세요.
결과 확인
암호화되지 않은 EBS를 생성하고 일정 시간이 지나면 다음과 같이 이메일이 도착합니다.
이메일 결과물을 좀 더 깔끔하게 보이고 싶다면 다음과 같이 코드를 수정해 볼 수 있습니다.
import json
import boto3
ec2 = boto3.client('ec2')
sns = boto3.client('sns')
SNS_TOPIC_ARN = 'arn:aws:sns:ap-northeast-2:xxxxxxxxxxxxx'
def lambda_handler(event, context):
print("🔍 Checking all EBS volumes for encryption status...")
unencrypted_volumes = []
# 모든 EBS 볼륨 조회
response = ec2.describe_volumes()
volumes = response['Volumes']
for volume in volumes:
volume_id = volume['VolumeId']
encrypted = volume.get('Encrypted', False)
print(f"Volume {volume_id} encrypted: {encrypted}")
if not encrypted:
unencrypted_volumes.append(volume_id)
# 알림 전송
if unencrypted_volumes:
volume_list = "\n".join([f"- {vid}" for vid in unencrypted_volumes])
message = f"""
🚨 *Unencrypted EBS Volumes Detected*
The following EBS volumes are **not encrypted**:
{volume_list}
Please review and take necessary action to enable encryption.
AWS Region: ap-northeast-2
Checked by: Lambda - EBS Encryption Scanner
"""
print(message)
sns.publish(
TopicArn=SNS_TOPIC_ARN,
Subject="🚨 Unencrypted EBS Volumes Detected",
Message=message
)
else:
print("✅ All EBS volumes are encrypted.")
return {
'statusCode': 200,
'body': f"암호화되지 않은 볼륨 개수: {len(unencrypted_volumes)}"
}
실제 메일로 오는 내용은 다음과 같습니다.
문의 사항은 클래스메소드 코리아로!
클래스메소드 코리아에서는 다양한 세미나 및 이벤트를 진행하고 있습니다.
진행중인 이벤트는 아래 페이지를 참고해주세요.
AWS에 대한 상담 및 클래스 메소드 멤버스에 관한 문의사항은 아래 메일로 연락주시면 감사드립니다!
Info@classmethod.kr