Chapter 03 정답

RDS 데이터베이스 - 정답 및 해설

강사용 안내

  • 이 문서는 각 실습 단계의 웹 콘솔 풀이와 AWS CLI 풀이를 모두 포함합니다
  • RDS 생성에 5~15분이 소요되므로 사전에 미리 생성해두거나, 생성 대기 시간에 개념 설명을 진행하세요
  • 학생들이 가장 많이 실수하는 부분: 보안 그룹 소스 설정, 퍼블릭 액세스 설정, .env 수정 후 재시작 누락

정답 1: RDS용 보안 그룹 생성

해설

RDS 보안 그룹의 핵심은 소스를 IP가 아닌 EC2 보안 그룹으로 지정하는 것입니다. 이렇게 하면 EC2의 IP가 바뀌더라도, 해당 보안 그룹에 속한 인스턴스는 항상 RDS에 접근할 수 있습니다. 이것이 AWS 보안 그룹의 강력한 기능인 "보안 그룹 참조(Security Group Reference)"입니다.

VPC 콘솔 → 보안 그룹 → 보안 그룹 생성

AWS 콘솔에서 VPC → 보안 그룹 → 보안 그룹 생성을 클릭합니다.

기본 정보 입력
  • 보안 그룹 이름: ShopEasy-RDS-SG
  • 설명: ShopEasy RDS MySQL Security Group
  • VPC: ShopEasy-VPC 선택
인바운드 규칙 추가

"규칙 추가"를 클릭하고 다음을 설정합니다.

  • 유형: MySQL/Aurora
  • 포트 범위: 3306 (자동 입력됨)
  • 소스: "사용자 지정" 선택 → ShopEasy-EC2-SG의 보안 그룹 ID 입력 (sg-로 시작하는 값을 입력하면 자동완성 됨)
  • 설명: Allow MySQL from EC2
"보안 그룹 생성" 클릭

생성된 보안 그룹의 ID (예: sg-0abc1234def56789)를 메모합니다.

먼저 EC2 보안 그룹 ID와 VPC ID를 확인합니다.

bash
# VPC ID 확인
VPC_ID=$(aws ec2 describe-vpcs \
  --filters "Name=tag:Name,Values=ShopEasy-VPC" \
  --query "Vpcs[0].VpcId" \
  --output text \
  --region ap-northeast-2)
echo "VPC ID: $VPC_ID"

# EC2 보안 그룹 ID 확인
EC2_SG_ID=$(aws ec2 describe-security-groups \
  --filters "Name=group-name,Values=ShopEasy-EC2-SG" \
            "Name=vpc-id,Values=$VPC_ID" \
  --query "SecurityGroups[0].GroupId" \
  --output text \
  --region ap-northeast-2)
echo "EC2 SG ID: $EC2_SG_ID"

RDS 보안 그룹을 생성합니다.

bash
# RDS 보안 그룹 생성
RDS_SG_ID=$(aws ec2 create-security-group \
  --group-name ShopEasy-RDS-SG \
  --description "ShopEasy RDS MySQL Security Group" \
  --vpc-id $VPC_ID \
  --query "GroupId" \
  --output text \
  --region ap-northeast-2)
echo "RDS SG ID: $RDS_SG_ID"

# 인바운드 규칙 추가 - EC2 보안 그룹을 소스로 지정
aws ec2 authorize-security-group-ingress \
  --group-id $RDS_SG_ID \
  --protocol tcp \
  --port 3306 \
  --source-group $EC2_SG_ID \
  --region ap-northeast-2

# 태그 추가
aws ec2 create-tags \
  --resources $RDS_SG_ID \
  --tags Key=Name,Value=ShopEasy-RDS-SG \
  --region ap-northeast-2

생성 확인:

bash
aws ec2 describe-security-groups \
  --group-ids $RDS_SG_ID \
  --query "SecurityGroups[0].{Name:GroupName,ID:GroupId,Ingress:IpPermissions}" \
  --region ap-northeast-2

정답 2: DB 서브넷 그룹 생성

해설

