애플리케이션용 PostgreSQL 데이터베이스 생성

AWSBeginner
지금 연습하기

소개

주문 애플리케이션이 고객 주문을 저장하려면 관계형 데이터베이스가 필요합니다. 이 실습에서는 Amazon RDS로 비공개 PostgreSQL 데이터베이스를 만들고 표준 SQL 클라이언트로 연결한 다음 애플리케이션에 새 엔드포인트를 설정합니다.

앞선 VPC 및 EC2 과정에서 배운 VPC 서브넷, 보안 그룹, 애플리케이션 연결을 이해하고 있어야 합니다. 환경에는 네트워크, 애플리케이션 및 설정된 AWS CLI가 제공됩니다. 개인 AWS 계정은 필요하지 않습니다. 마지막에 데이터베이스를 삭제합니다.

자격증 시험과의 연관성

이 실습은 다음 시험 주제를 위한 기초 실습을 제공합니다.

애플리케이션 데이터베이스 생성

이 단계에서는 준비된 데이터베이스 네트워크에 비공개 PostgreSQL 인스턴스를 만듭니다.

Amazon RDS는 관계형 데이터베이스 인스턴스를 관리합니다. PostgreSQL은 테이블을 저장하고 SQL을 실행하는 데이터베이스 엔진입니다. AWS CLI는 RDS 리소스를 관리하고 SQL 클라이언트는 엔진에 연결해 데이터를 처리합니다. RDS 인스턴스를 만드는 작업과 테이블을 조회하는 작업은 서로 다릅니다.

AWS Management Console은 서비스를 살펴보고 리소스를 확인할 때 유용합니다. CLI는 정확한 조회, 반복 가능한 작업 및 자동화에 유용하지만 구문을 익히려면 연습이 필요합니다. 이 과정에서는 준비된 Terminal과 AWS View를 사용합니다. AWS View는 실습 리소스와 애플리케이션 결과를 보여 주며 AWS Management Console과 별개입니다.

작업 디렉터리로 이동하고 제공된 연결 설정을 불러옵니다.

cd /home/labex/project
source database.env

DB_SECURITY_GROUP_ID는 데이터베이스의 준비된 네트워크 접근 규칙을 식별합니다. PGSERVICEFILE과 PGPASSFILE은 PostgreSQL 클라이언트에 일반 연결 파일과 비밀번호 파일의 위치를 알려 줍니다. 비밀번호 파일을 비공개로 유지하세요. 내용을 표시할 필요는 없습니다.

준비된 DB 서브넷 그룹을 확인합니다.

aws rds \
  describe-db-subnet-groups \
  --db-subnet-group-name orders-subnets \
  --query 'DBSubnetGroups[].{Name:DBSubnetGroupName,VPC:VpcId,Subnets:Subnets[].SubnetIdentifier}'

DB 서브넷 그룹은 RDS를 배치할 수 있는 VPC 서브넷을 지정합니다. 이 그룹에는 두 가용 영역의 비공개 데이터베이스 서브넷이 있습니다. 그룹에 서브넷이 두 개 있다고 해서 Multi-AZ 배포가 활성화되는 것은 아닙니다.

인스턴스를 만듭니다.

aws rds \
  create-db-instance \
  --db-instance-identifier orders-db \
  --db-instance-class db.t3.micro \
  --engine postgres \
  --engine-version 16.15 \
  --allocated-storage 20 \
  --master-username orders_admin \
  --master-user-password "$(cat db-password.txt)" \
  --db-name orders \
  --db-subnet-group-name orders-subnets \
  --vpc-security-group-ids "$DB_SECURITY_GROUP_ID" \
  --no-publicly-accessible \
  --backup-retention-period 0 \
  --query 'DBInstance.{Identifier:DBInstanceIdentifier,Status:DBInstanceStatus,Engine:Engine}'

인스턴스 식별자 orders-db는 RDS 리소스의 이름이고 데이터베이스 이름 orders는 그 안의 PostgreSQL 데이터베이스 이름입니다. db.t3.micro는 인스턴스 클래스를 선택하고 20은 요청한 스토리지 크기(GiB)입니다. 비공개 접근을 사용하면 애플리케이션 연결이 준비된 네트워크 안에서 이루어집니다. 짧은 실습이므로 자동 백업 보존을 비활성화하며 이후 실습에서 수동 스냅샷을 배웁니다.

$(cat db-password.txt)는 비밀번호를 출력하지 않고 제공된 데이터베이스 비밀번호를 전달합니다. 비밀번호를 메모나 스크린샷에 붙여 넣지 마세요.

사용 가능 상태를 기다린 다음 연결 엔드포인트를 확인합니다.

aws rds \
  wait db-instance-available \
  --db-instance-identifier orders-db
aws rds \
  describe-db-instances \
  --db-instance-identifier orders-db \
  --query 'DBInstances[0].{Identifier:DBInstanceIdentifier,Database:DBName,Status:DBInstanceStatus,Endpoint:Endpoint}'

데이터베이스 orders, 상태 available, PostgreSQL 포트 5432가 표시되어야 합니다. 엔드포인트는 클라이언트가 이 데이터베이스 인스턴스를 선택할 때 사용하는 주소입니다. 이제 AWS View에 orders-db가 기본 데이터베이스로 표시됩니다. 주문 테이블은 아직 없습니다.

SQL 클라이언트 및 애플리케이션 연결

