Week 07 — AWS 3-Tier 웹 서비스 인프라 완전 구축
상세 기술 보고서 및 스크린샷은 GitHub에서 확인할 수 있습니다. hojjang98 / skshielders-rookies-28 — projects/week_07
개요
Week 7 는 AWS 클라우드 인프라를 주제로 학습한 주간이다. 이론에 머무르지 않고, 중소 규모 전자상거래 웹사이트를 가상 시나리오로 설정하여 실무 수준의 완전한 3-Tier 아키텍처를 AWS 에서 처음부터 끝까지 직접 구축했다.
- 구축일 — 2025년 12월 11일
- 리전 — ap-northeast-3 (Osaka)
- 소요 시간 — 약 3시간
- 실제 발생 비용 — ~$0.5 (구축 후 즉시 삭제)
설계 목표
| 목표 | 구현 방법 |
|---|---|
| 고가용성 (HA) | Multi-AZ 구성으로 단일 가용 영역 장애 시에도 서비스 지속 |
| 자동 확장성 | Auto Scaling Group 으로 트래픽 변동에 자동 대응 |
| 계층별 보안 | Public / Private 서브넷 분리 + Security Group 최소 권한 |
| 트래픽 분산 | Application Load Balancer 를 통한 인스턴스 간 로드 밸런싱 |
| 데이터 격리 | RDS 를 완전한 Private Subnet 에 배치하여 외부 접근 차단 |
전체 아키텍처
인터넷 사용자
│
▼
Application Load Balancer (Public Subnet — ap-northeast-3a / 3b)
│
▼ (트래픽 분산)
┌────────────────────────────────────────┐
│ Amazon VPC (10.0.0.0/16) │
│ │
│ [ Public Subnet — Multi-AZ ] │
│ - ALB (3a, 3b) │
│ - NAT Gateway (3a, 3b) │
│ - Internet Gateway │
│ │ │
│ ▼ │
│ [ Private App Subnet — Multi-AZ ] │
│ - EC2 web-server-1a (3a) │
│ - EC2 web-server-1b (3b) │
│ - Auto Scaling Group (Min 2, Max 4) │
│ │ │
│ ▼ │
│ [ Private DB Subnet — Multi-AZ ] │
│ - RDS MySQL 8.0.35 │
│ - DB Subnet Group │
│ │
└────────────────────────────────────────┘
구축 리소스 상세
네트워크 계층
- VPC — 3tier-production-vpc (CIDR: 10.0.0.0/16)
- 서브넷 6개 — Public 2개 / Private App 2개 / Private DB 2개 (각 AZ 별 1개씩)
- Internet Gateway — VPC 와 인터넷 연결
- NAT Gateway 2개 — Private 서브넷의 아웃바운드 인터넷 통신 허용 (Multi-AZ)
- Route Table 5개 — Public 1개 + Private App 2개 + Private DB 2개
서브넷 CIDR 설계:
Public-3a : 10.0.1.0/24 (ALB, NAT)
Public-3b : 10.0.2.0/24 (ALB, NAT)
PrivateApp-3a : 10.0.11.0/24 (EC2)
PrivateApp-3b : 10.0.12.0/24 (EC2)
PrivateDB-3a : 10.0.21.0/24 (RDS)
PrivateDB-3b : 10.0.22.0/24 (RDS)
보안 계층 — Security Groups
계층별 인바운드 규칙을 철저히 분리하여 수평 이동(Lateral Movement) 을 차단한다.
alb-sg (ALB 전용)
인바운드: 80 (HTTP) / 443 (HTTPS) from 0.0.0.0/0
아웃바운드: 80 to web-server-sg
web-server-sg (EC2 전용)
인바운드: 80 (HTTP) from alb-sg 만 허용
아웃바운드: 3306 (MySQL) to rds-sg
rds-sg (RDS 전용)
인바운드: 3306 (MySQL) from web-server-sg 만 허용
아웃바운드: 제한 없음
컴퓨팅 계층
- Application Load Balancer — Active 상태, 헬스 체크로 비정상 인스턴스 자동 제외
- Target Group — 2개 인스턴스 모두 Healthy 확인
- Launch Template — AMI: Amazon Linux 2023 + User Data 스크립트 포함
- Auto Scaling Group — Min 2 / Max 4 / Desired 2, 인스턴스 장애 시 자동 교체
데이터베이스 계층
- RDS MySQL 8.0.35 (db.t3.micro)
- DB Subnet Group 으로 Multi-AZ 배치
- 완전 Private Subnet 격리 — 인터넷 및 ALB 에서 직접 접근 불가
핵심 코드 — EC2 User Data 스크립트
Auto Scaling Group 이 새 인스턴스를 시작할 때 Launch Template 의 User Data 가 자동 실행된다. 이 스크립트 덕분에 인스턴스가 추가될 때마다 수동 설정 없이 Nginx 가 자동 설치 및 실행된다.
스크립트 주요 흐름:
1. 시스템 업데이트 및 Nginx 설치
yum update -y
yum install -y nginx
2. Nginx 서비스 시작 및 부팅 시 자동 실행 등록
systemctl start nginx
systemctl enable nginx
3. EC2 메타데이터 API 로 인스턴스 정보 수집
INSTANCE_ID => ec2-metadata --instance-id
AZ => ec2-metadata --availability-zone
4. 인스턴스별 고유 HTML 페이지 생성
index.html 에 INSTANCE_ID, AZ 값을 동적으로 삽입
=> 브라우저에서 새로고침 시 ALB 가 두 인스턴스를 번갈아 응답하는 것을 육안으로 확인 가능
이 구성 덕분에 ALB 에서 발급받은 DNS 로 브라우저를 새로고침할 때마다 web-server-1a (ap-northeast-3a) 와 web-server-1b (ap-northeast-3b) 가 번갈아 응답하는 로드 밸런싱을 직접 확인할 수 있었다.
트러블슈팅
문제 1 — Private Subnet 에서 인터넷 접근 불가
-
증상 — User Data 스크립트 실행 실패, Nginx 설치 안 됨
-
원인 — Private App Subnet 의 Route Table 에 NAT Gateway 경로가 미설정
-
해결 — Private App Subnet Route Table 에 0.0.0.0/0 => NAT Gateway 경로 추가
수정 전: Private App Subnet => 목적지 없음 (인터넷 불가) 수정 후: Private App Subnet => 0.0.0.0/0 => NAT-3a / NAT-3b
문제 2 — Auto Scaling 인스턴스 단일 AZ 집중
-
증상 — Auto Scaling Group 이 두 인스턴스를 모두 ap-northeast-3a 에만 배치
-
원인 — ASG 의 AZ 밸런싱 설정이 초기 배포에서 단일 AZ 로 편중
-
해결 — ap-northeast-3b 에 EC2 인스턴스를 수동 생성 후 Target Group 에 직접 등록
결과: web-server-1a (ap-northeast-3a) + web-server-1b (ap-northeast-3b) => Target Group 에서 2 Healthy 확인
비용 분석
실제 구축 비용 (3시간 운영)
| 리소스 | 비용 |
|---|---|
| NAT Gateway × 2 | $0.27 |
| Application Load Balancer | $0.07 |
| EC2 t3.micro × 2 | $0 (프리티어) |
| RDS db.t3.micro | $0 (프리티어) |
| 총계 | ~$0.5 |
프로덕션 환경 월 예상 비용
NAT Gateway, ALB, EC2 (On-Demand), RDS 등을 상시 운영 시 약 $325/월 수준. 비용 절감을 위해서는 EC2 Reserved Instance, RDS Reserved Instance, Savings Plans 를 검토해야 한다.
보안 관점 연계
이번 프로젝트에서 적용한 설계 원칙은 실무 보안 아키텍처와 직접 연결된다.
-
최소 권한 원칙 (PoLP) — Security Group 에서 필요한 포트만 열고, 출처도 특정 SG 로 제한
-
심층 방어 (Defense in Depth) — ALB -> EC2 -> RDS 로 이어지는 3중 방어선
-
네트워크 분리 — 외부에서 DB 에 직접 접근하는 경로가 아키텍처 레벨에서 존재하지 않음
-
가용성 확보 — Multi-AZ 구성으로 단일 장애 지점(SPOF) 제거
공격자가 ALB DNS 를 알아도:
- EC2 내부 IP 는 외부 노출 없음 (Private Subnet)
- RDS 는 web-server-sg 에서만 접근 가능 (VPC 내부 전용)
- SSH 는 Security Group 규칙에 없음 (Bastion Host 별도 구성 필요)
학습 성과 정리
| 영역 | 학습 내용 |
|---|---|
| 네트워크 | VPC 설계, 서브넷 CIDR 할당, Route Table, NAT / IGW 역할 |
| 로드 밸런싱 | ALB 동작 원리, Target Group, 헬스 체크 메커니즘 |
| Auto Scaling | Launch Template, ASG 정책, User Data 자동화 |
| 데이터베이스 | RDS 배치 전략, DB Subnet Group, 보안 격리 |
| 보안 설계 | Security Group 계층 분리, 최소 권한 원칙 적용 |
| 트러블슈팅 | NAT 라우팅 문제 해결, AZ 불균형 수동 교정 |
향후 확장 방향
- HTTPS 적용 — ACM 인증서 + ALB HTTPS 리스너 추가
- 도메인 연결 — Route 53 으로 커스텀 도메인 연결
- Bastion Host — Private EC2 에 SSH 접근을 위한 점프 서버 구성
- CloudWatch 모니터링 — CPU / 메모리 / 요청 수 기반 Auto Scaling 정책 설정
- WAF 연동 — ALB 앞단에 AWS WAF 추가하여 웹 애플리케이션 공격 차단
- IaC 전환 — 수동 구축을 Terraform 또는 CloudFormation 으로 자동화