DB 서브넷 그룹은 RDS 인스턴스가 배치될 수 있는 서브넷을 지정합니다. 반드시 2개 이상의 가용 영역(AZ)에 있는 서브넷이 필요합니다. 여기서는 Chapter 01에서 만든 프라이빗 서브넷 2개(10.0.100.0/24, 10.0.101.0/24)를 사용합니다.

RDS 콘솔 → 서브넷 그룹 → DB 서브넷 그룹 생성

AWS 콘솔에서 RDS → 서브넷 그룹 → DB 서브넷 그룹 생성을 클릭합니다.

기본 정보 입력
  • 이름: shopeasy-db-subnet-group
  • 설명: ShopEasy RDS DB Subnet Group
  • VPC: ShopEasy-VPC 선택
서브넷 추가
  • 가용 영역: ap-northeast-2aap-northeast-2c 선택
  • 서브넷:
    • ap-northeast-2a: 10.0.100.0/24 (프라이빗 서브넷 1) 선택
    • ap-northeast-2c: 10.0.101.0/24 (프라이빗 서브넷 2) 선택

주의: 퍼블릭 서브넷(10.0.1.0/24, 10.0.2.0/24)이 아닌 프라이빗 서브넷을 선택해야 합니다. 이름 태그나 CIDR 블록으로 구분하세요.

"생성" 클릭

DB 서브넷 그룹이 "활성" 상태인지 확인합니다.

먼저 프라이빗 서브넷 ID를 확인합니다.

bash
# 프라이빗 서브넷 ID 확인 (이름 태그 기준)
PRIV_SUBNET_1=$(aws ec2 describe-subnets \
  --filters "Name=vpc-id,Values=$VPC_ID" \
            "Name=cidr-block,Values=10.0.100.0/24" \
  --query "Subnets[0].SubnetId" \
  --output text \
  --region ap-northeast-2)

PRIV_SUBNET_2=$(aws ec2 describe-subnets \
  --filters "Name=vpc-id,Values=$VPC_ID" \
            "Name=cidr-block,Values=10.0.101.0/24" \
  --query "Subnets[0].SubnetId" \
  --output text \
  --region ap-northeast-2)

echo "Private Subnet 1: $PRIV_SUBNET_1"
echo "Private Subnet 2: $PRIV_SUBNET_2"

DB 서브넷 그룹을 생성합니다.

bash
aws rds create-db-subnet-group \
  --db-subnet-group-name shopeasy-db-subnet-group \
  --db-subnet-group-description "ShopEasy RDS DB Subnet Group" \
  --subnet-ids $PRIV_SUBNET_1 $PRIV_SUBNET_2 \
  --region ap-northeast-2

생성 확인:

bash
aws rds describe-db-subnet-groups \
  --db-subnet-group-name shopeasy-db-subnet-group \
  --query "DBSubnetGroups[0].{Name:DBSubnetGroupName,Status:SubnetGroupStatus,Subnets:Subnets[*].{AZ:SubnetAvailabilityZone.Name,SubnetId:SubnetIdentifier}}" \
  --region ap-northeast-2

정답 3: RDS MySQL 인스턴스 생성

해설

RDS 인스턴스 생성 시 주의할 설정:

  • 템플릿: 프리 티어 - db.t3.micro 자동 선택, 비용 절약
  • 퍼블릭 액세스: 아니요 - 가장 중요! 인터넷에서 직접 접근 차단
  • 초기 데이터베이스 이름: ecommerce - 빈칸으로 두면 기본 DB가 생성되지 않음
  • VPC 보안 그룹: ShopEasy-RDS-SG - default가 아닌 직접 만든 보안 그룹 선택
RDS 콘솔 → 데이터베이스 → 데이터베이스 생성

RDS → 데이터베이스 → 데이터베이스 생성을 클릭합니다.

엔진 옵션
  • 데이터베이스 생성 방식: 표준 생성
  • 엔진 유형: MySQL
  • 엔진 버전: MySQL 8.0.x (최신 기본값)
  • 템플릿: 프리 티어 선택
설정
  • DB 인스턴스 식별자: shopeasy-db
  • 마스터 사용자 이름: admin
  • 자격 증명 관리: 자체 관리
  • 마스터 암호: 직접 설정 (예: ShopEasy2024!)
  • 암호 확인: 동일하게 입력
