1. CloudFront 개요
CloudFront란?
- Content Delivery Network (CDN) - 콘텐츠 전송 네트워크
- 전 세계 수백 개의 Edge Location에서 콘텐츠 캐싱
- 읽기 성능 향상, 사용자 경험 개선
CloudFront vs Edge Location 차이
CloudFront는 서비스 이름이고, Edge Location은 물리적 인프라입니다.
┌─────────────────────────────────────────────────────────────┐
│ CloudFront (서비스) │
│ │
│ = AWS의 CDN 서비스 전체를 말함 │
│ = 설정, 정책, 배포(Distribution) 등을 관리 │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Edge │ │ Edge │ │ Edge │ │ Edge │ │
│ │Location │ │Location │ │Location │ │Location │ │
│ │ (서울) │ │ (도쿄) │ │ (싱가폴) │ │ (LA) │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ = 전 세계 수백 개의 실제 서버/데이터센터 │
│ = 콘텐츠가 캐싱되는 물리적 위치 │
└─────────────────────────────────────────────────────────────┘| 구분 | CloudFront | Edge Location |
|---|---|---|
| 정의 | AWS의 CDN 서비스 | 전 세계에 분산된 물리적 서버 |
| 역할 | 배포 설정, 정책 관리 | 실제 콘텐츠 캐싱 및 전달 |
| 비유 | 택배 회사 (본사) | 각 지역 물류센터 |
| 개수 | 1개 서비스 | 전 세계 400개+ |
보안 기능
- DDoS 방어 (전 세계 분산 구조)
- AWS Shield 통합
- AWS WAF (Web Application Firewall) 통합
2. CloudFront Origins (원본)
지원하는 Origin 유형
| Origin 유형 | 설명 | 보안 |
|---|---|---|
| S3 Bucket | 파일 배포 및 캐싱, S3 업로드도 가능 | OAC (Origin Access Control) |
| VPC Origin | VPC Private Subnet 내 애플리케이션 | ALB/NLB/EC2 |
| Custom Origin (HTTP) | S3 정적 웹사이트, 모든 퍼블릭 HTTP 백엔드 | - |
S3를 Origin으로 사용 시
┌─── Edge (LA) ───┐
│ │
S3 Bucket ←─────────┼─── Edge (Mumbai)│ ←── Users
(Origin) Private │ │ (전 세계)
↑ AWS ├─── Edge (Melbourne)
│ │ │
OAC └─── Edge (São Paulo)
+
Bucket Policy- OAC (Origin Access Control) + S3 Bucket Policy로 보안
3. CloudFront vs S3 Cross Region Replication
| 비교 항목 | CloudFront | S3 Cross Region Replication |
|---|---|---|
| 네트워크 | Global Edge Network | 리전별 설정 필요 |
| 업데이트 | TTL 기반 캐싱 (예: 1일) | 거의 실시간 |
| 특징 | 캐싱 | 읽기 전용 |
| 용도 | 정적 콘텐츠 (전 세계 배포) | 동적 콘텐츠 (특정 리전 저지연) |
💡 실습: Private S3 버킷 + CloudFront + Route 53 연결하기
전체 아키텍처
┌─────────────────────────────────────────────────────────────────────┐
│ │
│ 사용자 │
│ │ │
│ │ https://www.example.com │
│ ▼ │
│ Route 53 (DNS) │
│ │ │
│ │ CNAME/Alias → d1234abcd.cloudfront.net │
│ ▼ │
│ CloudFront Distribution │
│ │ │
│ │ OAC (Origin Access Control) │
│ ▼ │
│ S3 Bucket (Private) │
│ - Block Public Access: ON │
│ - Bucket Policy: CloudFront만 허용 │
│ │
└─────────────────────────────────────────────────────────────────────┘Part 1: Private S3 버킷을 CloudFront OAC로 연결하기
Step 1: S3 버킷 생성 (Private)
# AWS CLI로 버킷 생성
aws s3 mb s3://my-private-website-bucket
# Block Public Access 활성화 (기본값이지만 확인)
aws s3api put-public-access-block \
--bucket my-private-website-bucket \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"⚠️ 버킷은 완전히 Private 상태입니다. 직접 접근 시 403 에러가 발생합니다.
Step 2: CloudFront Distribution 생성 + OAC 설정
콘솔에서 설정:
- CloudFront → Create Distribution
- Origin 설정:
- Origin Domain:
my-private-website-bucket.s3.ap-northeast-2.amazonaws.com - Origin Access: Origin Access Control (OAC) 선택
- Create new OAC 클릭 → 생성
- Origin Domain:
- Default Cache Behavior 설정:
- Viewer Protocol Policy: Redirect HTTP to HTTPS
- Allowed HTTP Methods: GET, HEAD
- Settings:
- Default Root Object:
index.html
- Default Root Object:
- Create Distribution 클릭
OAC란?
┌──────────────────────────────────────────────────────┐
│ OAC (Origin Access Control) - 권장 방식 │
│ │
│ CloudFront가 S3에 접근할 때 사용하는 인증 방식 │
│ - S3 버킷은 Private 유지 │
│ - CloudFront만 S3에 접근 가능 │
│ - 사용자는 반드시 CloudFront를 통해서만 접근 │
└──────────────────────────────────────────────────────┘
❌ OAI (Origin Access Identity) - 레거시, 사용 비권장
✅ OAC (Origin Access Control) - 신규 권장 방식Step 3: S3 Bucket Policy 설정
CloudFront가 S3에 접근할 수 있도록 Bucket Policy를 추가합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-private-website-bucket/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/EDFDVBD6EXAMPLE"
}
}
}
]
}| 요소 | 설명 |
|---|---|
Principal | CloudFront 서비스만 허용 |
Action | 객체 읽기만 허용 (GetObject) |
Condition | 특정 CloudFront Distribution만 허용 |
💡 콘솔에서 OAC 생성 시 "Copy policy" 버튼으로 자동 생성된 정책을 복사할 수 있습니다.
Step 4: 파일 업로드 및 테스트
# 파일 업로드
aws s3 cp index.html s3://my-private-website-bucket/
aws s3 cp style.css s3://my-private-website-bucket/
# 직접 S3 접근 시도 → 403 Forbidden (정상)
curl https://my-private-website-bucket.s3.ap-northeast-2.amazonaws.com/index.html
# CloudFront 통해 접근 → 200 OK (정상)
curl https://d1234abcd.cloudfront.net/index.htmlPart 2: Route 53으로 커스텀 도메인 연결하기
전제 조건
- Route 53에서 도메인 호스팅 중 (예:
example.com) - ACM에서 SSL 인증서 발급 (us-east-1 리전 필수!)
Step 1: ACM에서 SSL 인증서 발급
⚠️ 중요: CloudFront용 인증서는 반드시 us-east-1 (버지니아) 리전에서 발급해야 합니다!
AWS Certificate Manager (ACM) - us-east-1 리전
│
├─ Request certificate
│
├─ Domain names:
│ - example.com
│ - www.example.com
│ - *.example.com (와일드카드)
│
├─ Validation method: DNS validation
│
└─ Route 53에서 자동으로 CNAME 레코드 생성 (검증)Step 2: CloudFront에 커스텀 도메인 추가
- CloudFront Distribution → Edit
- Settings:
- Alternate Domain Names (CNAMEs):
www.example.com,example.com - Custom SSL Certificate: ACM에서 발급한 인증서 선택
- Alternate Domain Names (CNAMEs):
- Save Changes
Step 3: Route 53에서 DNS 레코드 생성
www.example.com → CloudFront 연결:
Route 53 Hosted Zone: example.com
│
└─ Record 생성:
- Record name: www
- Record type: A
- Alias: Yes
- Route traffic to: CloudFront distribution
- Distribution: d1234abcd.cloudfront.net 선택example.com (루트 도메인) → CloudFront 연결:
Route 53 Hosted Zone: example.com
│
└─ Record 생성:
- Record name: (비워둠 - 루트 도메인)
- Record type: A
- Alias: Yes
- Route traffic to: CloudFront distribution
- Distribution: d1234abcd.cloudfront.net 선택💡 Alias Record: Route 53 전용 기능으로, 루트 도메인(example.com)도 CloudFront에 연결 가능합니다. 일반 CNAME은 루트 도메인에 사용 불가!
Step 4: 최종 확인
# DNS 전파 확인 (몇 분 소요)
nslookup www.example.com
# HTTPS 접속 테스트
curl -I https://www.example.com
curl -I https://example.com전체 설정 요약 체크리스트
| 단계 | 설정 항목 | 확인 |
|---|---|---|
| 1 | S3 버킷 생성 (Private, Block Public Access ON) | ☐ |
| 2 | CloudFront Distribution 생성 + OAC 설정 | ☐ |
| 3 | S3 Bucket Policy에 CloudFront 허용 추가 | ☐ |
| 4 | ACM 인증서 발급 (us-east-1 필수) | ☐ |
| 5 | CloudFront에 Alternate Domain Names 추가 | ☐ |
| 6 | CloudFront에 SSL 인증서 연결 | ☐ |
| 7 | Route 53에 Alias A 레코드 생성 | ☐ |
자주 하는 실수
| 실수 | 해결 방법 |
|---|---|
| ACM 인증서를 다른 리전에서 발급 | us-east-1에서 다시 발급 |
| S3 Bucket Policy 누락 | CloudFront OAC용 정책 추가 |
| Route 53에서 CNAME 사용 (루트 도메인) | Alias A 레코드 사용 |
| CloudFront 배포 후 바로 접속 | 배포 완료까지 5~10분 대기 |
4. CloudFront 캐싱
기본 개념
- 캐시는 각 Edge Location에 존재
- Cache Key로 객체 식별
- Cache Hit 비율 최대화 = Origin 요청 최소화
CreateInvalidationAPI로 캐시 강제 갱신 가능
동작 흐름
Client → Edge Location → [캐시 확인]
↓
┌─── Cache Hit → 즉시 반환
│
└─── Cache Miss → Origin에서 가져옴 → 캐시 저장 → 반환
↓
TTL 후 만료5. Cache Key
기본 Cache Key 구성
Cache Key = hostname + resource portion of URL
예: mywebsite.com + /content/stories/example-story.htmlCache Key 확장
- 사용자, 디바이스, 언어, 위치에 따라 콘텐츠가 다른 경우
- Cache Policy로 추가 요소 포함 가능:
- HTTP Headers
- Cookies
- Query Strings
6. Cache Policy (캐시 정책)
캐시 기준 설정
| 요소 | 옵션 |
|---|---|
| HTTP Headers | None, Whitelist |
| Cookies | None, Whitelist, Include All-Except, All |
| Query Strings | None, Whitelist, Include All-Except, All |
TTL 설정
- 0초 ~ 1년 설정 가능
- Origin에서
Cache-Control,Expires헤더로도 설정 가능
HTTP Headers 옵션
| 옵션 | 설명 | 캐싱 성능 |
|---|---|---|
| None | 기본 헤더만 포함, 헤더 전달 안 함 | 최고 |
| Whitelist | 지정한 헤더만 Cache Key에 포함 + Origin에 전달 | 중간 |
Query Strings 옵션
| 옵션 | 설명 | 캐싱 성능 |
|---|---|---|
| None | Query String 무시, 전달 안 함 | 최고 |
| Whitelist | 지정한 것만 포함 + 전달 | 좋음 |
| Include All-Except | 지정한 것 제외하고 포함 + 전달 | 중간 |
| All | 모든 Query String 포함 + 전달 | 최저 |
Whitelist가 중요한 이유
Whitelist는 **"지정한 것만 Cache Key에 포함"**하는 옵션입니다.
같은 URL이라도 헤더/쿠키/쿼리에 따라 다른 콘텐츠를 보여줘야 할 때 사용합니다.
예: 언어별로 다른 콘텐츠
GET /products
Accept-Language: ko → 한국어 페이지
Accept-Language: en → 영어 페이지
Accept-Language: ja → 일본어 페이지
→ Whitelist에 Accept-Language만 추가하면 언어별로 캐시 분리!Whitelist 동작 예시:
┌─────────────────────────────────────────────────────────────┐
│ 클라이언트 요청 │
│ │
│ GET /products?category=shoes&tracking=abc123&ref=google │
│ Headers: Accept-Language, User-Agent, Authorization │
│ Cookies: session_id, preferences, ads_id │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Whitelist 설정: │
│ - Query String = "category"만 │
│ - Headers = "Accept-Language"만 │
│ - Cookies = "preferences"만 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Cache Key 생성 (이것만 캐시 구분에 사용) │
│ │
│ /products + category=shoes + Accept-Language:ko │
│ + preferences=dark │
│ │
│ ❌ tracking, ref, User-Agent, session_id 등은 무시 │
└─────────────────────────────────────────────────────────────┘All vs Whitelist 비교:
❌ All 사용 시 (비효율):
/products?category=shoes&tracking=abc → 캐시 1
/products?category=shoes&tracking=xyz → 캐시 2 (다른 캐시!)
/products?category=shoes&tracking=123 → 캐시 3 (또 다른 캐시!)
→ 같은 콘텐츠인데 tracking 값 때문에 캐시가 계속 분리됨
✅ Whitelist (category만) 사용 시 (효율적):
/products?category=shoes&tracking=abc → 캐시 1
/products?category=shoes&tracking=xyz → 캐시 1 (같은 캐시 사용!)
/products?category=shoes&tracking=123 → 캐시 1 (같은 캐시 사용!)
→ category만 보고 캐시 구분, tracking은 무시💡 핵심: Whitelist를 사용하면 캐시 효율을 높이면서도 필요한 경우에만 다른 콘텐츠를 제공할 수 있습니다.
7. Origin Request Policy
개요
- Cache Key에는 포함하지 않고 Origin 요청에만 포함할 값 지정
- 캐시 중복 방지
포함 가능 항목
- HTTP Headers: None, Whitelist, All viewer headers
- Cookies: None, Whitelist, All
- Query Strings: None, Whitelist, All
Cache Policy vs Origin Request Policy
Client 요청:
GET /content/stories/example-story.html?ref=123abc&split-pages=false
Headers: User-Agent, Authorization, Date, Keep-Alive
Cookie: session_id=12344321
┌─────────────────────────────────────────────────────┐
│ Cache Policy │
│ Cache Key: │
│ - mywebsite.com │
│ - /content/stories/example-story.html │
│ - Header: Authorization │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ Origin Request Policy │
│ Forward to Origin: │
│ - Headers: User-Agent, Authorization │
│ - Cookies: session_id │
│ - Query Strings: ref │
└─────────────────────────────────────────────────────┘
Origin으로 전달되는 요청:
GET /content/stories/example-story.html?ref=123abc
Headers: User-Agent, Authorization
Cookie: session_id=123443218. Cache Invalidation (캐시 무효화)
필요한 상황
- Origin 파일 업데이트 후 TTL 만료 전 캐시 갱신 필요
무효화 방법
CreateInvalidationAPI 사용- 전체 무효화:
/* - 특정 경로:
/images/*,/index.html
동작
S3 Bucket (Origin)
│ 파일 업데이트
↓
CloudFront에 Invalidation 요청
│
↓
┌─────────────────┐ ┌─────────────────┐
│ Edge Location 1 │ │ Edge Location 2 │
│ 캐시 무효화 │ │ 캐시 무효화 │
└─────────────────┘ └─────────────────┘9. Cache Behaviors (캐시 동작)
개요
- URL 경로 패턴별 다른 설정 적용
- 다른 Origin으로 라우팅 가능
경로 패턴 예시
| 패턴 | Origin | 용도 |
|---|---|---|
/images/* | S3 Bucket | 이미지 파일 |
/api/* | ALB | API 요청 |
/* | S3 Bucket | 기본 (항상 마지막 처리) |
로그인 페이지 예시
CloudFront Distribution
│
├─ /login → EC2 (인증 서버) → Signed Cookies 생성
│
└─ /* (default) → S3 Bucket (Signed Cookies 필요)10. Static vs Dynamic 분리 전략
Cache Hit 최대화 방법
┌─────────────────────────────────────────────────────┐
│ CloudFront CDN Layer │
│ │
│ Static Content │ Dynamic Content │
│ (S3) │ (ALB + EC2) │
│ │ │
│ - 헤더/세션 캐싱 없음 │ - 적절한 헤더/쿠키 캐싱 │
│ - 캐시 히트율 최대화 │ │
└─────────────────────────────────────────────────────┘11. ALB/EC2를 Origin으로 사용
방법 1: VPC Origins (권장)
- VPC Private Subnet 내 애플리케이션 배포 가능
- 인터넷에 노출 불필요
Users → CloudFront Edge → VPC Origin → Private Subnet
├─ ALB
├─ NLB
└─ EC2방법 2: Public Network
ALB 사용 시:
Edge Location (Public IP)
↓ Allow Edge Location IPs
ALB (Must be Public)
↓ Allow ALB Security Group
EC2 (Can be Private)EC2 직접 사용 시:
Edge Location (Public IP)
↓ Allow Edge Location IPs
EC2 (Must be Public)💡 Edge Location IP 목록:
http://d7uri8nf7uskq.cloudfront.net/tools/list-cloudfront-ips
12. Geo Restriction (지역 제한)
설정 방식
| 방식 | 설명 |
|---|---|
| Allowlist | 지정 국가에서만 접근 허용 |
| Blocklist | 지정 국가에서 접근 차단 |
특징
- 3rd party Geo-IP 데이터베이스로 국가 판별
- 사용 사례: 저작권법에 따른 콘텐츠 접근 제어
13. Signed URL / Signed Cookies
용도
- 프리미엄 사용자에게만 유료 콘텐츠 배포
Signed URL vs Signed Cookies
| 구분 | Signed URL | Signed Cookies |
|---|---|---|
| 대상 | 개별 파일 (파일당 1개 URL) | 여러 파일 (1개 쿠키로 다수 파일) |
정책에 포함되는 정보
- URL 만료 시간
- 접근 가능 IP 범위
- Trusted Signers (서명 가능한 AWS 계정)
URL 유효 기간 권장
| 콘텐츠 유형 | 유효 기간 |
|---|---|
| 공유 콘텐츠 (영화, 음악) | 짧게 (몇 분) |
| 개인 콘텐츠 | 길게 (몇 년까지 가능) |
동작 흐름
1. Client → Application (인증/인가)
2. Application → AWS SDK로 Signed URL 생성
3. Application → Client에 Signed URL 반환
4. Client → CloudFront (Signed URL로 요청)
5. CloudFront → OAC → S3 → 객체 반환14. CloudFront Signed URL vs S3 Pre-Signed URL
| 비교 항목 | CloudFront Signed URL | S3 Pre-Signed URL |
|---|---|---|
| 접근 범위 | 경로 기반 (Origin 무관) | 특정 S3 객체 |
| 키 관리 | 계정 전체 Key Pair (root 관리) | IAM Principal의 키 |
| 필터링 | IP, 경로, 날짜, 만료 | 제한적 |
| 캐싱 | ✅ 활용 가능 | ❌ 직접 S3 접근 |
| 권장 용도 | CloudFront 배포 콘텐츠 | S3 직접 접근 |
15. Signed URL 서명 프로세스
서명자 유형
| 유형 | 설명 | 권장 |
|---|---|---|
| Trusted Key Group | API로 키 생성/교체, IAM으로 보안 | ✅ 권장 |
| AWS Account Key Pair | root 계정 + 콘솔로 관리 | ❌ 비권장 |
키 사용 방식
┌─────────────────────────────────────────┐
│ Key Pair 생성 │
│ - Private Key: 애플리케이션 (EC2 등) │
│ - Public Key: CloudFront에 업로드 │
└─────────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────┐
│ Private Key로 URL 서명 (애플리케이션) │
└─────────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────┐
│ Public Key로 URL 검증 (CloudFront) │
└─────────────────────────────────────────┘16. CloudFront 요금
Price Classes
| Price Class | 설명 | 비용 | 성능 |
|---|---|---|---|
| Price Class All | 모든 리전 | 높음 | 최고 |
| Price Class 200 | 대부분 리전 (고비용 리전 제외) | 중간 | 좋음 |
| Price Class 100 | 최저가 리전만 | 최저 | 제한적 |
비용 절감 방법
- Edge Location 수를 줄여 비용 절감
- Price Class 100/200 선택
17. Multiple Origins (다중 Origin)
경로 패턴별 Origin 라우팅
CloudFront Distribution
│
├─ /api/* → ALB (API 서버)
│
└─ /* → S3 Bucket (정적 파일)18. Origin Groups (고가용성)
구성
- Primary Origin + Secondary Origin
- Primary 실패 시 Secondary로 자동 전환
동작 흐름
Client → CloudFront → Primary Origin (Origin A)
│
┌─────┴─────┐
│ 정상 응답 │ → 반환
│ │
│ 에러 응답 │ → Secondary Origin (Origin B) 시도
└───────────┘S3 + CloudFront 리전 레벨 고가용성
Origin Group
├─ Primary: S3 Bucket (us-east-1)
│ ↓ Replication
└─ Secondary: S3 Bucket (eu-west-1)19. Field Level Encryption
개요
- 민감한 정보를 Edge에서 암호화
- HTTPS에 추가적인 보안 레이어
- 비대칭 암호화 사용
동작 흐름
Client → Edge Location → ALB → Web Server
│ │
Public Key로 Private Key로
암호화 복호화설정
- POST 요청의 특정 필드 지정 (최대 10개)
- Public Key 지정하여 암호화
20. Real-Time Logs
개요
- CloudFront 요청을 실시간으로 Kinesis Data Streams에 전송
- 콘텐츠 전송 성능 모니터링, 분석, 조치
설정 옵션
- Sampling Rate: 로그를 받을 요청 비율
- 특정 필드 선택
- 특정 Cache Behaviors (경로 패턴) 선택
아키텍처 예시
CloudFront → Kinesis Data Streams → Lambda (실시간 처리)
│
└→ Kinesis Data Firehose → S3/Redshift (저장/분석)핵심 요약
Cache 최적화 전략
| 전략 | 설명 |
|---|---|
| Cache Key 최소화 | 불필요한 헤더/쿠키/쿼리 제외 |
| Static/Dynamic 분리 | 정적 콘텐츠는 캐싱, 동적은 별도 처리 |
| 적절한 TTL 설정 | 콘텐츠 특성에 맞게 |
| Cache Behaviors 활용 | 경로별 최적화된 설정 |
Origin 유형별 사용 사례
| Origin | 사용 사례 |
|---|---|
| S3 Bucket | 정적 웹사이트, 이미지, 미디어 |
| VPC Origin (ALB/EC2) | Private Subnet 앱, API |
| Custom HTTP | 기존 HTTP 서버, S3 정적 웹사이트 |
보안 기능 요약
| 기능 | 용도 |
|---|---|
| OAC | S3 Origin 보안 |
| Geo Restriction | 국가별 접근 제어 |
| Signed URL/Cookies | 프리미엄 콘텐츠 보호 |
| Field Level Encryption | 민감 필드 암호화 |