유의상황(실수 주의 코드 람다 수정하는 법)

대회/과제 요구사항(특히 "DB 정보 하드코딩 절대 금지")을 완벽하게 반영하여, AWS Secrets Manager에서 DB 정보를 가져와 RDS(MySQL)에 안전하게 연결하는 표준 Lambda 코드를 작성해 드립니다.

이 코드는 API Gateway를 통해 요청이 들어오거나 S3 이벤트가 발생했을 때 데이터베이스에서 users 테이블을 조회(SELECT)하는 예제입니다.


💻 Lambda + MySQL (Secrets Manager 연동) 완성 코드

Python 3.x 환경용 코드입니다. lambda_function.py에 이 코드를 복사해서 붙여넣으세요.

Python

import json
import boto3
import pymysql
import os
from botocore.exceptions import ClientError

def get_secret():
    """
    AWS Secrets Manager에서 데이터베이스 접속 정보를 가져옵니다.
    """
    secret_name = "/secret/db"  # 과제에서 요구한 시크릿 이름으로 변경하세요
    region_name = "ap-northeast-2" # 서울 리전

    # Secrets Manager 클라이언트 생성
    client = boto3.client('secretsmanager', region_name=region_name)

    try:
        response = client.get_secret_value(SecretId=secret_name)
        secret = json.loads(response['SecretString'])
        return secret
    except ClientError as e:
        print(f"Error retrieving secret: {e}")
        raise e

def lambda_handler(event, context):
    """
    Lambda 메인 핸들러 함수
    """
    # 1. Secrets Manager에서 DB 정보 로드 (하드코딩 방지)
    try:
        db_credentials = get_secret()
        # 시크릿에 저장된 Key 값(DB_HOST, DB_USER 등)은 실제 저장한 값과 맞춰야 합니다.
        db_host = db_credentials.get('DB_HOST') 
        db_user = db_credentials.get('DB_USER')
        db_password = db_credentials.get('DB_PASSWORD')
        db_name = db_credentials.get('DB_NAME')
    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps('Failed to retrieve secrets from Secrets Manager.')
        }

    # 2. RDS (MySQL) 연결
    try:
        connection = pymysql.connect(
            host=db_host,
            user=db_user,
            password=db_password,
            database=db_name,
            cursorclass=pymysql.cursors.DictCursor,
            connect_timeout=5
        )
    except pymysql.MySQLError as e:
        print("ERROR: Unexpected error: Could not connect to MySQL instance.")
        print(e)
        return {
            'statusCode': 500,
            'body': json.dumps('Database connection failed.')
        }

    # 3. 쿼리 실행 (예: users 테이블 조회)
    try:
        with connection.cursor() as cursor:
            # users 테이블에서 비밀번호를 제외하고 데이터 조회
            sql = "SELECT id, email, name, active FROM users LIMIT 10"
            cursor.execute(sql)
            result = cursor.fetchall()
            
        connection.commit()
    except Exception as e:
        print(f"Query Execution Error: {e}")
        return {
            'statusCode': 500,
            'body': json.dumps('Query execution failed.')
        }
    finally:
        connection.close()

    # 4. 결과 반환
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json'
        },
        'body': json.dumps(result)
    }

🚨 이 코드가 동작하기 위한 "4가지 필수 설정" (시험/과제 채점 포인트)

코드를 복사하는 것만으로는 절대 실행되지 않습니다! 아래 인프라 설정이 반드시 병행되어야 합니다.

1. 람다를 VPC 내부에 배치 (가장 많이 틀리는 부분)

2. 보안 그룹(Security Group) 설정

3. IAM 역할(Role) 권한 부여