이번에 AWS로 스프링 부트 서버를 배포해보면서 CI/CD 플랫폼인 Github Actions를 사용해 보았다.

 

CI/CD란?

- CI: 지속적 통합으로 빌드 -> 테스트 -> 통합의 과정을 자동화해주는 것

- CD: 지속적 배포로 운영 서버에 자동 배포하는 것

 

스프링 부트에는 톰캣이 내장되어 있어서 gradle로 빌드를 하면 패키징된 jar 파일이 생성되고 이 jar 파일을 실행하면 간단하게 서버를 띄울 수 있다.

 

전체적인 흐름을 보면 Github Actions를 통해 다음과 같은 워크플로우를 자동화하는 것이다.

 

"애플리케이션을 gradle로 빌드해서 jar 파일을 생성하고 jar 파일을 AWS 운영 서버에 전달을 해서 배포한다."

 

물론 깃액션이 모든 작업을 처리하는 것은 아니다.

 

먼저 AWS 환경을 구축해야 하는데 처음 배포를 하기 위해 AWS 관련 포스팅을 보면 설정이 조금씩 바뀌어서 헷갈리는 부분이 많다. 그래서  각각 작업에서 어떤 설정이 필요한지 이해하는 것이 좋다.

 

AWS 환경을 구축하기 위한 전체적인 순서는 다음과 같다.

 

1. IAM 사용자 생성

2. 서버를 배포하기 위한 클라우드 컴퓨팅 서비스 EC2 생성

3. 관계형 데이터베이스 서비스 RDS 생성

4. 온라인 스토리지 S3 (Jar 파일을 저장) 생성

5. 자동 배포 서비스 CodeDeploy 생성

 

 

1. IAM 사용자 생성

 

AWS에서 root 계정을 직접 사용하는 것은 보안상 권장하지 않아서 먼저 root 계정으로 로그인을 하고 IAM 사용자를 생성해서 필요한 작업을 한다. IAM 사용자를 생성할 때는 사용자 그룹에 필요한 권한을 추가해서 생성하고 해당 그룹에 사용자를 추가하는 식으로 생성한다.

 

사용자 그룹 생성 시 AdministratorAccess 권한을 주고 해당 그룹에 사용자를 추가했는데 AdministratorAccess는 거의 모든 권한을 가지기 때문에 실제로 사용하는 것은 위험할 것 같다. (사용자 권한에 대해서도 공부를..)

 

2. EC2 인스턴스 생성

 

EC2 메뉴에서 인스턴스 시작을 하면 생성을 할 수 있는데 하나씩 보도록 한다.

 

AMI(Amazon Machine Image)의 경우 서버 환경을 구성하는 것이다. AMI를 만들어두면 추후 다른 인스턴스에서 복제해서 사용할 수 있다. 인스턴스 유형은 CPU, 메모리 등을 정하는 건데 프리티어는 크게 선택할 것이 없다.

 

키페어(key-pair)인스턴스에 접속하기 위한 키(*.pem)를 생성하는 것으로 SSH로 인스턴스에 접속하기 위해 필요하다. 일단 자동 생성을 해둔다.

 

네트워크 설정을 보면 네트워크(vpc-0ad12dxxx), 서브넷, 보안 그룹이 보이는데 먼저 IP에 대해 이해를 해야 한다.

 

IP는 인터넷상에서 고유한 주소를 나타내는 공인 IP와 RFC1918에서 내부 네트워크로 지정된 대역인 사설 IP로 나뉜다.

공인 IP는 네이버, 구글과 같은 도메인의 IP를 나타내고 사설 IP는 공유기를 생각하면 이해하기 쉽다. 공유기에 연결된 노트북, 핸드폰의 와이파이 설정을 보면 사설 IP를 확인할 수 있는데 인터넷망에 접속할 때는 공유기의 NAT 기능을 통해 해당 공유기의 공인 IP로 변환이 된다.

(유튜브 널널한 개발자님의 공유기 관련 영상을 보는 것을 추천..!)

 

 

 

이제 다시 VPC와 서브넷을 알아보자.

 

VPC는 AWS에서 서비스를 개발, 제공하기 위한 가상 사설 네트워크망으로 사설 IP(Private Network)를 활용하여 네트워크 망을 구성하는 서비스를 말한다. VPC는 하나의 리전에 종속되며 서로 독립적(Private Network)이다.

그리고 VPC를 더 작은 범위의 네트워크로 나눈 것서브넷이라 하는데 서브넷은 AZ서비스에 속하며 서브넷 내 EC2, RDS와 같은 리소스들을 위치시킬 수 있다.

 

AWS 사이트에서 VPC를 검색해서 눌러보면 이미 생성되어 있는 VPC를 확인할 수 있는데 ID는 위에서 EC2 인스턴스를 생성할 때 본 것과 같고 IPv4 CIDR은 172.31.0.0/16으로 나와있다. (CIDR은 IP 주소 할당 방법으로 계산 방법은 따로 찾아본다.)

 

 

그리고 서브넷도 눌러보면 위의 VPC ID를 가지는 서브넷이 4개가 있고 IPv4 CIDR은 172.31.xx.x/20으로 되어 있다.

(같은 VPC를 가지는 4개의 서브넷이 있고 IP 또한 같은 범위의 사설 IP 대역에 속하는 것을 볼 수 있다.)

 

