스프링 웹 애플리케이션을 aws 인스턴스에 배포하는 방법은 지난 포스팅(329번 포스팅)에 작성했었다. 또, 자동 배포 스크립트를 생성하여 배포하는 방법도 334번 포스팅에 작성했다.
https://kth990303.tistory.com/329
https://kth990303.tistory.com/334
하지만 위 포스팅들은 하나의 인스턴스로 이루어진 VPC에서 작동시킨다는 가정 하에 작성됐다.
그렇지만 대부분은 웹 인스턴스와 db 인스턴스(거의 높은 확률로 외부에서 접속 못하게private ipv4 주소로 만들음)를 따로 분리하기 때문에, 위 포스팅 방법대로 할 경우 db는 aws꺼를 사용하지 않고 웹 인스턴스에만 접속하게 된다.
따라서 이번 포스팅에서는 db 인스턴스에까지 접속해서 aws db와 함께 연동하는 방법을 기록하려 한다.
참고로 이 포스팅에서 웹용 인스턴스는 public, db용 인스턴스는 private이라는 가정 하에 작성한다.
db용 인스턴스는 웹용 인스턴스를 통해서만 접근 가능하다.
1. db 인스턴스 키페어를 웹 인스턴스에 보내준다.
db 인스턴스는 웹 인스턴스에서만 접근할 수 있는 private 성질을 지닌다. 따라서 아래 명령어로 db 인스턴스 키페어를 웹 인스턴스에 보내주도록 하자.
scp -i {로컬 키페어} {db 인스턴스 키페어} ubuntu@{ec2-웹 인스턴스 ip}:/home/ubuntu
웹 인스턴스는 public인데 키페어를 보내는 것은 위험하지 않을까 하는 의문이 들 수도 있다. 당연히 더 좋은 방법이 있을 것 같지만, 나의 부족함으로 인해 현재는 이 방법을 진행했으며, 그에 대한 생각은 아래와 같다.
- 웹 인스턴스도 키페어가 있어야 접근할 수 있다. 웹 인스턴스에 접근할 수 있다는 것 자체가 웹용 키페어가 이미 탈취된 상태라는 것.
- 키페어의 접근권한을 사용자나 그룹 외의 외부에게 chmod에서 0으로 설정해두는 안전장치가 존재하긴 함.
2. db 인스턴스에 접근
아래 명령어로 db 인스턴스에 접근하자.
ssh -i {db 인스턴스 키페어} ubuntu@{ec2-db ip}
3. db 인스턴스에 mysql 설치
우리는 mysql로 배포할 것이므로 mysql을 인스턴스에 설치해주어야 한다.
그 전에 먼저 아래 명령어로 현재 설치되어있는 패키지들을 업데이트해주고 진행해주자.
sudo apt-get update
그 다음으로, mysql을 설치하고 User를 생성해준 후, 권한 설정을 해주어야 하는데 이 부분은 아래 글을 참고하자.
https://hiseon.me/linux/ubuntu/ubuntu-mysql-install/
4. db를 localhost외에 다른 곳에서도 접근할 수 있도록
db 인스턴에서 아래 명령어를 입력해주자.
vi /etc/mysql/mysql.conf.d/mysqld.cnf
이후 아래 화면처럼 bind-address = 127.0.0.1 이랑 mysqlx-bind-address = 127.0.0.1 을 주석처리해주자.
이 작업을 해주지 않으면 communications link failure 오류가 발생할 수 있다.
mysql 설정을 반영해주기 위해 서비스를 재시작해주자.
sudo service mysql restart
5. application.propeties (application.yml) 설정해둔 후, 환경변수 주입
로컬에서 사용할 datasource url과 배포할 datasource url이 다르므로 application.yml 설정을 변경해주어야 한다.
우아한테크코스의 백엔드 크루 오리랑 정이 정말 잘 알고 있는 부분이어서 크루들의 도움을 받아서 설정해주었다.
둘은 서로 다른 방법으로 환경변수 세팅 및 url을 설정해주었다. 나는 application.yml에 로컬에서의 test용, 배포에서의 prod용으로 나누어 작성하는 정의 방법을 사용하였다.
application.yml (22.06.08. 21시 19분 수정)
spring:
profiles.active: test
sql.init.mode: always
mvc.pathmatch.matching-strategy: ANT_PATH_MATCHER
---
spring:
config.activate.on-profile: prod
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${db_url}
username: ${db_username}
password: ${db_password}
security.jwt.token:
secret-key: ${secret-key}
expire-length: ${jwt-validity}
---
spring:
config.activate.on-profile: test
datasource:
url: jdbc:h2:~/test;MODE=MYSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
username: sa
security.jwt.token:
secret-key: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
expire-length: 36000000
config.activate.on-profile 에서 test는 로컬용, prod는 배포용이다. 그리고 dev에서는 h2 데이터베이스를 사용하도록 할 것이다.
디폴트값은 test로 주고, 배포할 때 prod로 바꿔주도록 명령어를 변경할 것이다.
nohup java -jar -Dspring.profiles.active=prod
-Dspring.datasource.url='jdbc:mysql://{ec2-db ip}:3306/{사용할 database}?serverTimezone=UTC&characterEncoding=UTF-8'
-Dspring.datasource.username='{db username}' -Dspring.datasource.password='{db password}'
-Dsecurity.jwt.token.secret-key='{토큰}' -Dsecurity.jwt.token.expire-length=36000000 {배포할 jar 파일} &
자동배포 셸 스크립트를 작성했다면 서버를 실행하는 부분을 위 명령어로 바꿔주면 된다. 띄어쓰기, 오타에 주의하면서 작성하자.
- datasource url 형식: jdbc:mysql://{ec2-db ip}:3306/{사용할 database}?serverTimezone=UTC&characterEncoding=UTF-8
- -Dspring.profiles.active=prod : 실제 배포용 application.yml 환경변수들을 이용하겠다고 설정해주는 부분
6. 명령어를 입력하여 실행하기
나는 자동배포 셸 스크립트를 짜놨기 때문에 이거를 실행시켰다. 셸 스크립트를 실행하지 않는다면 명령어를 5번에서 바꿔준대로 잘 입력해주도록 하자. (nohup java -jar ...)
웹 애플리케이션 실행 후, db 인스턴스에서 table들이 의도대로 뜨는지 확인해보자.
mysql db table이 EMPTY SET이 아닌 의도한대로 잘 뜬 것을 확인할 수 있다~
application.yml을 설정해주는 방법이 정말 힘들었다. 아무래도 처음 다뤄보는 내용들이다보니 삽질을 많이 했던 듯.
나중에 토이프로젝트할 때 유용할 것 같아 기록해두려 한다!
이 방법은 application.yml을 gitignore하지 않아도 되지만, 환경변수가 변경될 때 배포서버 실행 명령어를 수정해주어야 한다는 단점이 존재한다. 매번 수정해주지 않아도 되는 방법 (대신 application.yml은 gitignore) 역시 존재한다. (우아한테크코스의 백엔드 크루 갓-오리가 이 내용을 잘 정리해주었다.)
잘 학습해둬서 나중에 잘 써먹어봐야겠다.
'Infra > Aws' 카테고리의 다른 글
[AWS] Swap File을 이용해 EC2 메모리 부족 현상을 해결해보자 (2) | 2022.08.13 |
---|---|
[AWS] AWS Educate에서 더 이상 무료 프리티어 기능을 제공해주지 않는 것 같다 (0) | 2022.08.08 |
[AWS][Spring] Aws 우분투 인스턴스 웹 애플리케이션 자동 배포 스크립트 만들기 (0) | 2022.06.08 |
[AWS] 인텔리제이에서 AWS 인스턴스에 접속하기 (0) | 2022.06.03 |
[ERROR][AWS] Database may be already in use: null. Possible solutions: close all other connection(s); use the server mode [90020-200] 해결 (2) | 2022.06.03 |