38장. CloudFront — 사용자에 가까운 곳에서 응답하기
이 장에서 말하고자 하는 것
지금까지 우리는 사용자가 도메인을 거쳐
ALB까지 도달하는 길을 만들었다.
그런데 한국에서 만든 서비스를 미국 사용자가 쓴다면
미국 사용자 → 서울 ALB → 응답
응답이 너무 느리다. 매번 태평양을 왕복한다.
이걸 해결하는 도구가
Content Delivery Network (CDN)
이고 AWS의 CDN이
CloudFront
다.
CloudFront는 단순히 빠르게 만들어주는 것 이상으로
보안과 비용에도 영향을 주는 핵심 인프라다.
1. CDN이 하는 일
CDN의 아이디어는 단순하다.
자주 쓰이는 응답을 사용자 가까이에 미리 가져다 둔다
서울 origin → 1번만 가져온다
↓
[도쿄 엣지] [LA 엣지] [런던 엣지] [상파울루 엣지]
↓ ↓
일본 사용자 미국 사용자
같은 응답이라면 매번 origin까지 갈 필요가 없다.
엣지에 캐시된 응답이 직접 나간다.
이게 두 가지를 동시에 해결한다.
- 사용자 응답이 빠르다 (가까운 곳에서 응답)
- origin 부하가 줄어든다 (요청이 흡수됨)
2. CloudFront의 엣지 네트워크
AWS는 전 세계에 두 단계의 캐시 계층을 둔다.
[엣지 로케이션 (가장 가까운 곳)]
↑
[리전 엣지 캐시 (좀 더 큰 캐시)]
↑
[Origin (서울 ALB 등)]
- 엣지 로케이션 — 사용자에 가장 가까움. 수백 곳
- 리전 엣지 캐시 — 엣지 로케이션의 백업 캐시 역할
엣지에서 캐시 미스가 나면
바로 origin까지 가는 게 아니라
리전 엣지 캐시에서 한 번 더 확인한다.
같은 응답에 대해 origin 부담을 최소화하는 구조다
3. 요청은 어떻게 처리되는가
사용자가 https://example.com/image.png 를 요청하면
1. DNS → CloudFront의 가까운 엣지 응답
2. 엣지에서 image.png 가 캐시에 있나?
- 있다 → 즉시 응답 (Cache Hit)
- 없다 → 리전 엣지 캐시 확인
- 있다 → 가져와 응답
- 없다 → origin 까지 가서 가져오고 캐시
3. 다음 요청은 캐시에서 바로 응답
캐시 적중률(Cache Hit Ratio)이 높을수록
origin이 한가해지고 사용자가 빨라진다.
4. Origin — 어디에서 가져오는가
CloudFront 뒤에 둘 수 있는 origin은 여러 가지다.
- S3 — 정적 콘텐츠 (이미지, JS, CSS)
- ALB — 동적 서비스
- API Gateway — API 서비스
- Custom HTTP — 외부 서버 등
한 CloudFront 배포 안에 여러 origin을 두고
경로별로 다른 origin으로 보낼 수 있다.
/static/* → S3
/api/* → ALB
/* → S3 (SPA 호스팅)
이 부분은 다음 39장에서 자세히 다룬다.
5. 무엇을 캐시하는가
기본적으로 CloudFront는
- GET / HEAD 응답을 캐시한다
- 응답의
Cache-Control,Expires헤더와
CloudFront 자체의 TTL 설정을 함께 본다
POST · PUT · DELETE 같은 변경 요청은 캐시되지 않는다.
정적 자원 → 길게 캐시
동적 API → 짧거나 캐시 안 함
6. CloudFront가 보안에도 영향을 주는 이유
CloudFront를 앞에 두면 두 가지 보안 이점이 생긴다.
1. ALB · S3 를 노출하지 않을 수 있다
사용자 → CloudFront → (비공개) ALB / S3
S3에는 OAC, ALB에는 보안 그룹 + 헤더 검증으로
CloudFront만 통과시키는 구조를 만들 수 있다.
2. AWS Shield 표준 보호가 자동 적용된다
DDoS 공격이 origin까지 닿지 않고
CloudFront 단계에서 흡수된다.
WAF를 붙이면 한 단계 더 막을 수 있다. (40장에서 다룬다)
7. 우리 서비스에서
척추 그림에서 CloudFront 위치다.
[사용자]
↓ HTTPS (us-east-1 ACM)
[CloudFront] ← 여기
├─ /static/* → S3
└─ /* → ALB → ECS
- 정적 자원은 S3에서 직접 받아 캐시
- 동적 API는 ALB로 패스 (짧은 TTL 또는 캐시 비활성)
- HTTPS는 여기서 한 번 풀린다
- AWS Shield 기본 보호
8. 직접 확인해보기 — CLI
배포 목록 보기
aws cloudfront list-distributions
캐시 무효화 (Invalidation)
aws cloudfront create-invalidation \
--distribution-id E1234ABCD \
--paths "/static/*"
배포 후에 캐시를 강제로 비울 때 가장 자주 쓴다.
응답에서 캐시 적중 여부 확인
CloudFront는 응답 헤더에 다음을 넣어준다.
x-cache: Hit from cloudfront
x-cache: Miss from cloudfront
curl -I 로 헤더를 보면 캐시 동작을 바로 알 수 있다.
9. 코드로는 이렇게 생겼다 — Terraform
ALB를 origin으로 한 가장 작은 배포다.
resource "aws_cloudfront_distribution" "main" {
enabled = true
is_ipv6_enabled = true
aliases = ["api.example.com"]
origin {
domain_name = aws_lb.main.dns_name
origin_id = "alb-origin"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "https-only"
origin_ssl_protocols = ["TLSv1.2"]
}
}
default_cache_behavior {
target_origin_id = "alb-origin"
viewer_protocol_policy = "redirect-to-https"
allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
cached_methods = ["GET", "HEAD"]
cache_policy_id = "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" # CachingDisabled (동적 API용)
}
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.us_east.arn
ssl_support_method = "sni-only"
}
restrictions {
geo_restriction { restriction_type = "none" }
}
}
viewer_certificate.acm_certificate_arn 은
반드시 us-east-1 에서 발급한 인증서를 가리켜야 한다.
10. 이렇게 쓰면 망한다 — 안티패턴
안티패턴 1. 동적 API 응답을 길게 캐시한다
/api/me → 24시간 캐시
다른 사용자가 내 정보로 응답을 받을 수 있다.
인증된 응답은 캐시하지 않거나 Cache Key에 사용자 단위 필드를 넣는다
안티패턴 2. 캐시 무효화에 의존한다
매 배포마다 /* invalidation을 거는 방식.
- invalidation은 비용이 든다 (월 무료 한도 초과 시)
- 즉시 반영되지 않는다 (수 분 ~ 수십 분)
파일명에 해시(
app.a3f2c.js)를 박아 새 파일로 배포한다
그러면 invalidation 없이 신버전이 즉시 적용된다
안티패턴 3. CloudFront 없이 S3를 정적 호스팅으로 공개한다
S3 static website hosting → 그대로 노출
- HTTPS가 약하다
- DDoS 보호가 없다
- 캐시가 없어 속도가 느리다
정적 콘텐츠는 S3 + CloudFront 조합이 표준
안티패턴 4. Cache Key에 쓸데없는 헤더를 다 넣는다
User-Agent, Accept-Language, Cookie 같은 걸
Cache Key에 다 넣으면 캐시가 사실상 동작하지 않는다.
Cache Key는 응답을 정말로 바꾸는 헤더만 포함한다
11. 한 줄로 정리
CloudFront는 응답을 사용자 가까이에 캐시해
속도 · 비용 · 보안을 동시에 개선하는 엣지 계층이다
12. 이 장의 핵심 정리
- CloudFront는 AWS의 CDN으로 엣지 로케이션에 응답을 캐시한다.
- 엣지 → 리전 엣지 캐시 → origin 의 2단 캐시 구조를 가진다.
- origin에 S3 · ALB · API Gateway 등을 둘 수 있고, 경로별로 다르게 보낼 수 있다.
- 캐시 키 · TTL · Cache-Control 설정이 캐시 적중률을 결정한다.
- 인증된 동적 응답은 캐시하지 않도록 정책을 분리한다.
- CloudFront에 붙일 인증서는 us-east-1에서 발급한다.