CloudFront 및 AWS Global Accelerator

silver's avatar
Nov 20, 2025
CloudFront 및 AWS Global Accelerator
웹사이트와 애플리케이션의 성능을 전 세계적으로 향상시키는 두 가지 핵심 서비스
:1. CloudFront는 콘텐츠를 엣지 로케이션에 캐싱하고 2. Global Accelerator는 AWS 글로벌 네트워크를 통해 트래픽을 최적화한다

CloudFront

CloudFront는 AWS의 CDN(Content Delivery Network) 서비스로, 전 세계 450개 이상의 엣지 로케이션에서 콘텐츠를 제공
사용자 (서울) ↓ 요청 엣지 로케이션 (서울) ↓ 캐시 미스 오리진 (버지니아) ↓ 콘텐츠 반환 엣지 로케이션 (캐싱) ↓ 빠른 응답 사용자 두 번째 요청: 사용자 → 엣지 (캐시 히트) → 즉시 반환

주요 장점

1. 성능 향상
  • 지연 시간 감소 (평균 50-90% 감소)
  • 엣지 로케이션에서 즉시 제공
  • 오리진 서버 부하 감소
2. 글로벌 배포
  • 450+ 엣지 로케이션
  • 자동 라우팅
  • 지역별 최적화
3. 보안
  • DDoS 보호 (AWS Shield Standard 포함)
  • HTTPS 지원
  • 지리적 제한
  • AWS WAF 통합
4. 비용 효율
  • 데이터 전송 비용 절감
  • 오리진 부하 감소
  • 프리 티어: 월 50GB 데이터 전송

CloudFront vs 직접 배포

직접 S3 배포: 서울 사용자 → 버지니아 S3 - 지연시간: 200-300ms - 비용: 높음 (리전 간 전송) CloudFront: 서울 사용자 → 서울 엣지 → (캐시 히트) 즉시 반환 - 지연시간: 10-20ms (95% 감소) - 비용: 낮음 (엣지에서 처리)

비용 최적화

CloudFront 비용 구조

데이터 전송 (가장 큰 비용):
리전별 가격 (per GB): - 북미, 유럽: $0.085 - 아시아 (일본 제외): $0.140 - 남미: $0.250 - 오스트레일리아: $0.170 프리 티어: - 월 50GB 데이터 전송 - 월 2백만 HTTP/HTTPS 요청
요청:
HTTP/HTTPS: - $0.0075 ~ $0.0100 / 10,000 요청 HTTPS 요청 (추가): - $0.0100 / 10,000 요청 Invalidation: - 처음 1,000개/월: 무료 - 이후: $0.005/개

절감 전략

1. Price Class 조정

# 서비스 지역이 북미/유럽이면 aws cloudfront update-distribution \ --id E1234567890ABC \ --price-class PriceClass_100 # 절감: 약 20-30%

2. Compression 활성화

# Gzip/Brotli 압축 활성화 aws cloudfront update-distribution \ --id E1234567890ABC \ --distribution-config '{ "DefaultCacheBehavior": { "Compress": true } }' # 효과: 데이터 전송량 70-90% 감소
예시:
압축 전: - app.js: 500KB × 1,000,000 요청 = 500GB - 비용: 500GB × $0.085 = $42.50 압축 후: - app.js: 100KB (80% 압축) × 1,000,000 = 100GB - 비용: 100GB × $0.085 = $8.50 - 절감: $34.00 (80%)

3. 캐시 최적화

캐시 히트율 향상: 60% → 90% 효과: - 오리진 요청: 40% → 10% (75% 감소) - 오리진 비용: $100 → $25 - 지연시간: 100ms → 10ms

4. Lambda@Edge 대신 CloudFront Functions

Lambda@Edge: - $0.60 / 백만 요청 - $0.00001667 / GB-초 CloudFront Functions: - $0.10 / 백만 요청 - 추가 컴퓨팅 비용 없음 절감: 83%

5. Origin Shield

중간 캐싱 레이어를 추가하여 오리진 부하를 줄인다.
Origin Shield 없음: 450+ 엣지 → 오리진 (많은 요청) Origin Shield 사용: 450+ 엣지 → Origin Shield (1곳) → 오리진 └─ 오리진 요청 90% 감소
비용:
Origin Shield: $0.005 / 10,000 요청 오리진 비용 절감: $0.020 / 10,000 요청 순 절감: $0.015 / 10,000 요청
aws cloudfront update-distribution \ --id E1234567890ABC \ --distribution-config '{ "Origins": { "Items": [{ "Id": "S3-my-bucket", "DomainName": "my-bucket.s3.amazonaws.com", "OriginShield": { "Enabled": true, "OriginShieldRegion": "us-east-1" } }] } }'

