반응형
왜 CloudFront 앞에 S3를 두나?
- S3는 원본 저장소, CloudFront는 글로벌 캐시 + TLS + WAF + 헤더정책 + 로그의 허브 역할.
- 버킷은 비공개로 두고, CloudFront만 읽게 하면 보안과 캐시 전략을 깔끔하게 가져갈 수 있어요(이때 OAC 권장).
“한 배포에 여러 서브도메인”은 가능할까?
가능합니다. 하나의 CloudFront 배포에 여러 개의 Alternate Domain Name(CNAME)(예: example.com, a.example.com, b.example.com …)을 등록할 수 있어요. 단, 같은 CNAME을 두 개 배포에 동시에 등록할 수는 없습니다(중복 불가).
TLS 인증서는 us-east-1(버지니아 북부) 의 ACM에 있어야 CloudFront에 붙일 수 있습니다(와일드카드 *.example.com 권장).
비헤이비어는 “호스트가 아니라 경로”로 매칭된다
CloudFront의 캐시 비헤이비어는 요청 경로 패턴으로 매칭됩니다. 즉, 같은 배포라면 a.example.com/images/*도, b.example.com/images/*도 동일한 /images/* 비헤이비어에 잡혀 같은 S3 오리진으로 라우팅돼요. 기본 비헤이비어는 *이며, 우선순위는 구체적인 경로가 이겨요.
URL·CORS 빠른 판단표
페이지 호스트이미지 호스트CORS 필요?비고
| a.example.com | a.example.com/images/* | X | 같은 오리진, 가장 단순 |
| a.example.com | example.com/images/* | 경우에 따라 O | <img> 표시는 대개 OK, JS fetch/Canvas/폰트는 CORS 헤더 필요 |
| a.example.com | img.example.com/* | 경우에 따라 O | 전용 배포·도메인(운영 분리) 시 CORS 고려 |
CORS가 필요하면 CloudFront의 Managed Response Headers Policy 중 CORS-With-Preflight를 붙이면 편합니다.
“같은 배포 + 경로 기반” vs “별도 배포 + 전용 호스트”
- 같은 배포 + /images/* 비헤이비어(권장 기본값)
- 장점: 운영 단순(인증서/배포/Route53 하나), CORS無(같은 호스트 사용 시)
- 주의: 앱과 이미지가 같은 WAF/무효화 단위. 쿠키 스코프를 a.example.com로 좁혀 이미지 요청에 쿠키가 실리는 것을 피하세요.
- 별도 배포 + img.example.com
- 장점: 캐시 정책/TTL/무효화/로그/WAF/가격대를 완전 분리
- 주의: 초기 설정 조금 더 손이 감, 교차 출처(CORS) 고려 필요
보안 기본기(필수 체크리스트)
- S3 버킷 비공개 + Block Public Access ON.
- CloudFront OAC로 S3 읽기 권한 부여(버킷 정책에서 CloudFront 배포 ARN 기준으로 허용). OAC가 현재 권장입니다.
- 인증서는 ACM(us-east-1), 도메인은 Alternate Domain에 등록, Route53 에일리어스 A 레코드로 배포를 가리키기.
- 웹 방어가 필요하면 CloudFront에 AWS WAF 연결(앱/이미지 모두 보호).
캐시·성능·운영 팁
- 호스트별로 다른 컨텐츠를 같은 경로에 둘 계획이라면(예: a.example.com/images/x.png와 b.example.com/images/x.png가 서로 다름) → 캐시 키에 Host 헤더를 포함한 커스텀 Cache Policy를 써야 충돌이 없습니다.
- 무효화는 비용·지연이 있으니, 가능하면 파일명 버저닝(해시/버전 디렉터리)을 쓰세요. AWS도 버전드 파일명 사용을 권장합니다.
Terraform 예시(요지)
1) OAC + S3 버킷 정책
resource "aws_cloudfront_origin_access_control" "oac_images" {
name = "oac-images"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
# S3 버킷은 비공개 + BPA ON 가정
data "aws_iam_policy_document" "bucket_policy" {
statement {
sid = "AllowCFviaOAC"
principals { type = "Service", identifiers = ["cloudfront.amazonaws.com"] }
actions = ["s3:GetObject"]
resources = ["${aws_s3_bucket.images.arn}/*"]
condition {
test = "StringEquals"
variable = "AWS:SourceArn"
values = [aws_cloudfront_distribution.app.arn]
}
}
}
resource "aws_s3_bucket_policy" "images" {
bucket = aws_s3_bucket.images.id
policy = data.aws_iam_policy_document.bucket_policy.json
}
S3 접근은 해당 배포 ARN에서 오는 요청만 허용하도록 제한합니다(OAC 방식).
2) 같은 배포에 S3 오리진 + /images/* 비헤이비어 추가
resource "aws_cloudfront_distribution" "app" {
# 기존: ALB/EKS 오리진을 default_cache_behavior 로 사용 중이라고 가정
aliases = ["example.com", "a.example.com", "b.example.com", "c.example.com"] # 이미 보유
origins {
origin_id = "s3-images"
domain_name = aws_s3_bucket.images.bucket_regional_domain_name
origin_access_control_id = aws_cloudfront_origin_access_control.oac_images.id
}
ordered_cache_behavior {
path_pattern = "/images/*"
target_origin_id = "s3-images"
viewer_protocol_policy = "redirect-to-https"
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
cache_policy_id = data.aws_cloudfront_cache_policy.caching_optimized.id
# CORS 필요 시 응답헤더 정책 연결(Managed)
# response_headers_policy_id = data.aws_cloudfront_response_headers_policy.cors_with_preflight.id
compress = true
}
# ... default_cache_behavior 등 기존 설정 유지 ...
}
경로 패턴으로 라우팅되며, 배포에 연결된 모든 서브도메인에 동일하게 적용됩니다.
3) (옵션) CORS가 필요할 때: Managed 정책 사용
data "aws_cloudfront_response_headers_policy" "cors_with_preflight" {
name = "Managed-CORS-With-Preflight"
}
CloudFront의 Managed CORS 정책을 그대로 활용하면 예측 가능하고 편합니다.
운영 체크리스트
- ACM(us-east-1) 인증서에 모든 호스트(example.com, a.example.com …)가 포함되는지 확인.
- 같은 CNAME을 다른 배포에 중복 등록 불가 — 배포 이동 시 먼저 연결 해제 또는 associate-alias 절차를 쓰세요.
- WAF 연결로 공통 보안(봇/SQLi/XSS 등) 적용.
- 이미지 경로는 버전드 URL을 쓰고, 대규모 갱신 시엔 무효화 범위를 /images/*로 최소화.
- 캐시 키에 Host 포함 여부를 요구사항에 맞게 결정(여러 서브도메인이 같은 경로·이름으로 다른 컨텐츠를 갖는 경우만 포함).
자주 받는 질문(FAQ)
Q. 비헤이비어를 하나만 추가하면 모든 서브도메인에 적용되나요?
A. 네. 같은 배포에 들어오는 요청이라면, 경로 패턴 기준으로 매칭되어 모두 적용됩니다
반응형
'CLOUD > AWS' 카테고리의 다른 글
| CORS “보여주기 vs 읽기”, 프리플라이트, S3·CloudFront 정리 (1) | 2025.08.28 |
|---|---|
| [AWS IAM] 사용자에게 S3 전체 버킷 조회 + 객체 Get/Put/Delete 권한 부여하기 (1) | 2025.08.26 |
| AWS CloudFront 대체 도메인(Alternate Domain Names)와 Route 53 A 레코드 정리 (0) | 2025.08.20 |
| AWS Route 53 도메인에 SSL 인증서 발급 및 여러 리전 관리 방법 (0) | 2025.08.14 |
| AWS VPC에서 OpenVPN 스플릿 터널 구성 & 트러블슈팅 (2) | 2025.08.14 |
댓글