Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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. 이 장의 핵심 정리

  1. CloudFront는 AWS의 CDN으로 엣지 로케이션에 응답을 캐시한다.
  2. 엣지 → 리전 엣지 캐시 → origin 의 2단 캐시 구조를 가진다.
  3. origin에 S3 · ALB · API Gateway 등을 둘 수 있고, 경로별로 다르게 보낼 수 있다.
  4. 캐시 키 · TTL · Cache-Control 설정이 캐시 적중률을 결정한다.
  5. 인증된 동적 응답은 캐시하지 않도록 정책을 분리한다.
  6. CloudFront에 붙일 인증서는 us-east-1에서 발급한다.