보안 모범 사례

1. HTTPS 강제

// CloudFront Function function handler(event) { var request = event.request; if (request.headers['cloudfront-forwarded-proto'] && request.headers['cloudfront-forwarded-proto'].value === 'http') { return { statusCode: 301, statusDescription: 'Moved Permanently', headers: { 'location': { value: 'https://' + request.headers.host.value + request.uri } } }; } return request; }

2. 보안 헤더 추가

function handler(event) { var response = event.response; var headers = response.headers; // Security headers headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload' }; headers['content-security-policy'] = { value: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" }; headers['x-content-type-options'] = { value: 'nosniff' }; headers['x-frame-options'] = { value: 'DENY' }; headers['x-xss-protection'] = { value: '1; mode=block' }; headers['referrer-policy'] = { value: 'strict-origin-when-cross-origin' }; headers['permissions-policy'] = { value: 'geolocation=(), microphone=(), camera=()' }; return response; }

3. AWS WAF 통합

# WAF WebACL 생성 aws wafv2 create-web-acl \ --name my-waf-acl \ --scope CLOUDFRONT \ --default-action Allow={} \ --rules file://waf-rules.json # CloudFront에 연결 aws cloudfront update-distribution \ --id E1234567890ABC \ --web-acl-id arn:aws:wafv2:us-east-1:account-id:global/webacl/my-waf-acl/id
WAF 규칙 예시:
{ "Rules": [ { "Name": "RateLimitRule", "Priority": 1, "Statement": { "RateBasedStatement": { "Limit": 2000, "AggregateKeyType": "IP" } }, "Action": { "Block": {} } }, { "Name": "SQLInjectionRule", "Priority": 2, "Statement": { "SqliMatchStatement": { "FieldToMatch": { "QueryString": {} }, "TextTransformations": [{ "Priority": 0, "Type": "URL_DECODE" }] } }, "Action": { "Block": {} } }, { "Name": "GeoBlockRule", "Priority": 3, "Statement": { "GeoMatchStatement": { "CountryCodes": ["CN", "RU"] } }, "Action": { "Block": {} } } ] }

4. Signed URLs/Cookies (프리미엄 콘텐츠)

Signed URL 생성:
import boto3 from datetime import datetime, timedelta from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding from botocore.signers import CloudFrontSigner import base64 def rsa_signer(message): with open('private_key.pem', 'rb') as key_file: private_key = serialization.load_pem_private_key( key_file.read(), password=None ) return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1()) # CloudFront Signer 생성 cf_signer = CloudFrontSigner('APKAEIBAERJR2EXAMPLE', rsa_signer) # Signed URL 생성 url = 'https://d111111abcdef8.cloudfront.net/premium-video.mp4' expire_date = datetime.now() + timedelta(hours=1) signed_url = cf_signer.generate_presigned_url( url, date_less_than=expire_date ) print(signed_url)
Signed Cookie 생성:
policy = { "Statement": [{ "Resource": "https://d111111abcdef8.cloudfront.net/premium/*", "Condition": { "DateLessThan": { "AWS:EpochTime": int((datetime.now() + timedelta(hours=24)).timestamp()) } } }] } signed_cookies = cf_signer.generate_presigned_cookie( url, date_less_than=expire_date ) # 쿠키 설정 # CloudFront-Policy=... # CloudFront-Signature=... # CloudFront-Key-Pair-Id=...

트러블슈팅

문제 1: 504 Gateway Timeout

원인:
  • 오리진 응답 느림 (>30초)
  • 오리진 서버 다운
해결:
# 1. 오리진 타임아웃 확인 aws cloudfront get-distribution-config --id E1234567890ABC \ | jq '.DistributionConfig.Origins.Items[0].CustomOriginConfig.OriginReadTimeout' # 2. 타임아웃 증가 (최대 60초) aws cloudfront update-distribution \ --id E1234567890ABC \ --distribution-config '{ "Origins": { "Items": [{ "CustomOriginConfig": { "OriginReadTimeout": 60 } }] } }' # 3. 오리진 헬스 체크 curl -I https://origin-server.example.com/health

문제 2: 캐시가 업데이트되지 않음