위에서 기본으로 등록이 되어 있는 VPC, 서브넷은 서울 리전의 VPC와 서울 리전을 이루고 있는 가용 영역(AZ)의 서브넷을 나타내는 것이다. (EC2 인스턴스를 생성할때 따로 설정하지 않으면 기본적으로 등록이 된다.)

 

(VPC에 대해 자세한 내용은 아래 잘 정리된 블로그를 추천)

 

[AWS] 가장쉽게 VPC 개념잡기

가장쉽게 VPC 알아보기

medium.com

 

Virtual Private Cloud(VPC) 쉽게 이해하기 #1

VPC(Virtual Private Cloud) Amazon Virtual Private Cloud(Amazon VPC)에서는 사용자가 정의한 가상 네트워크로 AWS 리소스를 시작할 수 있습니다. 이 가상 네트워크는 AWS의 확장 가능한 인프라를 사용한다는 이점

aws-hyoh.tistory.com

 

 

 

보안 그룹은 방화벽과 같은 역할을 하는데 EC2 인스턴스 생성 후에 따로 설정을 한다. 마지막으로 스토리지는 프리티어에서 30GB까지 무료로 제공하기 때문에 30GB로 설정하고 인스턴스를 생성한다.

 

EC2 인스턴스가 잘 생성된 것을 확인하고 네트워크 및 보안에서 보안 그룹, 탄력적 IP를 순서대로 설정한다.

 

 

보안 그룹을 누르면 아까 기본으로 생성된 보안 그룹이 보이는데 인바운드 규칙, 아웃바운드 규칙을 추가할 수 있다.

인바운드 규칙은 외부 -> EC2로 허용할 IP 대역을 설정하는 것이고 아웃바운드는 EC2 -> 외부로 반대를 나타낸다.

보안 그룹은 Stateful(상태를 저장)하기 때문에 한번 인바운드를 통과하는 트래픽은 아웃바운드 규칙 적용을 받지 않는다. (반대 경우도)

 

 

인바운드 규칙에 SSH 접속을 위해 내 IP만 허용해서 추가를 하고 Spring Boot 기본 포트 8080을 Anywhere(0.0.0.0/0)로 추가한다.

 

다음으로 탄력적 IP를 추가한다. 위에서 EC2 인스턴스를 생성할 때 네트워크 설정을 보면 퍼블릭 IP 할당이 활성화로 되어있어서 인스턴스를 다시 실행할 때마다 외부에서 접근 가능한 공인 IP가 새로 할당이 되는데 탄력적 IP는 고정 IP를 할당받는 것이다. (탄력적 IP를 생성하고 사용하지 않으면 요금이 나오니 조심)

 

탄력적 IP 주소 할당을 하고 연결만 하면 간단하게 된다. 다시 EC2의 인스턴스로 가보면 퍼블릭 IP가 고정 IP로 할당된 것을 확인할 수 있다.

 

이제 EC2 인스턴스를 생성해서 외부에서 EC2에 접속이 가능하도록 보안 그룹의 인바운드 규칙을 추가하고 탄력적 IP까지 추가했으니 로컬에서 SSH로 접속을 해본다.

 

 

EC2 인스턴스를 체크하고 연결을 누르고 SSH 접속 명령어를 복사하면 된다. (예시는 키페어가 있는 위치에서 명령어를 실행)

 

맥 OS 기준으로 호스트를 등록해서 간단하게 실행하는 방법도 있다.

먼저 키페어(*.pem)를 터미널 ~/.ssh 경로로 이동시킨다.

~/.ssh 경로에 config 파일을 생성하고 아래 내용을 추가한다

(HostName은 퍼블릭 IP 또는 퍼블릭 DNS를, User는 기본 이름인 ubuntu, IdentityFile은 키페어 위치를 입력)

 

저장을 하면 Host명으로 간단하게 접속이 가능해진다.

 

EC2 인스턴스에 ssh로 접속을 했으면 Jar 파일을 실행하기 위해 JDK 설치를 해준다.

sudo apt-get update
sudo apt-get install openjdk-11-jdk

 

배포할 프로젝트를 gradle로 build하는데 Spring Boot 2.5 버전 이상은 build를 하면 jar 파일을 생성하는 bootJar Task와 jar Task가 둘 다 실행이 되어서 jar 파일이 두개가 생성이 된다. 실행 가능한 Jar를 생성하는 bootJar Task만 필요하기 때문에 build.gradle에 jar enabled 옵션을 false로 바꾸도록 한다. (false로 추가하지 않으면 plain.jar 파일도 같이 생성이 된다.)

 

 

로컬에서 SSH 원격으로 Jar 파일을 전송하기 위해 scp(Secure Copy) 명령어로 build된 jar 파일을 EC2 서버로 복사한다.

 

java -jar로 실행하고 테스트 요청을 보내본다.

 

 

 

 

AWS 1편: EC2 생성 후 Spring Boot 띄우기

Overview AWS EC2 인스턴스를 생성하고 Spring Boot 서버를 띄워보는 것까지 진행합니다. 주 목표는 서버를 외부에 제공하는 거라서 따로 배포 시스템을 구축하지 않고 단순히 빌드 파일을 복사해서 수

bcp0109.tistory.com

+ Recent posts