AWS에서 RDS PostgreSQL 만들기
AWS RDS에서 PostgreSQL 데이터베이스를 만들고, 보안 그룹과 Prisma migration을 통해 백엔드 프로젝트와 연결한 과정을 정리한 글
AWS에서 RDS PostgreSQL을 만들고, 로컬 백엔드 프로젝트에서 Prisma를 통해 연결하는 과정을 정리해보려고 한다.
프로젝트를 로컬 DB에서만 개발하다가 실제 배포 환경을 준비하려면 배포된 백엔드가 접근할 수 있는 데이터베이스가 필요하다.
나는 AWS RDS를 사용해서 PostgreSQL 데이터베이스를 만들고, 백엔드의 DATABASE_URL을 RDS로 연결했다.
환경을 완성하는 글이라기보다는, 학습과 초기 배포를 위해 RDS PostgreSQL을 직접 만들어보고 연결해본 과정에 가깝다.
1. AWS 리전 선택
먼저 AWS 콘솔에서 리전을 서울로 선택했다.
Asia Pacific (Seoul)
ap-northeast-2
리전은 데이터베이스가 실제로 생성되는 위치다.
백엔드 서버도 나중에 서울 리전에 배포할 예정이라면, RDS도 같은 서울 리전에 두는 것이 자연스럽다.
서버와 DB가 같은 리전에 있으면 네트워크 지연도 줄일 수 있고, 관리하기도 편하다.
2. RDS 서비스로 이동하기
AWS 콘솔 상단 검색창에 RDS를 검색한다.
검색 결과에서 다음 서비스를 선택했다.
Aurora and RDS
RDS는 AWS에서 제공하는 관리형 관계형 데이터베이스 서비스다.
직접 EC2에 PostgreSQL을 설치해서 운영할 수도 있지만, RDS를 사용하면 데이터베이스 설치, 백업, 모니터링, 유지 관리 같은 부분을 AWS가 어느 정도 관리해준다.
3. 데이터베이스 생성 방식 선택
RDS 화면에서 데이터베이스 생성을 선택하면 크게 두 가지 방식이 보인다.
빠른 구성으로 생성
전체 구성으로 생성
빠른 구성은 사전 설정된 옵션으로 빠르게 데이터베이스를 만들 수 있는 방식이다.
하지만 세부 옵션을 직접 선택하기 어렵다.
나는 학습하면서 각 설정을 이해하고 싶었기 때문에 전체 구성으로 생성을 선택했다.
데이터베이스 생성 방식 선택: 전체 구성
4. Aurora가 아니라 일반 RDS PostgreSQL을 선택한 이유
빠른 구성으로 만들면 Aurora PostgreSQL 클러스터가 생성될 수 있다.
Aurora PostgreSQL은 Amazon Aurora 안에 있는 PostgreSQL 호환 엔진이다.
성능과 확장성 면에서 장점이 있지만, 처음 학습하면서 사용하는 입장에서는 일반 RDS PostgreSQL이 더 단순하고 비용 예측도 쉬워 보였다.
그래서 나는 초기 학습과 배포 테스트 목적에 맞게 일반 RDS PostgreSQL을 선택했다.
엔진 옵션: PostgreSQL
5. 기본 설정
데이터베이스 생성 화면에서 내가 선택한 주요 설정은 다음과 같다.
엔진 옵션: PostgreSQL
데이터베이스 생성 방식: 전체 구성
템플릿: 프리 티어
가용성 및 내구성: 단일 AZ DB 인스턴스 배포
엔진 버전: 기본값
프리 티어 템플릿을 선택한 이유는 학습과 테스트 목적이었기 때문이다.
가용성 및 내구성은 단일 AZ DB 인스턴스 배포를 선택했다.
단일 AZ DB 인스턴스 배포
이 옵션은 하나의 가용 영역에 DB 인스턴스 1개를 두는 방식이다.
운영 안정성만 보면 Multi-AZ가 더 좋지만, 비용이 늘어날 수 있다.
이번에는 초기 배포와 학습 목적이었기 때문에 단일 AZ를 선택했다.
6. DB 인스턴스 정보 설정
다음으로 DB 인스턴스 정보를 설정했다.
DB 인스턴스 식별자: 프로젝트명-db
마스터 사용자 이름: postgres
자격 증명 관리: 자체 관리
마스터 암호: 직접 설정
데이터베이스 인증 옵션: 암호 인증
DB 인스턴스 식별자는 나중에 RDS 목록에서 구분하기 쉽도록 프로젝트명을 포함해서 작성했다.
예를 들어 다음과 같은 식이다.
highpass-db
마스터 사용자 이름은 postgres로 두었다.
마스터 사용자 이름: postgres
비밀번호는 직접 설정했다.
이 비밀번호는 나중에 DATABASE_URL에 들어가기 때문에 반드시 안전하게 관리해야 한다.
블로그나 GitHub에 절대 공개하면 안 된다.
7. 인스턴스 구성
인스턴스 구성은 기본값을 사용했다.
인스턴스 클래스: db.t4g.micro
프리 티어 또는 저비용 테스트 용도로 적당한 기본 인스턴스를 선택했다.
운영 트래픽이 많아지면 나중에 인스턴스 크기를 조정해야 할 수 있다.
하지만 초기 배포와 연결 테스트 단계에서는 작은 인스턴스로도 충분하다고 판단했다.
8. 스토리지 설정
스토리지도 기본값에 가깝게 설정했다.
스토리지 유형: 범용 SSD(gp2)
할당된 스토리지: 20GiB
스토리지 자동 조정: 끔
처음에는 데이터가 많지 않기 때문에 20GiB로 시작했다.
스토리지 자동 조정은 끄고 시작했다.
학습 단계에서는 비용이 예상치 못하게 늘어나는 것을 피하기 위해 자동 증가 옵션을 신중하게 보는 것이 좋다고 생각했다.
9. 연결 설정
연결 설정은 RDS를 로컬 컴퓨터에서 접속할 수 있게 만드는 데 중요하다.
내가 선택한 값은 다음과 같다.
컴퓨팅 리소스: EC2 컴퓨팅 리소스에 연결 안 함
VPC: 기본값
DB 서브넷 그룹: 기본값
퍼블릭 액세스 가능: 예
VPC 보안 그룹: 새로 생성
보안 그룹 이름: 프로젝트명-db-sg
가용 영역: 기본 설정 없음
데이터베이스 포트: 5432
여기서 가장 중요한 부분은 퍼블릭 액세스 가능이다.
퍼블릭 액세스 가능: 예
나는 로컬 컴퓨터에서 DBeaver나 Prisma로 직접 접속하며 테스트해야 했기 때문에 예로 설정했다.
다만 이 설정은 운영 환경에서는 신중해야 한다.
퍼블릭 액세스를 허용하면 인터넷에서 접근 가능한 위치에 DB가 놓일 수 있기 때문이다.
그래서 반드시 보안 그룹에서 접속 가능한 IP를 제한해야 한다.
운영 환경에서는 가능하면 DB를 private subnet에 두고, 백엔드 서버에서만 접근할 수 있게 구성하는 편이 더 안전하다.
이번 설정은 학습과 초기 연결 테스트를 위한 선택이었다.
10. 보안 그룹 생성
VPC 보안 그룹은 새로 생성했다.
VPC 보안 그룹: 새로 생성
보안 그룹 이름: 프로젝트명-db-sg
보안 그룹은 RDS의 네트워크 접근을 제어하는 방화벽 같은 역할을 한다.
쉽게 비유하면 다음과 같다.
RDS = 집
보안 그룹 = 현관문
5432 포트 = PostgreSQL 전용 문
내 IP 허용 = 내 컴퓨터만 들어갈 수 있게 허락
RDS를 만들었다고 해서 바로 내 컴퓨터에서 접속할 수 있는 것은 아니다.
보안 그룹에서 PostgreSQL 포트인 5432를 열어줘야 한다.
11. 추가 구성
추가 구성에서는 초기 데이터베이스 이름을 설정했다.
초기 데이터베이스 이름: 프로젝트명
이 값을 넣어두면 나중에 DATABASE_URL을 만들 때 깔끔하다.
예를 들어 초기 데이터베이스 이름을 highpass로 만들었다면, DATABASE_URL의 마지막 부분이 다음처럼 된다.
...:5432/highpass
만약 초기 데이터베이스 이름을 지정하지 않으면, 나중에 직접 DB를 만들거나 연결 경로를 다시 확인해야 할 수 있다.
그 외 설정은 대부분 기본값으로 두었다.
자동 백업 활성화
백업 보존 기간: 7일
마이너 버전 자동 업그레이드 사용
학습 단계라면 기본 설정으로 시작하되, 실제 운영에서는 백업, 유지 관리 시간, 암호화, 모니터링 옵션을 더 신중하게 확인해야 한다.
12. 데이터베이스 생성
설정을 모두 확인한 뒤 데이터베이스 생성을 클릭했다.
생성 직후에는 상태가 바로 사용 가능으로 바뀌지 않는다.
RDS 목록 화면에서 생성한 DB를 선택하고 상태를 확인한다.
상태: 생성 중
잠시 기다리면 상태가 다음처럼 바뀐다.
상태: 사용 가능
상태가 사용 가능이 되어야 실제로 접속할 수 있다.
13. 엔드포인트 확인
DB가 사용 가능 상태가 되면, 생성한 DB를 선택한 뒤 연결 및 보안 탭으로 이동한다.
여기서 다음 정보를 확인할 수 있다.
엔드포인트
포트
VPC
보안 그룹
엔드포인트는 RDS에 접속할 때 사용하는 주소다.
예시는 다음과 같은 형태다.
프로젝트명-db.xxxxxxxxxxxx.ap-northeast-2.rds.amazonaws.com
이 엔드포인트와 포트 5432를 사용해서 백엔드에서 RDS에 접속한다.
14. 보안 그룹 인바운드 규칙 수정
RDS를 만들었더라도 보안 그룹에서 내 IP를 허용하지 않으면 접속할 수 없다.
RDS의 연결 및 보안 탭에서 보안 그룹을 클릭하면 EC2의 보안 그룹 화면으로 이동한다.
생성한 보안 그룹을 선택한 뒤, 인바운드 규칙을 편집한다.
인바운드 규칙 편집
↓
규칙 추가
나는 다음과 같이 설정했다.
유형: PostgreSQL
프로토콜: TCP
포트 범위: 5432
소스: 내 IP
그리고 규칙 저장을 클릭했다.
이 설정은 내 컴퓨터의 현재 IP에서만 RDS PostgreSQL 포트로 접근할 수 있게 허용하는 것이다.
여기서 0.0.0.0/0처럼 전체 공개로 열면 위험하다.
학습 중이라도 DB 포트는 필요한 IP만 허용하는 것이 좋다.
15. DATABASE_URL 만들기
이제 백엔드 프로젝트의 .env 파일에서 DATABASE_URL을 RDS 주소로 변경한다.
Prisma에서 PostgreSQL을 사용할 때 DATABASE_URL은 보통 다음 형태다.
DATABASE_URL="postgresql://<사용자명>:<비밀번호>@<RDS엔드포인트>:5432/<초기DB이름>?schema=public"
예를 들어 구조만 보면 다음과 같다.
DATABASE_URL="postgresql://postgres:<password>@<endpoint>:5432/<database>?schema=public"
여기서 각 부분의 의미는 다음과 같다.
postgresql://
→ PostgreSQL에 접속한다는 의미
postgres
→ 마스터 사용자 이름
<password>
→ RDS 생성 시 직접 설정한 비밀번호
<endpoint>
→ RDS 연결 및 보안 탭에서 확인한 엔드포인트
5432
→ PostgreSQL 기본 포트
<database>
→ RDS 생성 시 입력한 초기 데이터베이스 이름
?schema=public
→ Prisma에서 사용할 PostgreSQL schema
주의할 점은 실제 비밀번호와 엔드포인트를 블로그나 GitHub에 올리면 안 된다는 것이다.
또한 비밀번호에 특수문자가 들어가면 URL에서 문제가 될 수 있다.
그런 경우 비밀번호를 URL 인코딩해서 넣어야 할 수 있다.
16. Prisma migration 적용하기
.env의 DATABASE_URL을 RDS로 변경한 뒤, 백엔드 프로젝트 폴더에서 migration을 적용했다.
npx prisma migrate deploy
이 명령어는 Prisma가 .env의 DATABASE_URL을 읽고, 해당 데이터베이스에 migration을 적용하는 명령어다.
즉 이번 경우에는 로컬 DB가 아니라 방금 만든 RDS PostgreSQL에 접속해서 테이블을 생성한다.
이 명령어로 두 가지를 확인할 수 있었다.
1. 내 컴퓨터에서 RDS에 접속 가능한가?
2. Prisma가 RDS PostgreSQL에 테이블을 만들 수 있는가?
만약 보안 그룹 설정이 잘못되었거나, DATABASE_URL이 틀렸거나, 비밀번호가 틀렸다면 이 단계에서 에러가 난다.
그래서 migrate deploy는 RDS 연결 확인에도 도움이 됐다.
17. 로컬 백엔드에서 RDS 연결 테스트
migration이 성공했다면, 이제 백엔드 서버를 로컬에서 실행해본다.
npm run start:dev
또는 프로젝트에 맞는 실행 명령어를 사용한다.
백엔드가 실행된 뒤 회원가입, 로그인, 데이터 생성 API 등을 호출해본다.
이때 데이터가 로컬 PostgreSQL이 아니라 RDS PostgreSQL에 저장된다면 연결이 성공한 것이다.
DBeaver 같은 DB 클라이언트로 RDS에 접속해서 테이블과 데이터가 생성되었는지도 확인할 수 있다.
18. 자주 실수할 수 있는 부분
RDS를 처음 연결하면서 헷갈릴 수 있는 부분은 다음과 같다.
1. RDS 상태가 아직 사용 가능이 아닌데 접속하려는 경우
2. 보안 그룹 인바운드 규칙에서 5432 포트를 열지 않은 경우
3. 소스를 내 IP로 설정하지 않은 경우
4. DATABASE_URL의 엔드포인트나 비밀번호가 틀린 경우
5. DATABASE_URL 마지막의 DB 이름을 잘못 적은 경우
6. 비밀번호 특수문자를 URL 인코딩하지 않은 경우
7. 로컬 .env가 실제로 백엔드 실행 시 로드되지 않는 경우
특히 가장 많이 헷갈렸던 부분은 보안 그룹이었다.
RDS를 만들었다고 끝이 아니라, 보안 그룹에서 내 컴퓨터의 IP가 PostgreSQL 포트로 접근할 수 있도록 허용해야 한다.
19. 운영 환경에서는 어떻게 해야 할까?
이번 글에서는 로컬에서 RDS에 접속하기 위해 퍼블릭 액세스 가능을 예로 설정했다.
하지만 실제 운영 환경에서는 DB를 퍼블릭으로 열어두는 것을 신중하게 봐야 한다.
운영 환경에서는 보통 다음과 같은 방향이 더 안전하다.
RDS는 private subnet에 둔다.
백엔드 서버만 RDS에 접근할 수 있게 한다.
보안 그룹에서 백엔드 서버의 보안 그룹만 허용한다.
DB 포트를 전체 공개하지 않는다.
환경변수와 비밀번호는 GitHub에 올리지 않는다.
이번 설정은 학습과 초기 배포 테스트 목적이었기 때문에 로컬 접속이 가능하도록 구성했다.
나중에 백엔드를 ECS나 EC2에 배포한다면, RDS 보안 그룹에서 내 IP가 아니라 백엔드 서버의 보안 그룹을 허용하는 방식으로 바꾸는 것이 더 안전하다.
정리
AWS에서 RDS PostgreSQL을 만들고, 로컬 백엔드 프로젝트에서 Prisma로 연결하는 과정.
전체 흐름은 다음과 같다.
1. AWS 리전을 서울로 선택
2. RDS에서 PostgreSQL 데이터베이스 생성
3. 프리 티어, 단일 AZ, db.t4g.micro 설정
4. 초기 데이터베이스 이름 설정
5. 퍼블릭 액세스 허용
6. 보안 그룹에서 PostgreSQL 5432 포트와 내 IP 허용
7. RDS 엔드포인트 확인
8. 백엔드 .env의 DATABASE_URL 수정
9. npx prisma migrate deploy 실행
10. 로컬 백엔드에서 RDS 연결 테스트
이제 로컬 개발 환경에서만 사용하던 DB를 벗어나, 배포 환경에서 사용할 수 있는 데이터베이스를 준비한 셈이다.