인스턴스 구성
  • DB 인스턴스 클래스: db.t3.micro (프리 티어 선택 시 자동)
스토리지
  • 스토리지 유형: 범용 SSD (gp2)
  • 할당된 스토리지: 20 GiB
  • 스토리지 자동 조정: 체크 해제
연결
  • 컴퓨팅 리소스: EC2 컴퓨팅 리소스에 연결 안 함
  • 네트워크 유형: IPv4
  • VPC: ShopEasy-VPC
  • DB 서브넷 그룹: shopeasy-db-subnet-group
  • 퍼블릭 액세스: 아니요
  • VPC 보안 그룹: "기존 항목 선택" → ShopEasy-RDS-SG (default 보안 그룹은 제거)
  • 가용 영역: 기본 설정 유지
추가 구성 펼치기
  • 초기 데이터베이스 이름: ecommerce (반드시 입력!)
  • 자동 백업: 체크 해제 (실습용)
  • 암호화: 기본값 유지
  • 삭제 방지: 체크 해제 (실습 후 삭제 편의)
"데이터베이스 생성" 클릭

5~15분 후 상태가 "사용 가능(Available)"이 되면, "연결 & 보안" 탭에서 엔드포인트를 확인합니다.

엔드포인트 예시: shopeasy-db.cxxxxxxxxx.ap-northeast-2.rds.amazonaws.com

bash
# RDS MySQL 인스턴스 생성
aws rds create-db-instance \
  --db-instance-identifier shopeasy-db \
  --db-instance-class db.t3.micro \
  --engine mysql \
  --engine-version 8.0 \
  --master-username admin \
  --master-user-password "ShopEasy2024!" \
  --allocated-storage 20 \
  --storage-type gp2 \
  --db-subnet-group-name shopeasy-db-subnet-group \
  --vpc-security-group-ids $RDS_SG_ID \
  --db-name ecommerce \
  --no-publicly-accessible \
  --no-multi-az \
  --backup-retention-period 0 \
  --no-deletion-protection \
  --no-storage-encrypted \
  --region ap-northeast-2

생성 상태 확인 (Available이 될 때까지 반복):

bash
# 상태 확인
aws rds describe-db-instances \
  --db-instance-identifier shopeasy-db \
  --query "DBInstances[0].{Status:DBInstanceStatus,Endpoint:Endpoint.Address,Port:Endpoint.Port}" \
  --region ap-northeast-2

엔드포인트 확인 (Available 상태에서):

bash
# 엔드포인트 가져오기
RDS_ENDPOINT=$(aws rds describe-db-instances \
  --db-instance-identifier shopeasy-db \
  --query "DBInstances[0].Endpoint.Address" \
  --output text \
  --region ap-northeast-2)
echo "RDS Endpoint: $RDS_ENDPOINT"

정답 4: EC2에서 RDS 접속 테스트

해설

EC2에서 RDS에 접속할 때는 MySQL 클라이언트가 필요합니다. Amazon Linux 2023에서는 mariadb105 패키지를 설치하면 MySQL 호환 클라이언트를 사용할 수 있습니다. 접속이 성공하면 보안 그룹과 네트워크 설정이 올바르다는 의미입니다.

EC2에 SSH 접속
bash
# 로컬 PC에서 EC2에 SSH 접속
ssh -i your-key.pem ec2-user@EC2_PUBLIC_IP
MySQL 클라이언트 설치
bash
# MariaDB 클라이언트 설치 (MySQL 호환)
sudo dnf install mariadb105 -y

# 설치 확인
mysql --version

출력 예시: mysql Ver 15.1 Distrib 10.5.xx-MariaDB

RDS 접속
bash
# RDS 접속 (엔드포인트를 실제 값으로 교체)
mysql -h shopeasy-db.cxxxxxxxxx.ap-northeast-2.rds.amazonaws.com -u admin -p

비밀번호 입력 후 MySQL [(none)]> 프롬프트가 나타나면 성공입니다.

데이터베이스 확인
sql
-- 데이터베이스 목록 확인
SHOW DATABASES;

-- ecommerce DB 사용
USE ecommerce;