원인:
  • 긴 TTL
  • 잘못된 Cache-Control 헤더
해결:
# 1. 즉시 무효화 aws cloudfront create-invalidation \ --distribution-id E1234567890ABC \ --paths "/*" # 2. 오리진 헤더 확인 curl -I https://d111111abcdef8.cloudfront.net/index.html # 3. Cache-Control 헤더 수정 aws s3api copy-object \ --bucket my-bucket \ --key index.html \ --copy-source my-bucket/index.html \ --metadata-directive REPLACE \ --cache-control "max-age=3600" \ --content-type "text/html"

문제 3: CORS 에러

원인:
  • 오리진에 CORS 헤더 없음
  • CloudFront가 CORS 헤더를 캐시하지 않음
해결:
# 1. Origin Request Policy 생성 aws cloudfront create-origin-request-policy \ --origin-request-policy-config '{ "Name": "CORS-Policy", "HeadersConfig": { "HeaderBehavior": "whitelist", "Headers": { "Items": ["Origin", "Access-Control-Request-Headers", "Access-Control-Request-Method"] } } }' # 2. Response Headers Policy 생성 aws cloudfront create-response-headers-policy \ --response-headers-policy-config '{ "Name": "CORS-Headers", "CorsConfig": { "AccessControlAllowOrigins": { "Items": ["https://example.com"] }, "AccessControlAllowHeaders": { "Items": ["*"] }, "AccessControlAllowMethods": { "Items": ["GET", "POST", "OPTIONS"] }, "AccessControlAllowCredentials": false, "OriginOverride": true } }'

문제 4: 높은 비용

원인:
  • 불필요한 엣지 로케이션
  • 낮은 캐시 히트율
  • 압축 미사용
해결:
# 1. 캐시 히트율 확인 aws cloudwatch get-metric-statistics \ --namespace AWS/CloudFront \ --metric-name CacheHitRate \ --dimensions Name=DistributionId,Value=E1234567890ABC \ --start-time 2024-11-01T00:00:00Z \ --end-time 2024-11-19T23:59:59Z \ --period 86400 \ --statistics Average # 2. Price Class 변경 aws cloudfront update-distribution \ --id E1234567890ABC \ --price-class PriceClass_100 # 3. Compression 활성화 aws cloudfront update-distribution \ --id E1234567890ABC \ --distribution-config '{"DefaultCacheBehavior": {"Compress": true}}' # 4. Origin Shield 활성화 aws cloudfront update-distribution \ --id E1234567890ABC \ --distribution-config '{ "Origins": { "Items": [{ "OriginShield": { "Enabled": true, "OriginShieldRegion": "us-east-1" } }] } }'

실전 프로젝트: 완전한 정적 웹사이트 배포

1단계: S3 버킷 및 콘텐츠 준비

# 버킷 생성 aws s3 mb s3://my-website-bucket # 웹사이트 파일 업로드 aws s3 sync ./build/ s3://my-website-bucket/ \ --cache-control "max-age=31536000" \ --exclude "*.html" \ --exclude "service-worker.js" # HTML 파일 (짧은 캐시) aws s3 sync ./build/ s3://my-website-bucket/ \ --cache-control "max-age=3600" \ --exclude "*" \ --include "*.html"

2단계: CloudFront 배포 생성

aws cloudfront create-distribution \ --origin-domain-name my-website-bucket.s3.amazonaws.com \ --default-root-object index.html \ --distribution-config file://distribution-config.json
distribution-config.json:
{ "CallerReference": "my-website-2024", "Origins": { "Quantity": 1, "Items": [{ "Id": "S3-my-website", "DomainName": "my-website-bucket.s3.amazonaws.com", "S3OriginConfig": { "OriginAccessIdentity": "" }, "OriginShield": { "Enabled": true, "OriginShieldRegion": "us-east-1" } }] }, "DefaultCacheBehavior": { "TargetOriginId": "S3-my-website", "ViewerProtocolPolicy": "redirect-to-https", "Compress": true, "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6" }, "CustomErrorResponses": { "Quantity": 1, "Items": [{ "ErrorCode": 404, "ResponsePagePath": "/index.html", "ResponseCode": "200", "ErrorCachingMinTTL": 300 }] }, "Comment": "My Website CDN", "Enabled": true }

3단계: Route 53 도메인 연결

