[메모장 프로젝트] EC2 생성, 보안 그룹 설정 + 자동화 쉘 스크립트 (AWS 1)
1. EC2 생성, 보안 그룹 설정 + 자동화 쉘 스크립트
2. RDS PostgreSQL 생성, EC2 에 Redis 설치
3. GitHub Actions 로 자동 배포
4. 도메인 연결하기
5. Nignx 무중단 배포
AWS 배포하게 된 이유
우선 기존 프로젝트를 간단하게 `render` 에서 배포하였지만, 무료 사용 기간(한 달)이 지나 `AWS` 로 재배포하기로 마음먹었다!!
메모장 프로젝트는
- `PostgreSQL`
- `Redis`
를 사용하고 있다.
`PostgreSQL`과 `Redis` 를 `AWS RDS` 로 사용하여 `AWS` 가 관리하도록 할지, `EC2` 서버 내부에 직접 설치할지 고민이었다.
1. `RDS` 사용하는 경우
: `AWS` 가 자동으로 백업, 장애복구, 보안패치, 스케일링 관리
: 고가용성 옵션 쉽게 적용 가능
: 성능 튜닝에만 집중 가능
: 비용이 들 수 있음 (PostgreSQL 은 프리티어에서 지원해 줘서 무료로 사용 가능, Redis 는 비용 추가)
2. `EC2` 서버 내부에 직접 설치하는 경우
: `RDS` 별도 요금 없음
: 설치, 설정 커스텀 가능
: 직접 백업, 장애 대응 등 관리 필요
: `EC2` 인스턴스가 다운되면 `DB` 도 다운
: 확장, 보안 관리 복잡
프리티어에서 `RDS` 는 750시간/월로 1대 인스턴스를 한 달 내내 무료로 사용할 수 있다.
따라서 `PostgreSQL` 은 프리티어로 `RDS` 를 사용하고,
`ElasticCache (Redis)` 는 추가 비용을 내야 하기 때문에 `EC2` 서버 내부에 직접 설치해서 사용하도록 하였다.
따라서
- `EC2 인스턴스` : Spring 애플리케이션 배포
- `RDS` : PostgreSQL (프리티어)
- `EC2` 내부 설치 : Redis
로 아키텍처를 결정했다.
`AWS` 에 접속하여 가입하고, 오른쪽 상단에 `region` 을 아시아 태평양 (서울) 로 바꿔준다.
그리고 혹시나 계정이 해킹당해 악명 높은 aws 요금이 발생할까 걱정되어 `Authenticator` 를 등록하여 핸드폰 앱으로 로그인 인증을 받도록 하였다.
EC2 인스턴스 생성하기
EC2
`AWS Console` > `EC2` > `인스턴스 시작`
(아래는 내가 설정한 방식이다. 참고만 바람!)
- 이름 : `notepad-ec2-server`
- 이미지: `Ubuntu 22.04 LTS`
- 인스턴스 유형: `t2.micro` (프리티어)
- 키페어: 생성하여 선택
(꼭꼭 저장해 주어야 한다. 잃어버리면 `EC2 인스턴스에 다시 접속할 수 없다.)
- 보안 그룹: 보안 그룹 생성해서 `notepad-secure`
이렇게 하고 인스턴스 시작 을 누르면 된다.
(인스턴스 종료를 누르게 되면, 다시 시작할 수 없어 인스턴스를 다시 생성해야 한다. 혹시나 꼬이거나 다시 시작해야 한다면, 재부팅 or 중지/시작 을 누르길 바란다...!)
보안 그룹
`네트워크 및 보안` > `보안 그룹`
아까 생성한 `notepad-secure` 를 클릭하여 인바운드 규칙을 추가한다.
`SSH` `22` 포트로 내 ip 만 접근하도록 추가하였다.
스프링 부트 애플리케이션을 연결할 것이기 때문에, 스프링 부트가 사용하는 포트인 `8284` 를 추가해 주었다.
(기존에는 `8000` 포트이지만, 내가 `application.yml` 에서 서버 포트를 `8284` 로 변경해 주었다.)
`HTTP` `80` 포트로 모든 ip 가 접근하도록 추가하였다.
(추후 `80` 포트로 접근하는 것을 `8284`로 라우팅 해주는 `Nginx` 를 사용할 것이기 때문에 추가해 주었다.)
`HTTPS` `443` 포트로 모든 ip 가 접근 가능하도록 추가하였다.
(도메인이 있어야 SSL 인증서를 통해 `HTTPS` 포트로 접근할 수 있지만, 미리 추가해 두었다.)
자동 등록 스크립트 작성
여기서 하나의 문제가 발생하는데,
내 ip 는 고정 ip 가 아닌 동적 ip 로 일정 기간마다 바뀌어서 일일이 보안 그룹에 추가해야 한다.
이러한 문제를 쉘 스크립트를 작성하여 자동화해 주었다.
@echo off
REM [AWS 보안 그룹에 내 IP 자동 등록]
set GROUP_ID=[보안 그룹 ID]
set PORTS=22
set PROTOCOL=tcp
REM 현재 외부 IP 조회
for /f "delims=" %%i in ('curl -s https://checkip.amazonaws.com') do set MY_IP=%%i
echo 현재 내 IP: %MY_IP%
REM 각 포트에 대해 기존 규칙 제거 후 새 규칙 추가
for %%P in (%PORTS%) do (
echo 포트 %%P 기존 규칙 제거 중...
aws ec2 revoke-security-group-ingress --group-id %GROUP_ID% --protocol %PROTOCOL% --port %%P --cidr %MY_IP%/32 > nul 2>&1
echo 포트 %%P 새 규칙 추가 중...
aws ec2 authorize-security-group-ingress --group-id %GROUP_ID% --protocol %PROTOCOL% --port %%P --cidr %MY_IP%/32
)
echo 완료! 현재 IP (%MY_IP%/32)가 포트 [%PORTS%]에 대해 보안 그룹에 등록되었습니다.
pause
이 파일을 생성하여 `.bat` 으로 저장하면 더블 클릭으로 쉘 스크립트가 실행되며 자동 등록이 된다.
여기서 기존 규칙 제거할 때, 중복 등록만 막는 용도로 과거 IP 는 제대로 삭제되지 않는다.
과거 IP 를 삭제하려면 과거 IP 를 불러와야 하는데
그렇게 하려면 aws 에서 보안 그룹을 `json` 이든 다른 걸로 받아와서 파싱 해서 해야 하므로,,, 우선은 이렇게 자동 등록만 되도록 하였다.
(보안 그룹에서 과거 IP 는 수동 삭제 해주면 된다.)
쉘 스크립트 실행
이제 `.bat` 스크립트가 `AWS` 가 통신할 수 있도록 `AWS CLI` 기본 설정을 해주어야 한다.
우선 `AWS Console` 에서 자격 증명을 발급받아야 하는데,
내 프로필 > 보안 자격 증명 > Access Key 만들기 를 통해 발급받을 수 있다.
여기서 `aws_access_key_id`, `aws_secret_access_key` 가 발급되는데 이것은 최초 한 번만 보여주니까 무조건 따로 저장해놔야 한다!
터미널에서 `aws` 를 설치해 준 뒤
aws configure
명령어를 입력하여 `AWS` 자격 증명 설정을 시작한다.
`AWS Access Key Id` : 아까 발급받은 `aws_access_key_id`
`AWS Secret Access Key` : 아까 발급받은 `aws_secret_access_key`
`region` : 아까 설정한 아시아 태평양(서울) region `ap-northeast-2`
`output` : 기본 설정 `json`
aws configure list
를 통해 설정된 내용을 확인할 수 있다.
이제 자동 등록 쉘 스크립트를 더블 클릭을 통해 실행할 수 있다!!
EC2 서버 실행
터미널에서 해당 명령어를 통해 `ec2` 서버에 접속할 수 있다.
ssh -i [key.pem] ubuntu@[EC2 퍼블릭 IP]
여기서 `key.pem` 은 아까 키 페어 생성한 그 파일로,
해당 파일이 있는 폴더로 이동한 후 실행해 주어야 키 페어 파일을 찾아 접속할 수 있다.
`ubuntu` 는 사용자 이름으로 `ubuntu` 를 사용하면 기본값이다.
`ec2 퍼블릭 ip` 는 생성한 `ec2` 인스턴스의 퍼블릭 ip 를 입력해 주면 된다.