-- 테이블 확인 (아직 비어있는 것이 정상)
SHOW TABLES;

-- 접속 종료
exit;

SHOW DATABASES; 결과에 ecommerce가 보이면 정상입니다. SHOW TABLES;에서 "Empty set"이 나오는 것은 정상입니다 (seed.js를 아직 실행하지 않았으므로).

CLI에서도 동일하게 EC2에 SSH 접속 후 MySQL 클라이언트를 사용합니다.

bash
# 한 줄로 접속 테스트 (비밀번호도 인라인으로)
mysql -h $RDS_ENDPOINT -u admin -p"ShopEasy2024!" -e "SHOW DATABASES;"

예상 출력:

text
+--------------------+
| Database           |
+--------------------+
| ecommerce          |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

정답 5: API 서버 .env 수정

해설

ShopEasy API 서버는 .env 파일의 DB_TYPE 값에 따라 SQLite 또는 MySQL을 사용합니다. DB_TYPE=mysql로 변경하면 DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME 값을 읽어 RDS MySQL에 접속합니다.

EC2에서 .env 파일 수정
bash
cd ~/ecommerce-app/api-server
nano .env
.env 파일 내용 (수정 후)

데이터베이스 관련 부분만 다음과 같이 변경합니다.

env
# 서버 포트
PORT=5000

# 데이터베이스 설정 - MySQL (RDS)
DB_TYPE=mysql
DB_HOST=shopeasy-db.cxxxxxxxxx.ap-northeast-2.rds.amazonaws.com
DB_PORT=3306
DB_USER=admin
DB_PASSWORD=ShopEasy2024!
DB_NAME=ecommerce

# 나머지 설정은 그대로 유지
STORAGE_TYPE=local
REVIEW_STORE=local
CACHE_TYPE=memory
QUEUE_TYPE=sync
JWT_SECRET=ecommerce-jwt-secret-key-2024

Ctrl + O → Enter (저장) → Ctrl + X (종료)

sed 명령어로 .env 파일을 수정할 수도 있습니다.

bash
cd ~/ecommerce-app/api-server

# DB_TYPE 변경
sed -i 's/^DB_TYPE=sqlite/DB_TYPE=mysql/' .env

# DB_HOST 설정
sed -i "s/^DB_HOST=.*/DB_HOST=$RDS_ENDPOINT/" .env

# DB_PORT 설정
sed -i 's/^DB_PORT=.*/DB_PORT=3306/' .env

# DB_USER 설정
sed -i 's/^DB_USER=.*/DB_USER=admin/' .env

# DB_PASSWORD 설정
sed -i 's/^DB_PASSWORD=.*/DB_PASSWORD=ShopEasy2024!/' .env

# DB_NAME 설정
sed -i 's/^DB_NAME=.*/DB_NAME=ecommerce/' .env

# 변경 확인
cat .env | grep DB_

정답 6: API 서버 재시작 & 시드 데이터 입력

해설

.env 파일을 수정한 후에는 반드시 서버를 재시작해야 합니다. Node.js는 시작 시 .env를 읽으므로, 실행 중인 서버는 이전 설정을 사용합니다. seed.js는 테이블을 자동 생성하고 기본 데이터를 넣어줍니다.

실행 중인 서버 종료
bash
# pm2를 사용 중인 경우
pm2 stop all

# 프로세스 직접 실행 중인 경우
# Ctrl + C 로 종료
MySQL 드라이버(mysql2) 설치
bash
cd ~/ecommerce-app/api-server
npm install mysql2

mysql2는 Node.js에서 MySQL에 접속하기 위한 드라이버 패키지입니다. SQLite만 사용했던 환경에서는 이 패키지가 설치되어 있지 않을 수 있습니다.

시드 데이터 입력
bash
node seed.js

성공 출력 예시:

text
========================================
  시드 데이터 생성 시작
========================================

[1/2] 테스트 사용자 생성 중...
  ✔ 사용자 생성: test@test.com / password123

[2/2] 상품 데이터 생성 중...
  ✔ 20개 상품 생성 완료

========================================
  시드 데이터 생성 완료!