# ACM 인증서 요청 (us-east-1에서!) aws acm request-certificate \ --domain-name example.com \ --subject-alternative-names www.example.com \ --validation-method DNS \ --region us-east-1 # CloudFront에 도메인 및 인증서 추가 aws cloudfront update-distribution \ --id E1234567890ABC \ --distribution-config file://distribution-with-domain.json # Route 53 레코드 생성 aws route53 change-resource-record-sets \ --hosted-zone-id Z1234567890ABC \ --change-batch file://dns-records.json
dns-records.json:
{ "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "example.com", "Type": "A", "AliasTarget": { "HostedZoneId": "Z2FDTNDATAQYW2", "DNSName": "d111111abcdef8.cloudfront.net", "EvaluateTargetHealth": false } } }, { "Action": "CREATE", "ResourceRecordSet": { "Name": "www.example.com", "Type": "A", "AliasTarget": { "HostedZoneId": "Z2FDTNDATAQYW2", "DNSName": "d111111abcdef8.cloudfront.net", "EvaluateTargetHealth": false } } } ] }

4단계: 보안 강화

// CloudFront Function: 보안 헤더 function handler(event) { var response = event.response; var headers = response.headers; headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload' }; headers['content-security-policy'] = { value: "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://api.example.com" }; headers['x-content-type-options'] = { value: 'nosniff' }; headers['x-frame-options'] = { value: 'DENY' }; headers['x-xss-protection'] = { value: '1; mode=block' }; headers['referrer-policy'] = { value: 'strict-origin-when-cross-origin' }; return response; }

5단계: CI/CD 파이프라인

# GitHub Actions name: Deploy to CloudFront on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Build run: | npm install npm run build - name: Deploy to S3 run: | aws s3 sync build/ s3://my-website-bucket/ \ --delete \ --cache-control "max-age=31536000" \ --exclude "*.html" aws s3 sync build/ s3://my-website-bucket/ \ --cache-control "max-age=3600" \ --exclude "*" \ --include "*.html" env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: us-east-1 - name: Invalidate CloudFront run: | aws cloudfront create-invalidation \ --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} \ --paths "/*"

마치며

CloudFront와 Global Accelerator는 글로벌 애플리케이션의 성능과 가용성을 극대화하는 강력한 도구
핵심 요약:
CloudFront:
  • 정적/동적 콘텐츠 캐싱 및 배포
  • 450+ 엣지 로케이션
  • S3, ALB, 커스텀 오리진 지원
  • Lambda@Edge/CloudFront Functions로 엣지 컴퓨팅
  • 보안: HTTPS, Signed URLs, WAF, Geo Restriction
  • 비용 최적화: Compression, Origin Shield, Price Class
Global Accelerator:
  • TCP/UDP 트래픽 가속화
  • 고정 Anycast IP
  • AWS 백본 네트워크 사용
  • 게임, IoT, VoIP에 최적
  • Health Check 및 자동 장애 조치
선택 가이드:
  • HTTP/HTTPS 콘텐츠 → CloudFront
  • TCP/UDP 애플리케이션 → Global Accelerator
  • 정적 웹사이트 → CloudFront + S3
  • 동적 웹앱 → CloudFront + ALB
  • 실시간 게임 → Global Accelerator + NLB
다음 단계로 AWS WAF, Shield, GuardDuty 등 보안 서비스를 학습하여 더욱 안전한 인프라를 구축해보세요! 🚀CloudFront와 S3 통합

기본 설정

1. S3 버킷 생성 및 콘텐츠 업로드

# 버킷 생성 aws s3 mb s3://my-static-website # 웹사이트 파일 업로드 aws s3 sync ./website/ s3://my-static-website/

2. CloudFront 배포 생성

aws cloudfront create-distribution \ --origin-domain-name my-static-website.s3.amazonaws.com \ --default-root-object index.html
콘솔 설정:
Origin Settings: - Origin Domain: my-static-website.s3.amazonaws.com - Origin Path: / (선택) - Origin Access: Origin Access Control (OAC) - 권장 Default Cache Behavior: - Viewer Protocol Policy: Redirect HTTP to HTTPS - Allowed HTTP Methods: GET, HEAD - Cache Policy: CachingOptimized Distribution Settings: - Price Class: Use All Edge Locations - Alternate Domain Names (CNAMEs): www.example.com - SSL Certificate: Custom SSL certificate (ACM) - Default Root Object: index.html

3. Origin Access Control (OAC) 설정

OAC 생성:
aws cloudfront create-origin-access-control \ --origin-access-control-config '{ "Name": "my-oac", "Description": "OAC for S3 origin", "SigningProtocol": "sigv4", "SigningBehavior": "always", "OriginAccessControlOriginType": "s3" }'
S3 버킷 정책 업데이트:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCloudFrontServicePrincipal", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::my-static-website/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/E1234567890ABC" } } } ] }
보안 비교:
❌ Public S3 (권장하지 않음): 인터넷 → S3 (누구나 접근 가능) ✅ OAC (권장): 인터넷 → CloudFront S3 └─ S3CloudFront만 접근 허용

