AWS - EC2를 이용한 백엔드 배포

이유승·2024년 2월 8일
0

AWS

목록 보기
2/6

가장 먼저 EC2를 이용한 Node.js 기반 백엔드 배포에 나서보았다.

1. 순서

백엔드 배포는 대략 아래와 같은 순서로 진행되었다.

EC2 인스턴스 생성

보안 그룹 설정

백엔드 파일 업로드

테스트

2. 고통받는다..

배포를 해놓고 보면 간단하지만, 배포를 성공하는 과정은 가히 고통이나 다름없었다. 모든 단계에서 하나 이상의 문제가 반드시 발생했기 때문. 모든 문제들을 하나하나 열거하기에는 글이 너무 길어지기 때문에 단계별 진행 사항과 발생한 문제점, 그리고 해결 방법들을 정리해보았다.

EC2 인스턴스 생성 및 설정

AWS EC2 대시보드에서 인스턴스 생성을 위해 AMI 선택, 인스턴스 유형(t2.micro 사용), 키 페어 생성 및 할당, 스토리지 구성 등의 작업을 수행하였다.

여기서는 인스턴스 유형 및 스토리지 옵션 선택부터 어려움이 있었다. 당장 Amazon Machine Image(AMI)를 고르는데도 뭐가 뭔지 몰라서 두통이 올라오기 시작했다..

Amazon Linux 2 AMI: AWS에서 직접 관리하고 지원하는 AMI로, AWS와의 긴밀한 통합을 제공합니다. Node.js를 비롯한 다양한 소프트웨어를 쉽게 설치하고 관리할 수 있도록 구성되어 있습니다. AWS의 다른 서비스들과 함께 사용하기 위해 최적화되어 있으므로, 특히 AWS 환경에 특화된 기능이 필요한 경우 유리합니다.

Ubuntu Server AMI: Ubuntu는 Node.js 개발자들 사이에서 널리 사용되는 운영 체제입니다. 뛰어난 커뮤니티 지원과 광범위한 패키지 리포지토리를 자랑합니다. 또한, Node.js를 포함한 최신 소프트웨어의 설치가 매우 쉽습니다.

AWS Marketplace의 특정 Node.js AMI: 특정 Node.js 버전이 사전 설치된 AMI를 찾고 있다면, AWS Marketplace에서 관련 AMI를 검색해볼 수 있습니다. 이러한 AMI는 소프트웨어 스택을 미리 구성해놓은 것으로, 설정 시간을 절약할 수 있습니다.

내가 필요한 것은 Node.js 기반 백엔드 파일의 배포인데, 대략 알아보니 사실 뭘 선택해도 문제는 없는것 같았다. 구글링 결과 Ubuntu가 많이 사용되는 것 같아 이를 선택하였다.

인스턴스 유형의 경우, 돈을 많이 내고 싶은게 아니라면 선택지는 이미 정해져있다. 프리티어에 해당되는 유형을 친절하게 표시하기 해주기 때문에 고민 없이 선택하였다.

EC2 인스턴스 로그인에 사용되는 보안 키 페어(Key Pair). 키의 이름을 작성하면 AWS에서 보안 키를 알아서 생성해준다. 사용자는 이를 안전하게 보관하고 있다가 인스턴스 로그인 시에 사용하면 된다. 키 페어 형식의 경우 .ppk와 .pem으로 나뉘는데 윈도우 운영체제에서는 인스턴스 제어용 터미널 프로그램 PuTTY를 많이 사용하고, 여기에서는 .ppk를 사용한다고 해서 적절한 형식의 키로 발급받았다.

  • 주의!
    보안 키 페어 파일은 EC2 인스턴스에 대한 접근 권한을 뜻한다. 절대. 절대 잃어버리거나 함부로 공유해서는 안된다!

네트워크 설정은 EC2 인스턴스에 대한 엑세스 규칙을 설정하는 '보안 그룹' 구성을 포함한다. 해당 인스턴스에 접근할 수 있는 권한을 제어하는 곳이기에 매우매우 중요하다. 하단 체크박스에 대한 설명은..