========================================

  테스트 계정: test@test.com / password123
  상품 수: 20개
  카테고리: 전자기기, 패션, 식품, 생활용품, 뷰티
RDS에서 데이터 확인 (선택)
bash
# MySQL 클라이언트로 RDS 접속
mysql -h shopeasy-db.cxxxxxxxxx.ap-northeast-2.rds.amazonaws.com -u admin -p
sql
USE ecommerce;
SHOW TABLES;
SELECT COUNT(*) FROM products;
SELECT id, name, price, category FROM products LIMIT 5;
SELECT id, email, name FROM users;
exit;

products 테이블에 20개, users 테이블에 1개의 레코드가 있으면 정상입니다.

API 서버 재시작
bash
# pm2 사용
pm2 start server.js --name shopeasy-api
pm2 logs shopeasy-api --lines 20

# 또는 직접 실행 (백그라운드)
nohup node server.js > server.log 2>&1 &
tail -f server.log

로그에 "Server running on port 5000" 메시지가 보이고 DB 관련 에러가 없으면 성공입니다.

이 단계는 EC2 내에서 실행하는 것이므로 웹 콘솔과 동일합니다.

bash
# 한 번에 실행
cd ~/ecommerce-app/api-server && \
npm install mysql2 && \
node seed.js && \
pm2 restart shopeasy-api || pm2 start server.js --name shopeasy-api

정답 7: API 테스트

해설

curl 명령어로 API 서버의 주요 기능을 테스트합니다. 회원가입 → 로그인 → 상품 조회 순서로 진행하여 RDS MySQL에 데이터가 정상적으로 읽기/쓰기 되는지 확인합니다. 이 테스트는 로컬 PC에서 실행합니다 (EC2가 아님).

회원가입 테스트

새로운 터미널에서 (로컬 PC) 다음 명령어를 실행합니다. EC2_PUBLIC_IP를 실제 IP로 교체하세요.

bash
curl -X POST http://EC2_PUBLIC_IP:5000/api/auth/signup \
  -H "Content-Type: application/json" \
  -d '{"username":"testuser","email":"test@test.com","password":"test1234"}'

성공 응답 예시:

json
{
  "message": "회원가입 성공",
  "user": {
    "id": 2,
    "email": "test@test.com",
    "name": "testuser"
  }
}

참고: seed.js에서 이미 test@test.com으로 사용자를 만들었으므로 "이미 존재하는 이메일" 에러가 나올 수 있습니다. 다른 이메일로 시도하거나, 에러가 나오는 것 자체가 DB 연동이 정상이라는 증거입니다.

로그인 테스트
bash
curl -X POST http://EC2_PUBLIC_IP:5000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"test@test.com","password":"test1234"}'

성공 응답 예시:

json
{
  "message": "로그인 성공",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": 1,
    "email": "test@test.com",
    "name": "테스트유저"
  }
}

참고: seed.js에서 만든 사용자의 비밀번호는 password123이고, curl에서 가입한 사용자의 비밀번호는 test1234입니다. 로그인 시 올바른 비밀번호를 사용하세요.

상품 조회 테스트
bash
curl http://EC2_PUBLIC_IP:5000/api/products

성공 응답 예시 (일부):

json
[
  {
    "id": 1,
    "name": "삼성 갤럭시 S24 울트라",
    "description": "최신 AI 기능을 탑재한 프리미엄 스마트폰...",
    "price": 1698000,
    "category": "전자기기",
    "stock": 50
  },
  {
    "id": 2,
    "name": "LG 그램 17인치 노트북",
    "description": "초경량 17인치 노트북...",
    "price": 1890000,
    "category": "전자기기",
    "stock": 30
  },
  ...
]

20개의 상품 데이터가 JSON으로 출력되면 RDS MySQL 연동 완료입니다!

(선택) JSON 보기 좋게 출력
bash
# jq가 설치되어 있으면
curl -s http://EC2_PUBLIC_IP:5000/api/products | jq .

# python이 있으면
curl -s http://EC2_PUBLIC_IP:5000/api/products | python3 -m json.tool

API 테스트는 curl 명령어를 사용하므로 웹 콘솔 방법과 동일합니다. 아래는 EC2 퍼블릭 IP를 자동으로 가져와서 테스트하는 방법입니다.