CloudFront 고급 기능

1. 지리적 제한 (Geo Restriction)

특정 국가에서의 접근을 허용하거나 차단
aws cloudfront update-distribution \ --id E1234567890ABC \ --distribution-config '{ "Restrictions": { "GeoRestriction": { "RestrictionType": "whitelist", "Quantity": 2, "Items": ["US", "KR"] } } }'
사용 사례:
  • 라이선스 제한 (예: 한국에서만 서비스)
  • 저작권 보호
  • 규제 준수
Whitelist (허용 목록): - US, KR만 허용 - 기타 국가: 403 Forbidden Blacklist (차단 목록): - CN, RU 차단 - 기타 국가: 허용

2. Price Classes (요금 클래스)

사용할 엣지 로케이션을 제한하여 비용을 절감
옵션:
Price Class All (기본)
  • 모든 엣지 로케이션 (450+)
  • 최상의 성능
  • 가장 비쌈
Price Class 200
  • 북미, 유럽, 아시아, 중동, 아프리카
  • 남미 제외
  • 중간 가격
Price Class 100
  • 북미, 유럽만
  • 가장 저렴
  • 제한된 커버리지
aws cloudfront update-distribution \ --id E1234567890ABC \ --price-class PriceClass_200
비용 비교:
Price Class All: $0.085/GB (아시아-태평양) Price Class 200: $0.085/GB (동일) Price Class 100: $0.085/GB → 사용 불가 (미국/유럽만)

3. Cache Invalidation (캐시 무효화)

배포된 콘텐츠를 즉시 업데이트합니다.
# 단일 파일 무효화 aws cloudfront create-invalidation \ --distribution-id E1234567890ABC \ --paths /index.html # 폴더 전체 무효화 aws cloudfront create-invalidation \ --distribution-id E1234567890ABC \ --paths /images/* # 모든 파일 무효화 aws cloudfront create-invalidation \ --distribution-id E1234567890ABC \ --paths /*
비용:
  • 월 1,000개 무료
  • 이후: $0.005/개
모범 사례:
❌ 나쁜 예: 자주 무효화 - 콘텐츠 변경할 때마다 무효화 - 비용 증가 ✅ 좋은 예: 버전 관리 - 파일 이름에 버전 포함 - style.css → style.v2.css - 무효화 불필요
즉시 업데이트 전략:
# 버전 기반 배포 import boto3 import hashlib import time s3 = boto3.client('s3') def upload_with_version(file_path, bucket, key_prefix): # 파일 해시로 버전 생성 with open(file_path, 'rb') as f: content = f.read() version = hashlib.md5(content).hexdigest()[:8] # 버전이 포함된 키 versioned_key = f"{key_prefix}.{version}.js" # 업로드 s3.put_object( Bucket=bucket, Key=versioned_key, Body=content, CacheControl='max-age=31536000' # 1년 ) return versioned_key # 사용 new_script = upload_with_version('app.js', 'my-bucket', 'js/app') print(f"New version: {new_script}") # → js/app.a3b5c7d9.js

CloudFront와 ALB 통합

아키텍처

