| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- OOP
- SpringLegacy
- AOP
- TDD
- 이벤트핸들러this
- 문제선택근거
- 공통기술
- 로그백
- 디스크i/o
- string
- JPA
- 전전긍긍
- SEQUENCE
- 클린아키텍처
- model
- MVC
- Ajax
- 설정세팅
- JDBC
- 냄새라도
- Transaction
- index
- 공통규약
- 이벤트핸들러등록
- MVC요청플로우
- 사면초가
- DDD
- 단위테스트
- springsecurity
- 커뮤니티서버
- Today
- Total
개발이군고구마
[우당탕탕 배포공부] 2. AWS 세팅 1 - EC2와 ALB 세팅 본문

시리즈 순서
1. 요구조건 파악 : 배포 프로세스 결정하기 (요구사항, 다른 옵션과 비교, 선택 이유)
2. AWS EC2와 ALB 세팅
3. AWS RDS와 S3+CloudFront세팅
4. 과금 방지와 스프링단 설정
5. 도커와 CI/CD로의 확장 (추후)
1. 사용자 생성
루트 계정을 사용하게 되면 매번 MFA 인증을 하게되어 팀원들이 AWS 관리를 하기가 쉽지 않다.
개발자들이 쉽게 접속할 수 있게끔 사용자를 생성하여, 왠만한 모든 기능들을 컨트롤 할 수 있는 정책을 할당하였다.
여기서 IAM 개념과 구도 정리