SSH 트래픽 허용: 이 규칙은 원격에서 인스턴스에 SSH로 접속할 수 있게 합니다. 보안상의 이유로, 가능하다면 특정 IP 주소 또는 IP 주소 범위만 허용하도록 설정하는 것이 좋습니다.

HTTPS 트래픽 허용: 만약 인스턴스가 HTTPS 트래픽을 처리할 웹 서버로 사용될 예정이라면, 포트 443에 대한 접근을 허용해야 합니다.

HTTP 트래픽 허용: 웹 사이트 또는 웹 애플리케이션을 호스팅하는 경우, 포트 80에 대한 접근을 허용해야 합니다.

해당 인스턴스가 인터넷 상에서 완전 공개되어 누구나 접근하게 두는 것은 보안상의 관점에서 그리 좋은 일이 아니다. 다만 내 프로젝트의 특성상 외부에 공개되는게 당연한 탓에, 이 설정은 기본 설정을 그대로 두었다. 지금 당장은 이해하기 쉬운 내용이 아니므로 나중에 다시 살펴보기로 하였다.

스토리지 구성은.. 프리티어에서 허용하는 만큼 그대로 두면 된다. EC2 프리티어에서는 30GB까지 제공하지만, 사용량이 폭증하면 이에 대한 과금이 발생하기도 하고 내 개인 프로젝트에서 큰 용량을 필요로 할 가능성도 낮아서 8GB의 스토리지 설정을 그대로 사용하였다.

마지막으로 고급 세부 설정 탭이 있다. 여기는 내 프로젝트 목적 상 굳이 손댈 항목들이 없어 기본 설정을 그대로 두었다. 세부 설정에는 아래와 같은 항목들이 존재한다.

사용자 데이터(User Data): 인스턴스가 시작될 때 실행할 스크립트나 명령을 제공할 수 있습니다. 예를 들어, 서버에 소프트웨어를 자동으로 설치하거나 구성을 수행하는 스크립트를 입력할 수 있습니다.

IAM 역할(IAM Role): 인스턴스가 AWS 서비스에 안전하게 접근할 수 있도록 IAM 역할을 할당할 수 있습니다.

모니터링: 추가 모니터링 옵션인 "상세 모니터링 활성화"를 선택하여 인스턴스의 성능 지표를 더 자세히 모니터링할 수 있습니다.

테넌시(Tenancy): 인스턴스가 공유된 하드웨어에서 실행될지, 아니면 전용 하드웨어에서 실행될지를 결정합니다.

그러면 이렇게 EC2 인스턴스를 생성할 수 있다.

PuTTY를 이용한 SSH 설정

다음 단계는 배포 중인 인스턴스에 접속하여 백엔드 구동에 필요한 요소들을 설치하고, 백엔드 파일을 업로드한 다음 서버를 가동해보는 것이다.

서버는 EC2를 통해 배포되었다. 그런데 이 서버에 내가 접근할 수 있어야 필요한걸 설치하고, 서버를 가동하고 멈추는 등의 행동을 할 수 있다. 이를 위해서 PuTTY를 설치하였다.

PuTTY

무료, 오픈 소스 터미널 에뮬레이터 프로그램. 사용자가 네트워크를 통해 다른 컴퓨터와 통신할 수 있게 해준다.

PuTTY는 다음과 같은 기능들을 제공해준다.

SSH (Secure Shell): SSH는 원격 컴퓨터에 안전하게 접속하고 명령을 실행할 수 있게 해주는 프로토콜입니다. PuTTY를 사용하여 서버나 다른 컴퓨터에 SSH를 통해 안전하게 연결할 수 있습니다.

Telnet: 이전에는 널리 사용되었던 Telnet 프로토콜을 통해 원격 컴퓨터에 접속할 수 있습니다. 하지만 Telnet은 암호화되지 않기 때문에 보안상의 문제가 있어 현재는 SSH에 비해 덜 사용됩니다.

시리얼 COM 포트 연결: PuTTY는 시리얼 포트를 통해 하드웨어 장치와 통신하는 기능도 제공합니다.

기타 프로토콜 지원: SCP, SFTP 등의 프로토콜도 지원합니다.

