본문 바로가기
프로젝트 기록/Architecture, Infra, CICD

[Project / AWS] EC2와 RDS로 스프링 API 서버 배포하기

by clean01 2024. 5. 4.


해당 포스트는 API Server를 AWS의 EC2, RDS를 이용해서 배포한 과정을 담고 있습니다.

AWS 프리티어 계정만 있다면 EC2, RDS를 하나씩 제공 받을 수 있으므로 간단한 프로젝트는 무료 배포가 가능합니다.
프리티어 계정이 있다는 전제하에 포스트를 작성했습니다.
계정이 없는 분들은 AWS 계정을 만들어 주시면 됩니다!

VPC 만들기

우선 VPC를 하나 만들어 주겠습니다.
VPC가 뭔지 잘 모르시겠다면 이 글에 설명이 아주 잘 되어있으니 읽어보시기를 추천 드립니다.

VPC 대시보드로 들어가서 우측 상단에 있는 VPC 생성을 클릭해주세요.

 

이렇게 설정 해준 뒤, "VPC 생성" 버튼을 눌러줍니다.

보안 그룹 생성

이제 보안 그룹을 만들어 주겠습니다.
총 2개의 보안 그룹을 만들 건데, 하나는 EC2에 적용할 보안 그룹, 다른 하나는 RDS에 적용할 보안 그룹입니다.

EC2 보안 그룹 만들기

위에서 EC2는 어디서든 접근할 수 있게 하고, RDS는 EC2를 통해서만 접근할 할 수 있게 보안 그룹을 설정해주기로 하였습니다.

그 계획대로 만들어 보겠습니다!


이름은 원하는 대로 지어 주시고, VPC는 방금 만들었던 그 VPC로 지정해줍니다.

인바운드 규칙을 위와 같이 설정해주고 "보안 그룹 생성"을 눌러줍니다.

RDS 보안 그룹 만들기

이제 RDS를 위한 보안 그룹을 만들어주겠습니다.

 


인바운드 규칙은 위와 같이 설정해줍니다.
"소스" 부분에는 방금 만들었던 EC2를 위한 보안 그룹을 넣어주면 됩니다.
위와 같이 설정하면, "해당 보안 그룹에서 보낸 트래픽만 3306 포트를 통해 받겠다"라는 의미입니다.

이렇게 설정해준 뒤 보안 그룹을 생성해줍니다!

EC2 인스턴스 만들기


아마존 리눅스보다는 우분투의 명령어가 익숙하기 때문에 우분투로 설정해주었습니다.


이 "네트워크 설정" 부분이 중요한데

  • VPC: 아까 만들었던 VPC로 설정
  • 방화벽: 기존 보안 그룹 선택
  • 일반 보안 그룹: 아까 만들었던 ec2를 위한 보안 그룹 선택

이렇게 설정해줍니다.

앗 VPC랑 보안 그룹의 이름이 바뀐 것 같다고요?
맞습니다. 아까 만든 VPC의 이름은 test-vpc였는데, 현재 mewsinsa-vpc로 되어 있죠...ㅎㅎ
그것은 제가 이미 mewsinsa-vpc와 그에 포함되는 보안 그룹을 만든 뒤, 블로그 포스팅을 위해 보안 그룹 만드는 과정을 캡처하기 위해 test-vpc라는 이름으로 새로운 보안 그룹을 만들었었기 때문에 위에는 test-vpc로 되어있습니다.
이제부터는 mewsinsa-vpc로 진행하도록 하겠습니다. (간단하게 testmewsinsa로 치환했다고 생각하시면 됩니다!)

그 외에 부분은 건드리지 않고 기본 값으로 하여 생성해줍니다.

RDS 인스턴스 만들기


RDS 대시보드로 가서 "데이터베이스 생성"을 눌러줍니다.


저는 프로젝트에서 MariaDB를 사용했었어서 MariaDB를 선택해주었습니다.
이는 프로젝트에 사용한 DB에 따라 적절하게 선택해주시면 됩니다.

 

 


RDS를 만들 때에도 "연결"을 설정해주는 부분이 중요합니다.
아까 전에 만들어 주었던 그 VPC를 선택해주세요.

보안 그룹도 아까 rds를 위해 만들었던 그 보안그룹을 선택해줍니다.

이렇게 설정해준 뒤, RDS 인스턴스를 생성해줍니다.

private 레포에 프로젝트 코드 올리기