bash
# EC2 퍼블릭 IP 가져오기
EC2_IP=$(aws ec2 describe-instances \
  --filters "Name=tag:Name,Values=ShopEasy-EC2" \
            "Name=instance-state-name,Values=running" \
  --query "Reservations[0].Instances[0].PublicIpAddress" \
  --output text \
  --region ap-northeast-2)
echo "EC2 IP: $EC2_IP"

# 회원가입
curl -X POST http://$EC2_IP:5000/api/auth/signup \
  -H "Content-Type: application/json" \
  -d '{"username":"cliuser","email":"cli@test.com","password":"test1234"}'

echo ""

# 로그인
curl -X POST http://$EC2_IP:5000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"test@test.com","password":"password123"}'

echo ""

# 상품 조회
curl -s http://$EC2_IP:5000/api/products | python3 -m json.tool | head -30

트러블슈팅

자주 발생하는 문제와 해결 방법

EC2에서 RDS에 접속이 안 됩니다 (Connection timed out)

원인: 보안 그룹 설정 오류가 가장 많습니다.

  • 확인 1: RDS 보안 그룹(ShopEasy-RDS-SG)의 인바운드 규칙에 포트 3306이 있는지 확인
  • 확인 2: 소스가 EC2 보안 그룹 ID (sg-xxxx)로 설정되어 있는지 확인. 0.0.0.0/0이나 다른 IP가 아닌 보안 그룹 ID여야 합니다
  • 확인 3: EC2에 실제로 ShopEasy-EC2-SG 보안 그룹이 적용되어 있는지 확인
  • 확인 4: EC2와 RDS가 같은 VPC에 있는지 확인
bash
# 보안 그룹 규칙 확인
aws ec2 describe-security-groups \
  --filters "Name=group-name,Values=ShopEasy-RDS-SG" \
  --query "SecurityGroups[0].IpPermissions" \
  --region ap-northeast-2
RDS에 접속은 되지만 "Access denied for user" 에러 발생

원인: 마스터 사용자 이름 또는 비밀번호가 올바르지 않습니다.

  • 마스터 사용자 이름이 admin인지 확인
  • 비밀번호에 특수문자가 있으면 따옴표로 감싸서 입력: mysql -h ENDPOINT -u admin -p'MyP@ss!'
  • 비밀번호를 잊어버린 경우: RDS 콘솔에서 "수정" → 마스터 암호 변경 (적용까지 수 분 소요)
RDS 인스턴스 생성에 시간이 너무 오래 걸립니다

정상입니다. RDS 인스턴스 생성에는 보통 5~15분이 소요됩니다.

  • 상태가 "생성 중(Creating)"에서 "사용 가능(Available)"이 될 때까지 기다립니다
  • 이 시간에 .env 수정 방법, 보안 그룹 개념을 복습하는 것을 권장합니다
  • 미리 생성해둔 RDS를 사용하는 것도 방법입니다
bash
# 상태 확인 (반복해서 확인)
aws rds describe-db-instances \
  --db-instance-identifier shopeasy-db \
  --query "DBInstances[0].DBInstanceStatus" \
  --output text \
  --region ap-northeast-2
mysql 명령어가 없다고 나옵니다 (command not found)

원인: MySQL 클라이언트가 설치되지 않았습니다.

bash
# Amazon Linux 2023
sudo dnf install mariadb105 -y

# Amazon Linux 2 (구 버전)
sudo yum install mysql -y

# 설치 후 확인
mysql --version
node seed.js 실행 시 "ECONNREFUSED" 에러

원인: API 서버가 RDS에 접속하지 못하고 있습니다.

  • .envDB_HOST가 RDS 엔드포인트와 정확히 일치하는지 확인
  • DB_PORT3306인지 확인
  • 먼저 mysql 클라이언트로 직접 접속이 되는지 테스트
  • 보안 그룹 설정 확인
node seed.js 실행 시 "ER_NOT_SUPPORTED_AUTH_MODE" 에러