PuTTY를 설치하고 실행시키면 이런 화면이 출력된다. 가장 먼저 할 것은 SSH 세션을 구성하는 것. 이를 위해서 아래 단계를 수행하였다.

Host Name (or IP address): 여기에 EC2 인스턴스의 퍼블릭 IP 주소 또는 퍼블릭 DNS 이름을 입력합니다.

생성한 EC2 인스턴스에서는 접근을 위한 IP 주소 혹은 DNS 이름을 제공하고 있다. 이를 가져와서 입력하면 된다. 인스턴스 콘솔의 퍼블릭 IPv4 주소를 가져오면 된다.

Port: SSH의 기본 포트인 22를 그대로 사용합니다.

Connection type: 'SSH'가 선택되어 있는지 확인합니다. 이것은 기본적으로 선택되어 있어야 합니다.

Saved Sessions: 세션 정보를 저장하고 싶다면, 이 섹션에 세션 이름을 입력하고 'Save' 버튼을 클릭합니다. 이렇게 하면 나중에 같은 설정을 빠르게 불러올 수 있습니다.

Open: 모든 정보가 입력되었다면 'Open' 버튼을 클릭하여 EC2 인스턴스에 접속합니다.

필요한 내용들을 입력하고.. 세션을 열어서 인스턴스에 접속하면..

이 문제는 어처구니 없지만 PuTTY를 종료하고 재실행하니 다시 발생하지 않았다. 일시적인 오류가 발생했었나 보다..

이번에는 새로운 오류가 발생하였다. 이 오류 문구를 검색해보니 PuTTY가 올바른 퍼블릭 키를 제공받지 못하고 있을 때 발생하는 오류라고 한다. 퍼블릭 키라는 것은 EC2 인스턴스 생성 과정에서 발급받은 보안 키 페어(Key Pair)를 뜻한다. 생각해보니 이 보안 키를 PuTTY에 저장하거나 키를 가져오는 등의 설정을 해주지 않았었다. 보안 키는 아래 과정을 통해 PuTTY에서 접근할 수 있도록 해주어야 한다.

PuTTY 설정에서 'Connection' > 'SSH' > 'Auth' 섹션으로 이동합니다.

'Private key file for authentication' 필드에 .ppk 파일을 지정해야 합니다.

'Browse' 버튼을 클릭하여 올바른 .ppk 파일을 찾아 선택합니다.

그러자.. PuTTY에서 정상적으로 내 EC2 인스턴스에 접근할 수 있었다!

Node.js 및 필요 소프트웨어 설치

다음 순서는 EC2 인스턴스 내부에 백엔드 구종에 필요한 소프트웨어들을 설치해주어야 한다. 가장 먼저 설치해야하는 것은 Node.js.

sudo apt-get install -y nodejs # Ubuntu

그런데 Node.js 설치 단계에서 오류가 발생하였다! 이게 도대체 무슨 일인지 파악하지 못해 한동안 골머리를 앓았는데.. 알고보니 Node.js 버전 문제였다. 내가 입력한 명령어에서는 딱히 버전을 선택해주지 않았는데, 기본으로 설치되는 버전은 14.x 버전이고 이건 너무 오래되서 보안 업데이트나 중요한 안정성 업데이트를 받지 못하기 때문에 deprecated. 설치가 금지되어 있었다.

sudo yum install https://rpm.nodesource.com/pub_18.x/nodistro/repo/nodesource-release-nodistro-1.noarch.rpm -y
sudo yum install nodejs -y --setopt=nodesource-nodejs.module_hotfixes=1

따라서 노드소스의 GitHub 저장소에서 새로운 설치 방법을 찾아, Node.js의 최신 버전을 적절한 설치 방법을 통해 설치하였다.

백엔드 코드 배포

이번에는 백엔드 코드를 업로드 해주어야 한다. 방법은 여러가지가 존재하지만, 가장 간단한 것은 Git 연동. 특정 Git 저장소에서 파일들을 클론받아 올 수가 있다. 이 방법은 파일을 가져오는 것도 편리하지만, 서버 파일이 업데이트 되었을 때 Git의 버전 관리를 그대로 사용할 수 있어 파일 업데이트도 손쉽게 수행할 수 있다.

