Gemini의 응답
대회 전 마지막으로 머릿속에 완벽하게 집어넣을 수 있도록, 'DB와 연동되는 AWS Lambda 모듈(패키지)'의 A to Z를 실전 체크리스트 형태로 총정리해 드립니다.
이 4단계 흐름만 머릿속에 그려지면 어떤 변형 과제가 나와도 당황하지 않으실 겁니다!
핸들러 (입구): AWS가 코드를 실행하는 진입점입니다. lambda_function.py 파일의 lambda_handler(event, context) 구조를 유지하고, 콘솔 설정과 이름이 일치하는지 확인하세요.
외부 라이브러리: pymysql, requests 등은 람다에 기본 내장되어 있지 않습니다.
해결책: 폴더에 직접 설치해서 코드와 함께 .zip 파일로 압축하여 올리거나, 대회에서 제공된 Lambda Layer를 연결해야 합니다.
하드코딩 제거: 파일에 적힌 password = "1234" 같은 값은 지우세요.
환경 변수 활용: 파이썬의 os.environ.get('DB_USER') 모듈을 사용해 코드를 깔끔하게 만들고, 실제 값은 AWS Lambda 콘솔의 [환경 변수] 탭에 입력하세요.
VPC & 서브넷: 람다가 RDS(데이터베이스)에 접속해야 한다면, 람다를 RDS와 같은 집(VPC) 안으로 들여보내야 합니다.
보안 그룹 (Security Group): RDS의 문지기(인바운드 규칙)에게 "우리 람다(람다의 보안 그룹 ID)가 3306 포트로 들어오면 문을 열어줘"라고 설정해야 합니다.
IAM 역할 (Role): 람다가 Secrets Manager나 S3를 읽어야 한다면, 람다의 '실행 역할'에 해당 서비스에 접근할 수 있는 권한(Policy)이 부여되어야 합니다.
제한 시간 (Timeout): 기본 3초는 DB 접속에 너무 짧습니다. 10초~30초로 넉넉하게 늘려두세요.
에러 핸들링 (try-except): 에러가 났을 때 시스템이 멈추지 않고, {"statusCode": 500, "message": "DB Error"} 처럼 깔끔한 JSON 응답을 뱉도록 처리하세요.
로그 확인: 테스트 후 무조건 CloudWatch Logs로 들어가서 print()로 찍어둔 값들이나 에러 로그를 확인하는 습관을 들이세요.
기능대회는 기술력뿐만 아니라, 제한된 시간 안에 아키텍처의 퍼즐을 정확히 끼워 맞추는 침착함을 보는 자리입니다. 지금까지 짚어드린 내용들을 잘 숙지하셨으니 좋은 결과가 있을 거예요!
전체적인 배포 흐름 중에서 혹시 아직 머릿속에 완벽하게 그려지지 않는 단계가 남아있나요?
말씀하신 내용
그럼 환경변수와 압축과 그런게 적용되기 전의 파일과 적용된 후의 파일의 차이점을 보여줘
Gemini의 응답
가장 직관적으로 이해할 수 있도록, 대회에서 던져주는 '날것(Before)'의 파일과 네가 세팅을 끝마친 '제출용(After)' 파일 및 구조가 어떻게 달라지는지 딱 비교해서 보여줄게!
❌ Before: 대회에서 제공받은 초기 상태 (감점/실패 요인)
처음 파일을 열면 보통 보안도, 예외 처리도 없는 뼈대만 덩그러니 있을 거야. 이대로 AWS 콘솔에 복사해서 붙여넣으면 백발백중 에러가 나거나 감점을 받게 돼.
파일 상태: * lambda_function.py 파일 딱 하나만 있음. (pymysql 라이브러리가 없어서 실행 불가)
코드 상태 (lambda_function.py):
Python
import pymysql
import json
db_host = "test-db.rds.amazonaws.com"
name = "admin"
password = "supersecretpassword123!"
db_name = "competition_db"
def lambda_handler(event, context):
# 🚨 문제점 2: 매번 실행될 때마다 무조건 DB에 새로 접속함 (성능 저하)
conn = pymysql.connect(
host=db_host,
user=name,
password=password,
database=db_name
)
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
result = cursor.fetchall()
# 🚨 문제점 3: 에러가 나면 프로그램이 그냥 뻗어버림 (try-except 없음)
return {
'statusCode': 200,
'body': json.dumps(result)
}
✅ After: 네가 수정한 완벽한 제출 상태 (가산점/합격 요인)
보안, 성능, 그리고 실제 AWS 환경에서 돌아갈 수 있도록 패키징까지 완료된 완벽한 상태야.
Plaintext
내폴더/
├── lambda_function.py (수정된 내 코드)
├── pymysql/ (pip install pymysql -t . 로 설치한 라이브러리 폴더)
├── PyMySQL-1.1.0.dist-info/
└── ...
👉 이 폴더 안의 내용물들을 싹 다 잡아서 deploy.zip으로 압축한 뒤 Lambda에 업로드!
Python
import pymysql
import json
import os # 🌟 개선 1: 환경변수 사용을 위해 추가
DB_HOST = os.environ.get('DB_HOST')
DB_USER = os.environ.get('DB_USER')
DB_PASSWORD = os.environ.get('DB_PASSWORD')
DB_NAME = os.environ.get('DB_NAME')
connection = None
def lambda_handler(event, context):
global connection
try:
# 연결이 끊어져 있거나 아예 없을 때만 새로 연결 (성능 대폭 향상)
if not connection or not connection.open:
connection = pymysql.connect(
host=DB_HOST,
user=DB_USER,
password=DB_PASSWORD,
database=DB_NAME,
connect_timeout=5
)
with connection.cursor(pymysql.cursors.DictCursor) as cursor:
cursor.execute("SELECT * FROM users LIMIT 10")
result = cursor.fetchall()
return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps({"message": "Success", "data": result}, default=str)
}
except Exception as e:
# 🌟 개선 4: 에러가 나더라도 서버가 죽지 않고 친절하게 500 에러를 반환함
print(f"Error executing query: {e}")
return {
'statusCode': 500,
'body': json.dumps({"error": "Internal Server Error"})
}
💡 한눈에 보는 핵심 차이점
배포 방식: 텍스트 복붙(Before) ➡️ 의존성 라이브러리와 함께 .zip 압축 업로드 (After)
보안: 하드코딩(Before) ➡️ os.environ.get() + Lambda 콘솔 환경변수 세팅 (After)
성능: 매번 DB 연결(Before) ➡️ 전역 변수(global connection)를 활용한 연결 재사용 (After)
안정성: 에러 나면 뻗음(Before) ➡️ try-except로 우아하게 방어 (After)
이렇게 코드를 수정하고 폴더를 압축하는 과정(로컬 PC에서 pip install -t . 치고 압축하는 것)은 대회 환경에서 직접 해볼 수 있을 것 같아? 아니면 패키징하는 명령어 순서를 다시 한번 정리해 줄까?