이제 EC2에 프로젝트 파일을 다운받아 빌드/실행해서 배포해보겠습니다.
지금 제 프로젝트 코드는 public repository에 올라가있는데,
이런 public 레포에 올라가 있는 프로젝트를 배포할 때 문제점이 application.properties 같은 설정 파일을 어떻게 처리할지입니다.

ec2로 코드를 옮길 때, 깃 레포에서 클론 받는 형식으로 옮길 것이므로 github에 배포에 필요한 모든 파일이 올라가 있으면 좋은데, 일부 설정 파일에는 DB url, API 키, 해싱에 쓰이는 고정 상수 등등이 들어있어서, github에 올리면 내용들이 존재합니다.

이런 민감한 정보들은 Jenkins를 이용해서 github에서는 노출이 안되지만 빌드시에는 올바른 값이 들어가도록 설정할 수 있다고 들었는데, 저는 아직 Jenkins를 쓸 줄 모르기 때문에... 이는 나중에 Jenkins로 CI/CD 파이프라인을 구축하면서 시도해봐야할 것 같습니다.

그렇다면 현재 쓸 수 있는 방법 중에는 public repo에는 그런 민감한 정보를 담고 있는 파일들을 빼고 올려놓은 후, public repo에 있는 내용을 클론 받고 일부 설정 파일만 vim 에디터 이용해서 추가하는 등의 방법을 쓸 수 있겠습니다.
하지만 이는 좀 번거롭습니다.. GUI나 IDE가 없는 환경에서 코드를 고쳐야하는 것이니까요.
이 뿐만 아니라, application.yml의 DB url 부분도 모두 수정해주어야 합니다.

그래서 저는 그냥 가장 간단한 방법을 쓰기로 했는데, "퍼블릭 레포에 있는 내용 + 민감한 정보"를 새로운 private 레포지토리를 만들어 따로 올리는 것입니다.
private 레포이므로 민감한 정보가 올라가도 되고, ec2에 내려받은 뒤에 수정할 부분이 없어서 간편합니다.

우선 private 레포지토리를 새로 하나 만들어주고, 기존 레포지토리를 clone 해주고 민감한 내용이 포함된 설정파일들을 추가해줬습니다.
그리고 application.yml에서 DB url과 같은 변경 사항들도 모두 변경해주었습니다.

apllication.yml

spring:
  datasource:
    url: jdbc:mariadb://[RDS 엔드포인트]?useUnicode=true&characterEncoding=UTF8
    driver-class-name: org.mariadb.jdbc.Driver
    username: [RDS 생성시 정했던 관리자 이름]
    password: [RDS 생성시 정했던 패스워드]

엔드 포인트는 RDS 정보에서 보실 수 있습니다.

rm -rf .git

명령어를 통해 기존 .git 파일을 삭제해주고,

git remote add origin [private 리포지토리 주소]

명령어로 새로운 private 리포지토리와 연결해줍니다.
그리고 다시 add, commit, push를 통해 private 레포에 코드를 올려주면 됩니다.

RDS에 스키마와 테스트 데이터 넣기

이제 배포까지 거의 다 왔습니다.
그런데 그 전에 RDS에 스키마를 입력하고 테스트 데이터 몇 개를 넣어보겠습니다.

일단 Mysql Workbench에서 접근할 수 있도록 보안 그룹을 잠깐만 수정해주어야 합니다.

EC2에서 빌드/실행하기

EC2에 접속하기

chmod 400 [키이름]

위 명령어로 권한을 부여해주고

ssh -i [키이름] ubuntu@[DNS 주소 or 퍼블릭 IP]

이렇게 접속해줍니다.

저는 탄력적 IP(고정 퍼블릭 아이피)로 접근했습니다.

private 리포지토리 클론 받기

이 글을 참고하여 리포지토리를 ssh로 clone하였습니다.

빌드하고 실행

아래 명령어로 자바 17 버전을 다운 받아주고

sudo apt install openjdk-17-jdk

프로젝트 최상위 디렉토리로 들어가서 이 명령어로 빌드를 해주었습니다.

./gradlew build
cd build/libs
ls

위의 명령어를 입력해주면 빌드된 jar 파일이 보입니다.

nohup java -jar mewsinsa-0.0.1-SNAPSHOT.jar &

이렇게 실행하면 백그라운드에서 실행됩니다

잘 배포 됐나? Request 보내보기

우선 인스턴스 접속을 끊고, 포스트맨으로 상품 전시 정보를 보는 요청을 보내보겠습니다.


응답이 잘 나오는 것을 보니, 인스턴스의 백그라운드에서 잘 실행되고 있는 것 같습니다.

Reference