일단 프로젝트 기능이 제대로 구현된 것은 아니기 때문에 서버에 호출이 들어오면 콘솔에 응답 문구를 출력하는 간이 백엔드 파일을 Git에 올려 EC2 인스턴스로 업로드하였다. 물론, 작업에 앞서 Git도 EC2 인스턴스에 설치해주어야 한다.

sudo apt-get install git # Ubuntu

git clone https://your-repository-url.git

Git을 설치하고, 백엔드 코드가 저장된 Git 저장소의 url을 이용해 명령어를 입력해준다. 이렇게 되면 EC2 인스턴스에 백엔드 파일이 정상적으로 업로드된다.

환경 변수 설정

.env 파일을 포함한 환경 변수들은 대부분의 경우 gitignore을 이용하여 Git에 업로드 되지 않도록 설정한다. 경 변수 파일은 보통 민감한 정보(예: 데이터베이스 비밀번호, API 키 등)를 포함하므로, 이를 공개 리포지토리에 업로드하는 것은 보안상 대단히 위험한 행동이기 때문이다.

따라서 EC2 인스턴스에서는 .env 파일을 따로 만들어주어야 한다. 여기서는 2개의 텍스트 편집 프로그램을 기본적으로 제공해주고 있다.

nano .env
vi .env

원하는 편집 프로그램을 통해 env 파일을 생성하고, 필요한 키와 값을 입력한 뒤 파일 저장 및 종료해주면 된다.

백엔드 서비스 실행 및 테스트

Git에서 파일을 클론해본 사람은 알겠지만, 기본적으로 프로그램 구동에 필요한 기반 파일들은 용량 문제 등으로 같이 클론되지 않는다. package.json을 통해 어떤 라이브러리 등이 무슨 버전으로 설치되어있는지 정보만 저장되어있다. EC2 인스턴스에서도 동일하다.

npm i

package.json의 정보를 이용하여 필요한 라이브러리 등을 인스턴스에 설치하여 준다. 그리고 백엔드가 클론되어있는 경로에 들어가 서버 파일을 실행시킨다.

node server.js

연결 테스트..?

프론트엔드에서 보낸 요청이 백엔드에 도달하지 않았다. 이는 프론트엔드가 백엔드와 연결되지 못했다는 뜻. 이 문제의 원인은 다양하지만, 일단 가장 먼저 살펴보아야 할 곳은 보안 그룹 설정이다.

다행스럽게도 문제의 원인은 빠르게 발견되었다. EC2 인스턴스의 인바운드, 아웃바운드 설정에서는 특정 포트에서의 접근만을 허용하고 있다. 내 인스턴스에 접근할 수 있는 포트가 보안 규칙에 존재하지 않아서 프론트엔드에서 접근이 불가능했던 것이다.

'새 규칙 추가' 버튼을 클릭하고, 다음 정보를 입력합니다:
유형: Custom TCP Rule
프로토콜: TCP
포트 범위: 3001
원본: 0.0.0.0/0 (또는 보안을 위해 특정 IP 주소만 허용할 수 있습니다)

인바운드 규칙에 포트 범위를 추가하고, 모든 IP에서의 요청을 허용하였다. 다시 테스트해보니.. 내 로컬 프론트엔드에서 EC2 백엔드 인스턴스에 요청이 잘 닿는 것을 확인하였다!

세부 사항: 프론트엔드 애플리케이션에서 백엔드 API에 대한 요청을 테스트했습니다.
문제와 해결: 처음에는 연결 시간 초과 오류가 발생했습니다. EC2 인스턴스의 보안 그룹 설정을 조정하여 필요한 포트를 열어 문제를 해결했습니다.

3. 겨우 성공했다..

며칠 동안 극한의 고통을 받아간 끝에 겨우 EC2를 이용한 백엔드 배포에 성공했다. 성공한 것은 보람차고 뿌듯한 일이지만, 아직 갈 길이 멀다. 프론트엔드와 데이터베이스는 시작도 못했기 때문..

profile
프론트엔드 개발자를 준비하고 있습니다.

0개의 댓글