원인: MySQL 8.0의 인증 플러그인 호환성 문제입니다.

  • mysql2 패키지가 설치되었는지 확인: npm list mysql2
  • 설치가 안 되었으면: npm install mysql2
  • mysql (1 버전)이 아닌 mysql2 패키지를 사용해야 합니다
.env 수정 후에도 여전히 SQLite를 사용합니다

원인: .env 수정 후 서버를 재시작하지 않았습니다.

  • Node.js는 실행 시점에 .env를 읽습니다. 실행 중에는 변경 사항이 반영되지 않습니다
  • 반드시 서버를 종료 후 재시작해야 합니다
bash
# pm2 재시작
pm2 restart shopeasy-api

# 또는 전체 중지 후 시작
pm2 stop all
pm2 start server.js --name shopeasy-api
"초기 데이터베이스 이름"을 입력하지 않았습니다

원인: RDS 생성 시 "추가 구성"에서 초기 데이터베이스 이름을 비워두면 기본 DB가 생성되지 않습니다.

  • MySQL 클라이언트로 접속 후 수동으로 생성합니다:
sql
CREATE DATABASE ecommerce CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
SHOW DATABASES;
curl 명령이 응답하지 않습니다 (연결 시간 초과)

원인: EC2 보안 그룹에서 포트 5000이 열려있지 않습니다.

  • EC2 보안 그룹(ShopEasy-EC2-SG)의 인바운드 규칙에 포트 5000 (또는 사용자 지정 TCP 5000)이 있는지 확인
  • 소스가 0.0.0.0/0 (어디서나 접근) 또는 본인의 IP인지 확인
  • API 서버가 실제로 실행 중인지 확인: pm2 status

강의 팁

진행 시 유의사항
  • RDS 사전 생성 권장: 수업 시작 전에 RDS를 미리 생성해두면 대기 시간을 줄일 수 있습니다. 학생들에게 생성 과정을 보여주고, 실제 사용은 미리 만들어둔 인스턴스를 활용합니다
  • 비밀번호 통일: 학생들이 비밀번호를 잊어버리는 경우가 많습니다. 실습용 공통 비밀번호를 정하는 것도 방법입니다 (예: ShopEasy2024!)
  • 보안 그룹 참조 강조: IP 대신 보안 그룹 ID를 소스로 사용하는 것은 AWS의 핵심 보안 패턴입니다. 이 부분을 충분히 설명해 주세요
  • .env 수정 후 재시작: 학생들이 가장 많이 놓치는 부분입니다. 수정 후 반드시 재시작해야 한다는 점을 여러 번 강조하세요
학생 질문 예상 답변
  • Q: 왜 db.t3.micro를 쓰나요?
    A: 프리 티어에서 무료로 사용 가능한 최소 사양입니다. 실습용으로 충분하며, 운영 환경에서는 트래픽에 맞게 더 큰 인스턴스를 사용합니다.
  • Q: Multi-AZ는 뭔가요?
    A: 다른 가용 영역에 대기 DB를 만들어두는 것입니다. 메인 DB에 장애가 나면 자동으로 대기 DB로 전환됩니다. 비용이 2배지만 가용성이 높아집니다. 실습에서는 비용 절약을 위해 사용하지 않습니다.
  • Q: 로컬 PC에서 RDS에 직접 접속할 수 없나요?
    A: 퍼블릭 액세스를 "아니요"로 설정했기 때문에 인터넷에서 직접 접속할 수 없습니다. 같은 VPC 안의 EC2를 통해서만 접근 가능합니다. 이것이 프라이빗 서브넷에 DB를 배치하는 이유입니다.
  • Q: SQLite 데이터는 어떻게 되나요?
    A: EC2의 SQLite 파일은 그대로 남아있지만 더 이상 사용하지 않습니다. DB_TYPE=mysql로 변경했으므로 모든 데이터는 RDS MySQL에 저장됩니다.
비용 주의

db.t3.micro는 프리 티어에서 월 750시간 무료이지만, 프리 티어 기간이 만료된 계정이나 다른 RDS 인스턴스가 이미 있는 경우 시간당 약 $0.026의 비용이 발생합니다. 실습이 끝나면 반드시 RDS 인스턴스를 삭제하도록 안내하세요. (Chapter 08에서 정리 예정)