3. 이벤트 기반 데이터 처리 및 백업 아키텍처
제2과제의 S3 Query 및 MySQL with Lambda 요구사항을 결합한 통합 인프라 구조입니다.
•
구성: S3 버킷, Lambda 함수, EC2, 그리고 EFS가 연동됩니다.
•
EFS 활용: EC2에서 생성된 로그나 결과 파일을 EFS에 저장하면, 이를 주기적으로 S3로 백업하거나 Lambda가 참조하는 구조입니다.
• 보안 정책:
◦
S3 & Lambda: Lambda가 S3에서 데이터를 조회(Query)하여 MySQL에 저장할 때, 관련 자원에만 접근할 수 있도록 최소 권한 원칙(Least Privilege)을 적용한 IAM 정책을 구성합니다.
◦
네트워크: 모든 리소스 생성 시 문제에서 지정한 Region을 준수하며, 채점용 Cloud Shell 접근에 문제가 없도록 구성합니다.
대회 현장에서 문제지의 요구사항에 따라 실시간으로 수정해야 하는 변수들을 명확하게 구분해 드릴게요.
이 스크립트는 Shared Network Storage(EFS), S3 Query(Athena), MySQL 연동 아키텍처를 모두 아우르는 통합 버전입니다. < >로 표시된 부분은 환경에 맞게 반드시 바꿔야 하는 변동 구간입니다.
Bash
#!/bin/bash
# [1] 시스템 업데이트 및 패키지 설치
yum update -y
yum install -y amazon-efs-utils mysql jq # jq는 JSON 파싱용으로 유용합니다.
# [2] 디렉토리 설정 (변동 가능: 문제지에서 지정한 경로로 수정)
# 예: /var/www/html 또는 /mnt/shared_data 등
MOUNT_PATH="<마운트_경로_예: /mnt/efs>"
mkdir -p $MOUNT_PATH
# [3] EFS 마운트 설정 (변동 필수: 생성한 리소스 ID 입력)
# <EFS_ID> 예시: fs-0123456789abcdef
EFS_ID="<본인의_EFS_ID>"
mount -t efs -o tls $EFS_ID:/ $MOUNT_PATH
# [4] 부팅 시 자동 마운트 (변동 필수: 위와 동일한 ID와 경로 사용)
echo "$EFS_ID:/ $MOUNT_PATH efs _netdev,tls 0 0" >> /etc/fstab
# [5] 권한 설정 (변동 가능: 필요에 따라 ec2-user 또는 apache 등으로 변경)
chown -R <사용자명_예: ec2-user>:<그룹명_예: ec2-user> $MOUNT_PATH
chmod -R 775 $MOUNT_PATH
# [6] 데이터베이스 및 서비스 연동 (변동 필수: RDS 정보 입력)
# MySQL with Lambda 과제 시 EC2에서 테스트용으로 사용됩니다.
DB_HOST="<RDS_엔드포인트_주소>"
DB_USER="<데이터베이스_사용자명>"
DB_PASS="<데이터베이스_비밀번호>"
S3_BUCKET="<데이터_버킷_이름>"
# [7] 테스트 파일 생성 (변동 가능: 결과 확인용 로그 경로)
echo "Setup completed at $(date)" > $MOUNT_PATH/setup_log.txt
| 구분 | 변수명 (스크립트 내) | 설명 및 확인 방법 |
|---|---|---|
| 인프라 식별자 | <본인의_EFS_ID> | EFS를 생성한 후 할당받는 fs-xxxx 형태의 ID입니다. 가장 빈번하게 틀리는 부분이니 복사/붙여넣기 시 주의하세요. |
| 파일 시스템 경로 | <마운트_경로> | 문제지 요구사항에 "공유 저장소를 /data에 구성하시오"라고 되어 있다면 해당 경로로 바꿔야 합니다. |
| 데이터베이스 정보 | <RDS_엔드포인트> | 생성된 RDS(MySQL)의 연결 및 보안 탭에 있는 엔드포인트 주소입니다. |
| 인증 정보 | <DB_USER>, <DB_PASS> | RDS 생성 시 설정한 마스터 사용자 이름과 비밀번호입니다. (보안상 Secrets Manager 사용 시 코드가 달라질 수 있음) |
| S3 리소스 | <데이터_버킷_이름> | Query from S3를 위해 데이터가 저장된 버킷의 정확한 이름입니다. |
| 권한 대상 | <사용자명>, <그룹명> | 웹 서버(Nginx/Apache)를 올린다면 www-data나 apache로 바꿔야 할 수도 있습니다. |
Lambda가 S3의 이벤트를 받아 MySQL에 데이터를 넣거나, SQS 메시지를 처리하는 핵심 로직입니다.
import json
import pymysql # 과제 환경에 따라 설치/패키징 필요할 수 있음
import boto3
import os
# [변동 필수: 환경 변수 또는 직접 입력]
DB_HOST = "<RDS_엔드포인트>"
DB_USER = "<DB_사용자명>"
DB_PASS = "<DB_비밀번호>"
DB_NAME = "<데이터베이스_이름>"
def lambda_handler(event, context):
# 1. DB 연결
conn = pymysql.connect(host=DB_HOST, user=DB_USER, password=DB_PASS, db=DB_NAME)
try:
with conn.cursor() as cursor:
# 2. 이벤트 분석 (S3 또는 SQS 메시지 예시)
# <변동 가능: 문제에서 요구하는 로직에 따라 파싱 방법이 달라짐>
message = event['Records'][0]['body']
# 3. MySQL 쿼리 실행
sql = "INSERT INTO <테이블명> (content) VALUES (%s)"
cursor.execute(sql, (message,))
conn.commit()
return {"statusCode": 200, "body": "Data inserted successfully"}
finally:
conn.close()
S3에 저장된 로그나 CSV 파일을 데이터베이스 테이블처럼 만드는 과정입니다. Athena 콘솔에서 실행합니다.
-- [변동 필수: 테이블명 및 S3 경로]
CREATE EXTERNAL TABLE IF NOT EXISTS <데이터베이스명>.<테이블명> (
`id` string,
`timestamp` string,
`message` string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',' -- <변동 가능: CSV는 ',', TSV는 '\t' 등>
STORED AS TEXTFILE
LOCATION 's3://<데이터_버킷_이름>/<폴더경로>/' -- <변동 필수: 데이터가 있는 S3 경로>
TBLPROPERTIES ('has_encrypted_data'='false');
-- 데이터 조회 테스트
SELECT * FROM <테이블명> LIMIT 10;
특정 리소스에만 접근을 허용하는 JSON 정책입니다. 이 부분을 얼마나 꼼꼼하게 짜느냐가 변별력입니다.
[예시: 특정 S3 버킷과 SQS에만 접근 허용]
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::<데이터_버킷_이름>",
"arn:aws:s3:::<데이터_버킷_이름>/*"
]
},
{
"Effect": "Allow",
"Action": [
"sqs:ReceiveMessage",
"sqs:DeleteMessage"
],
"Resource": "arn:aws:sqs:<리전_예:ap-northeast-2>:<계정ID>:<큐_이름>"
}
]
}
EC2에서 SQS가 제대로 동작하는지 확인할 때 유용합니다.
aws sqs send-message --queue-url <SQS_URL> --message-body "<전송할_메시지_내용>" --region <지정된_리전>
aws sqs receive-message --queue-url <SQS_URL> --region <지정된_리전>
aws ec2 create-tags 같은 CLI 명령어를 한 곳에 모아두고 한꺼번에 실행하는 것도 전략입니다.