💥 사용자 계정으로 들어갔을 때 EC2 안보이는 오류
- Region 확인 필수임
☑️ 이제 개발자가 아이디와 비번으로 MFA 에 없이 AWS 에 로그인하여 부여받은 정책의 기능들을 사용할 수 있게 된다.
2. EC2 생성
1단계.
AWS AMI 를 생성하였다면, 이제 본격 그 OS에 서버를 설치할 차례이다.
그 서버를 EC2 라 하고, 현 프로젝트는 프리티어 기능을 사용할 것이므로 t2.micro 를 선택하였다.
ec2나 rds 는 vpc 내에서 실행이 되고, 디폴트로 제공되는 vpc를 사용했다.
ALB를 사용할 예정이기 때문에 따로 탄력 ip(고정 ip) 를 할당하지 않았다.
(추후에 진행되는 많은 절차에서 퍼블릭 ip 주소를 사용하여 해결하였다.)
- EC2의 키페어 (.pem) 를 통해서 서버에 접근이 가능하기 때문에 잘 보관해두어야 한다.
- EC2 보안그룹은 누구에게서 받은 포트(역할)만 허용할 것인지를 정한다.
- SSH 포트의 경우 현재 로컬 PC의 IP를 지정하였고 (팀원들이 접근하기 위해선 그들의 로컬 ip주소도 추가한다)
- HTTPS (anywhere) HTTP (anywhere) 로 지정하였다 (이 부분도 추후 ALB가 생성되면 ALB에서만 받도록 수정예정)
2단계.
SSH 접속을 준비해야한다.
로컬 IP 주소로 접근이 가능하도록 보안그룹에 설정을 해두었기 때문에 접근이 가능하다.
💥 SSH 포트 접속 안됨 오류 " ubuntu@18.212.196.173: Permission denied (publickey)."
- 빠르게 인스턴스 접고, 키페어 다시 만들어서 해보는게 방법이다.
- 명령어를 한번에 치지 않고 끊어서 쳐보니 그때 ubuntu 안에 있는 ec2로 접속기 가능했다.
☑️ 이렇게 되면 지금 내 pc 에선 aws vpc 내에 ec2 라는 서버에 들어와있는 상태가 된다.
3. 가비아 DNS 등록
프론트 엔드는 netlify를 사용하여 배포가 된다고 한다. 이 부분은 아직 진행전이기 때문에, 백쪽에서 해주는 api 요청에 대한 처리를 진행한다.
netify (=프론트엔드) 가 배포가 되면 www. 로 netlify의 도메인 주소를 입력해야함을 까먹지 말자.
해당 단계에서는 A 레코드 "api.도메인" 을 "EC2의 퍼블릭 ip" 로 연결해주었으나 추후 이 부분은 CNAME ALB 도메인 주소로 변경 예정이다.
여기서 CNAME 과 A record 비교
| CNAME | A 레코드 | |
| 목적 | 도메인을 다른 도메인에 연결 | 도메인을 특정 IP에 직접 연결 |
| 사용 예 | static.도메인.com → dxxxxxx.cloudfront.net | api.도메인.com → 123.45.67.89 |
| 값 | 도메인(호스트)명 | IPv4 주소(숫자) |
| 특징 | IP가 바뀌어도 자동 연결 | IP가 바뀌면 직접 수정해야 함 |
| CloudFront, Netlify, AWS ALB 등 | CNAME만 사용 가능 | 사용 불가(CloudFront, Netlify 등은 IP가 없음) |
| 루트 도메인(예: 도메인.com 자체) | 불가(서브도메인만 사용) | 사용 가능 |
☑️ 이제 api.도메인 을 입력하면 AWS cloud에 있는 EC2로 접속하게 된다.
4. EC2에 스프링 띄우기
EC2 서버에 spring을 띄울 수 있는 사전 작업을 해야한다.
1단계.
spring 프로젝트는 현재 jdk 21로 구성되어있기 때문에, ec2 에 jdk 를 설치한다.
2단계.
이후 EC2에 깃헙에 올라가있는 프로젝트를 클론받고 -> 깃헙 프로젝트 폴더가 설치된다.
해당 폴더에서 gradle 빌드를 실행한다 -> 빌드 결과 실행할 수 있는 jar 파일이 생성됨 (배포하기 위해 생성된 파일)
jdk 명령어를 사용해 jar 파일을 실행시키면 spring 어플리케이션이 8080 포트로 실행이 된다.
3단계.
http://api.도메인:8080/ 으로 postman 테스트를 했을 때 "/" 경로로 요청을 받았을 때 나오는 응답메세지가 나오면 성공
번외.
- 컴파일링 과정에서 프리티어 CPU로는 감당이 안될 때가 있음 test 부분은 제외하고 컴파일링 시켜주는 것도 방법
./gradlew build -x test -x checkstyleMain -x checkstyleTest
- 스프링에서 코드 수정 후 ec2에 넣고 바로 테스트 해보고 싶을 때
로컬에서 작성한 파일을 ec2로 옮기고 로컬 안에서 컴파일링 이후 해당 로컬 파일을 ec2 로 옮겨줌
scp -i key.pem "로컬경로-0.0.1-SNAPSHOT.jar" ubuntu@퍼블릭ip:jar파일 경로
☑️ EC2 내에 코드 파일들이 저장된 폴더 안에서 spring을 실행되고 있다.
5. ALB와 HTTPs 연결
Client (443 HTTPS 요청)
↓
CloudFront (S3 이미지 - 지금은 생략)
↓
ALB (HTTPS → EC2:8080)
↓
EC2 Spring App (port 8080)
라는 흐름으로 요청이 가게끔 하기 위해 ALB를 설치해본다.
ALB는 사실 현 프로젝트처럼 EC2가 하나 존재하고 트래픽이 많이 발생해 서버를 분산하지 않는다면 굳이 필요가 없는 기능이긴 하다. 이 부분은 Nginx 로도 대체할 수 있는 부분이긴 하지만, 앞으로의 확장성을 위하여 설치해본다.
1단계.
우선 netlify 에서 들어오는 https 요청을 처리하기 위하여 ALB 에 SSL 인증서를 적용해야한다.
- ACM 에 들어가서 SSL 용 인증서를 발급받는다.
- 해당 인증서에는 2개의 도메인 경로를 연결시킨다. (*. 와일드 카드 + / 메인 )
- 여기서 ACM은 서울 리전에서 사용하는 것으로 생성한다.
2단계.
발급받은 인증서의 키와 값을 가비아 DNS 에 입력해둔다.
이렇게 되면 지정한 도메인으로 요청이 들어오게 되면 (api 요청) AWS가 등록된 키와 값을 확인하고 인증서를 발급해준다.
3단계.
향후 ALB가 연결된 target group을 생성한다.
생성한 target group은 http 8080으로 설정하고, 이 target group에는 기존에 생성한 EC2 인스턴스를 연결한다.
(이때 target group은 EC2가 autoscaling을 하게 된다면 ALB가 서버를 분산시키는 하나의 범위가 된다)
4단계.
- ALB를 생성한다.
ALB 는 subnet을 무조건 2개 이상 선택해야하지만, 현재 우리 프로젝트 사이즈엔 서브넷이 1개만 필요하다.
2개가 생성됬어도 어차피 EC2가 하나라면 사실상 subnet을 둘필요가 없긴 하다. 이런 경우에 ALB는 subnet 1개만 사용한다고 한다.
- 보안그룹을 수정한다.
Client (443 HTTPS 요청)
↓
ALB (HTTPS → EC2:8080) <- ALB의 보안그룹을 만들어서 443만 받도록 한다.
↓
EC2 Spring App (port 8080) <- EC2의 보안그룹은 8080 포트로 들어오는 요청은 ALB의 보안그룹만을 허용한다.
- EC2의 보안그룹도 수정해준다.
설정 기능들은 아래와 같다.
1) Internet-facing : 외부에서 들어오는 api
2) 리스너 설정 : 443 듣기 (과금의 위험으로 http 리다이렉트 기능은 넣지 않는다)
3) 보안그룹 : ALB의 보안그룹
4) 보안 리스닝 : 인증서 ACM
5) target group : http 8080
여기서 보안 그룹과 보안 리스닝의 차이 비교
| 리스너(Listener) | 보안 그룹(Security Group) |
| ALB에서 “443(https)”포트를 듣겠다고 선언 | 실제로 이 포트로 트래픽이 들어오는 걸 허용할지 결정(방화벽) |
5단계.
CNAME 을 api.도메인 요청이 들어올 때 ALB 도메인으로 오게 수정한다.
💥 503 Service Temporarily Unavailable
- target group을 제대로 설정해주지 않아서 오류가 발생함
- 또는 ALB와 EC2과 생성된 가용범위가 달라서 발생함 꼭 ALB를 생성할 땐 EC2와 같은 가용범위로 지정해주자
(만약 AZ 를 잘 못 설정하게 되면 ALB를 삭제한 후 다시 만들어야 한다)
☑️ https://api.도메인 을 입력하게 되면 ALB를 통하여 EC2에 접근하게 됨

[번외 - ALB의 확실한 기능 트래픽 분산]

'Cloud Deploy' 카테고리의 다른 글
| [GIT] rebase 또는 merge main 으로 브랜치 현행화 (0) | 2025.06.01 |
|---|---|
| [우당탕탕 배포공부] 4. 과금 방지와 스프링단 설정 (리전/AZ와 .env) (1) | 2025.05.18 |
| [우당탕탕 배포공부] 3. AWS 세팅 2 - AWS RDS와 S3+CloudFront세팅 (0) | 2025.05.17 |
| [우당탕탕 배포공부] 1. 배포 프로세스 결정하기 (요구 조건 파악) (0) | 2025.05.11 |
| [Git] Conflict 해소하며 배운 Git branch 원리들 (0) | 2024.07.13 |