이 단계에서는 데이터베이스 엔진을 테스트하고 애플리케이션에 엔드포인트를 설정합니다.

psql은 PostgreSQL의 표준 명령줄 클라이언트입니다. 준비된 orders-db 서비스에는 방금 만든 인스턴스의 연결 정보가 들어 있습니다. 서비스 이름은 편리한 클라이언트 설정 항목이며 AWS 리소스가 아닙니다.

엔진을 조회합니다.

프라이빗 PostgreSQL 연결에는 접근 가능한 엔드포인트와 허용된 포트가 필요함

개념도: 프라이빗 PostgreSQL 연결에는 접근 가능한 엔드포인트와 허용된 포트가 필요함.

psql \
  "service=orders-db" \
  --command 'SELECT current_database(), current_user;'

데이터베이스 orders와 사용자 orders_admin이 표시되어야 합니다. 이 결과는 RDS 리소스 메타데이터가 아니라 데이터베이스 연결에서 나옵니다. RDS는 데이터베이스 호스트를 관리하며 애플리케이션은 호스트에 SSH로 접근하는 대신 데이터베이스 프로토콜로 연결합니다.

RDS에서 엔드포인트를 가져옵니다. --query는 한 필드를 선택하고 --output text는 일반 값을 출력하며 셸의 $(...)는 이를 DB_ENDPOINT에 저장합니다.

DB_ENDPOINT=$(aws rds \
  describe-db-instances \
  --db-instance-identifier orders-db \
  --query 'DBInstances[0].Endpoint.Address' \
  --output text)

제공된 애플리케이션 설정을 확인합니다.

cat app-config.json

read_host는 조회할 데이터베이스를 선택하고 write_host는 변경할 데이터베이스를 선택합니다. 지금은 둘 다 기본 데이터베이스를 사용해야 합니다. password_file은 이 JSON 문서에 비밀번호를 넣는 대신 비공개 파일을 참조합니다.

JSON 편집 도구인 jq로 두 호스트 필드를 설정합니다. 새 파일을 작성한 뒤 편집이 성공하면 설정 파일을 교체합니다.

jq \
  --arg host "$DB_ENDPOINT" \
  '.read_host = $host | .write_host = $host' \
  app-config.json > app-config.new
mv app-config.new app-config.json

애플리케이션 연결을 테스트합니다.

curl \
  --silent \
  --show-error \
  --fail \
  http://127.0.0.1:8080/application/connection

database는 orders, user는 orders_admin, read_only는 false여야 합니다. 기본 데이터베이스는 쓰기를 허용하지만 이 실습에서는 연결만 설정합니다. 주문 테이블이 없으므로 AWS View의 주문 목록은 아직 사용할 수 없습니다. 다음 실습에서 테이블을 만듭니다. AWS View의 기본 PostgreSQL 연결

예시는 애플리케이션이 기본 orders 데이터베이스와 RDS 엔드포인트에 연결된 모습을 보여 줍니다. 주문 테이블은 아직 없습니다. 리소스 식별자는 다를 수 있습니다.

AWS Console: RDS

공식 Console 예시: Connectivity & security의 Endpoint와 Port는 CLI 응답의 Endpoint.Address와 Endpoint.Port에 해당합니다. 공식 예시는 MySQL의 3306을 표시하지만 이 실습은 PostgreSQL의 5432와 직접 실행한 명령이 반환한 엔드포인트를 사용합니다. 예시 호스트 이름이나 포트를 복사하지 마세요. AWS 로그인 없이 Terminal과 AWS View에서 계속하세요.

Source: AWS RDS guide.

데이터베이스 인스턴스 삭제

이 단계에서는 준비된 애플리케이션과 네트워크를 유지하면서 임시 데이터베이스를 삭제합니다.

최종 스냅샷을 남기지 않고 인스턴스를 삭제합니다.

aws rds \
  delete-db-instance \
  --db-instance-identifier orders-db \
  --skip-final-snapshot \
  --query 'DBInstance.DBInstanceIdentifier'

--skip-final-snapshot은 복구용 복사본을 저장하지 않고 실습 데이터베이스를 삭제합니다. 중요한 데이터라면 인스턴스를 삭제하기 전에 백업을 보존할 방법을 결정하세요.

삭제를 기다리고 리소스 목록을 확인합니다.

aws rds \
  wait db-instance-deleted \
  --db-instance-identifier orders-db
aws rds \
  describe-db-instances \
  --query 'DBInstances[].DBInstanceIdentifier'

[]가 표시되어야 합니다. AWS View에는 데이터베이스가 없어야 합니다. 애플리케이션의 이전 엔드포인트 뒤에는 더 이상 데이터베이스가 없으므로 삭제 후 연결 실패는 예상된 결과입니다. 제공된 서브넷 그룹, 보안 그룹 및 애플리케이션 파일은 그대로 두세요.

요약

비공개 RDS PostgreSQL 인스턴스를 만들고 리소스 식별자와 데이터베이스 이름의 차이를 이해한 뒤 엔드포인트를 확인했습니다. psql로 엔진을 조회하고 애플리케이션을 같은 기본 데이터베이스에 연결했습니다. 마지막으로 준비된 네트워크를 유지하면서 인스턴스를 삭제했습니다.

다음 실습에서는 주문 테이블을 만들고 SQL로 고객 주문을 저장하고 조회합니다.