사용자 ↓ [CloudFront] ├─ 정적 콘텐츠 (S3 Origin) │ └─ /assets/* → S3 └─ 동적 콘텐츠 (ALB Origin) └─ /api/* → ALB → EC2

설정

1. ALB를 오리진으로 추가

aws cloudfront create-distribution \ --distribution-config '{ "Origins": { "Items": [ { "Id": "S3-my-bucket", "DomainName": "my-bucket.s3.amazonaws.com", "S3OriginConfig": { "OriginAccessIdentity": "" } }, { "Id": "ALB-my-app", "DomainName": "my-alb-123456789.us-east-1.elb.amazonaws.com", "CustomOriginConfig": { "HTTPPort": 80, "HTTPSPort": 443, "OriginProtocolPolicy": "https-only" } } ] }, "CacheBehaviors": { "Items": [ { "PathPattern": "/api/*", "TargetOriginId": "ALB-my-app", "ViewerProtocolPolicy": "redirect-to-https", "CachePolicyId": "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" } ] } }'

2. 캐시 동작 (Cache Behavior) 설정

기본 동작 (Default): - Origin: S3 - Path: /* - Cache: Enabled (긴 TTL) 추가 동작 #1: - Origin: ALB - Path: /api/* - Cache: Disabled (동적 콘텐츠) 추가 동작 #2: - Origin: S3 - Path: /images/* - Cache: Enabled (매우 긴 TTL)

캐시 정책

CachingOptimized (정적 콘텐츠)
TTL: - Minimum: 1초 - Maximum: 31,536,000초 (1년) - Default: 86,400초 (1일) 캐시 키: - Query strings: None - Headers: None - Cookies: None
CachingDisabled (동적 콘텐츠)
TTL: 0 (캐싱 안 함) 모든 요청을 오리진으로 전달
커스텀 캐시 정책
{ "Name": "CustomCachePolicy", "MinTTL": 0, "MaxTTL": 31536000, "DefaultTTL": 86400, "ParametersInCacheKeyAndForwardedToOrigin": { "EnableAcceptEncodingGzip": true, "EnableAcceptEncodingBrotli": true, "QueryStringsConfig": { "QueryStringBehavior": "whitelist", "QueryStrings": { "Items": ["page", "sort"] } }, "HeadersConfig": { "HeaderBehavior": "whitelist", "Headers": { "Items": ["Accept-Language", "CloudFront-Viewer-Country"] } }, "CookiesConfig": { "CookieBehavior": "none" } } }

CloudFront Functions vs Lambda@Edge

비교

특성
CloudFront Functions
Lambda@Edge
실행 위치
엣지 로케이션 (모든 PoP)
리전별 엣지 로케이션
지연 시간
1ms 미만
5-10ms
최대 실행 시간
1ms
5초 (viewer), 30초 (origin)
메모리
2MB
128MB ~ 10GB
패키지 크기
10KB
50MB
가격
매우 저렴 ($0.10/100만 요청)
비쌈 ($0.60/100만 요청)
네트워크 액세스
불가
가능
파일 시스템
불가
불가
사용 사례
간단한 변환
복잡한 로직

CloudFront Functions 예시

1. 헤더 추가

function handler(event) { var response = event.response; var headers = response.headers; // 보안 헤더 추가 headers['strict-transport-security'] = { value: 'max-age=63072000' }; headers['x-content-type-options'] = { value: 'nosniff' }; headers['x-frame-options'] = { value: 'DENY' }; headers['x-xss-protection'] = { value: '1; mode=block' }; return response; }

2. URL 리다이렉트

function handler(event) { var request = event.request; var uri = request.uri; // 디렉토리 접근 시 index.html 추가 if (uri.endsWith('/')) { request.uri += 'index.html'; } // 확장자 없는 경우 .html 추가 else if (!uri.includes('.')) { request.uri += '.html'; } return request; }

3. A/B 테스트

function handler(event) { var request = event.request; var headers = request.headers; var cookies = request.cookies; // 쿠키 확인 var testGroup = cookies['ab-test'] ? cookies['ab-test'].value : null; if (!testGroup) { // 랜덤 할당 testGroup = Math.random() < 0.5 ? 'A' : 'B'; } // URI 변경 if (testGroup === 'B') { request.uri = '/beta' + request.uri; } // 쿠키 설정 request.headers['set-cookie'] = { value: `ab-test=${testGroup}; Max-Age=86400; Path=/` }; return request; }

Lambda@Edge 예시

1. 이미지 리사이징

const AWS = require('aws-sdk'); const sharp = require('sharp'); const S3 = new AWS.S3(); exports.handler = async (event) => { const request = event.Records[0].cf.request; const response = event.Records[0].cf.response; // 리사이즈 파라미터 파싱 const params = new URLSearchParams(request.querystring); const width = parseInt(params.get('w')) || 800; // 원본 이미지 가져오기 const s3Object = await S3.getObject({ Bucket: 'my-images', Key: request.uri.substring(1) }).promise(); // 리사이징 const resized = await sharp(s3Object.Body) .resize(width) .toBuffer(); // 응답 생성 return { status: '200', headers: { 'content-type': [{ value: 'image/jpeg' }], 'cache-control': [{ value: 'max-age=31536000' }] }, body: resized.toString('base64'), bodyEncoding: 'base64' }; };

2. 인증 확인

const jwt = require('jsonwebtoken'); exports.handler = async (event) => { const request = event.Records[0].cf.request; const headers = request.headers; // Authorization 헤더 확인 const authHeader = headers.authorization && headers.authorization[0].value; if (!authHeader || !authHeader.startsWith('Bearer ')) { return { status: '401', statusDescription: 'Unauthorized', headers: { 'www-authenticate': [{ value: 'Bearer' }] } }; } const token = authHeader.substring(7); try { // JWT 검증 const decoded = jwt.verify(token, process.env.JWT_SECRET); // 사용자 정보를 커스텀 헤더로 전달 request.headers['x-user-id'] = [{ value: decoded.userId }]; request.headers['x-user-role'] = [{ value: decoded.role }]; return request; } catch (err) { return { status: '403', statusDescription: 'Forbidden', body: 'Invalid token' }; } };

3. 동적 콘텐츠 생성

exports.handler = async (event) => { const request = event.Records[0].cf.request; // 국가 정보 const country = request.headers['cloudfront-viewer-country'][0].value; // 동적 HTML 생성 const html = ` <!DOCTYPE html> <html> <head> <title>Welcome</title> </head> <body> <h1>Welcome from ${country}!</h1> <p>Your local time is: ${new Date().toLocaleString()}</p> </body> </html> `; return { status: '200', headers: { 'content-type': [{ value: 'text/html; charset=utf-8' }], 'cache-control': [{ value: 'no-cache' }] }, body: html }; };

AWS Global Accelerator

AWS의 글로벌 네트워크를 사용하여 애플리케이션의 가용성과 성능을 향상시킨다
CloudFront (캐싱): 사용자 → 엣지 (캐시 히트) → 즉시 반환 Global Accelerator (프록시): 사용자 → 엣지 → AWS 백본 → 애플리케이션 └─ 캐싱 없음, 모든 요청 전달

CloudFront vs Global Accelerator

특성
CloudFront
Global Accelerator
목적
콘텐츠 캐싱 및 배포
네트워크 성능 향상
프로토콜
HTTP/HTTPS
TCP/UDP
캐싱
있음
없음
IP
동적
고정 (Anycast)
사용 사례
정적/동적 웹 콘텐츠
게임, IoT, VoIP
가격
저렴
비쌈

Global Accelerator 구성

[Global Accelerator] ├─ Static IP: 1.2.3.4, 5.6.7.8 (Anycast) ├─ Endpoint Group (ap-northeast-2) │ ├─ ALB-1 (가중치: 70) │ └─ EC2-1 (가중치: 30) └─ Endpoint Group (us-east-1) ├─ ALB-2 (가중치: 100) └─ NLB-1 (가중치: 0)

설정

# Accelerator 생성 aws globalaccelerator create-accelerator \ --name my-accelerator \ --ip-address-type IPV4 \ --enabled # Listener 생성 aws globalaccelerator create-listener \ --accelerator-arn arn:aws:globalaccelerator::123456789012:accelerator/a1234567-89ab-cdef-0123-456789abcdef \ --port-ranges FromPort=80,ToPort=80 FromPort=443,ToPort=443 \ --protocol TCP # Endpoint Group 생성 aws globalaccelerator create-endpoint-group \ --listener-arn arn:aws:globalaccelerator::123456789012:listener/l1234567/89abcdef \ --endpoint-group-region ap-northeast-2 \ --endpoint-configurations \ EndpointId=arn:aws:elasticloadbalancing:ap-northeast-2:123456789012:loadbalancer/app/my-alb/50dc6c495c0c9188,Weight=100

주요 기능

1. Health Check

aws globalaccelerator update-endpoint-group \ --endpoint-group-arn arn:aws:globalaccelerator::account:accelerator/id/listener/id/endpoint-group/id \ --health-check-protocol HTTP \ --health-check-path /health \ --health-check-interval-seconds 30 \ --threshold-count 3

2. Traffic Dial (트래픽 다이얼)

엔드포인트 그룹으로 전송되는 트래픽 비율을 제어
# 트래픽 50%만 전송 (블루-그린 배포) aws globalaccelerator update-endpoint-group \ --endpoint-group-arn arn:... \ --traffic-dial-percentage 50
사용 예시:
배포 전: Traffic Dial 100% (구버전) 배포 중: Traffic Dial 50% (신버전 테스트) 확인 후: Traffic Dial 100% (신버전)

3. Client Affinity (클라이언트 선호도)

# 소스 IP 기반 라우팅 aws globalaccelerator update-endpoint-group \ --endpoint-group-arn arn:... \ --client-affinity SOURCE_IP
동작:
Client Affinity: None - 요청마다 다른 엔드포인트 가능 Client Affinity: SOURCE_IP - 동일 IP는 항상 같은 엔드포인트 - 세션 유지 필요한 애플리케이션

실전 사용 사례

사례 1: 글로벌 정적 웹사이트

아키텍처: [S3 Static Website] ↓ Origin [CloudFront] ├─ 450+ 엣지 로케이션 ├─ HTTPS (ACM 인증서) ├─ Geo Restriction (필요시) └─ Lambda@Edge (헤더 추가) ↓ [Route 53] └─ www.example.com → CloudFront 성능: - 서울 사용자: 10-20ms (엣지에서) - 뉴욕 사용자: 10-20ms (엣지에서) - 오리진 부하: 99% 감소 (캐시 히트율) 비용: - S3: $0.023/GB (저장) - CloudFront: $0.085/GB (전송) - 월 1TB 전송: ~$85 (직접 대비 60% 절감)

사례 2: 동적 웹 애플리케이션

[ALB] ├─ [EC2] AZ-A └─ [EC2] AZ-C ↓ Origin [CloudFront] ├─ /api/* → Cache: Disabled ├─ /assets/* → Cache: Enabled (1년) └─ /* → Cache: Enabled (1일) 설정: - Cache Policy: CachingDisabled (/api/*) - Origin Request Policy: AllViewer (/api/*) - Response Headers Policy: SecurityHeadersPolicy 보안: - AWS WAF (SQL Injection, XSS 차단) - AWS Shield (DDoS 보호) - Rate Limiting (1000 req/min)

사례 3: 게임 서버 (Global Accelerator)

이유: CloudFront 사용 불가 - TCP/UDP 프로토콜 - 실시간 통신 (캐싱 불가) - 낮은 지연시간 필수 아키텍처: [Global Accelerator] ├─ Static IP: 1.2.3.4, 5.6.7.8 ├─ 서울 리전 │ └─ NLB → EC2 (게임 서버) └─ 도쿄 리전 └─ NLB → EC2 (게임 서버) 성능 개선: - 공인 인터넷: 200ms 지연 - Global Accelerator: 50ms 지연 (75% 개선) - AWS 백본 사용으로 안정성 향상

사례 4: 하이브리드 (CloudFront + Global Accelerator)

[CloudFront] ← 정적 콘텐츠 (HTML, CSS, JS, 이미지) └─ S3 Origin [Global Accelerator] ← API 및 WebSocket ├─ ALB (REST API) └─ NLB (WebSocket) 클라이언트: - 페이지 로드: CloudFront에서 - API 호출: Global Accelerator로 - 실시간 통신: Global Accelerator (WebSocket)

모니터링 및 최적화

CloudWatch 지표

# 캐시 히트율 조회 aws cloudwatch get-metric-statistics \ --namespace AWS/CloudFront \ --metric-name CacheHitRate \ --dimensions Name=DistributionId,Value=E1234567890ABC \ --start-time 2024-11-19T00:00:00Z \ --end-time 2024-11-19T23:59:59Z \ --period 3600 \ --statistics Average
주요 지표:
  • CacheHitRate: 캐시 히트율 (목표: 80% 이상)
  • Requests: 총 요청 수
  • BytesDownloaded: 다운로드된 바이트
  • 4xxErrorRate: 클라이언트 에러율
  • 5xxErrorRate: 서버 에러율

캐시 최적화

낮은 캐시 히트율 원인: 1. Query String 변동 (?timestamp=123456) 2. Cookie 변동 3. 짧은 TTL 4. Vary 헤더 해결책: 1. Query String 화이트리스트 2. Cookie 화이트리스트 3. 적절한 TTL 설정 4. Cache-Control 헤더 최적화
Cache-Control 헤더:
정적 콘텐츠 (CSS, JS, 이미지): Cache-Control: public, max-age=31536000, immutable 동적 콘텐츠 (HTML): Cache-Control: public, max-age=3600, must-revalidate API 응답: Cache-Control: no-cache, no-store, must-revalidate

Share article

silver