서로 다른 AWS 계정에서 CloudFront ↔ S3 안전하게 연동하기

JH.KIM·2025년 7월 15일
post-thumbnail

📌 들어가며

콘텐츠를 전 세계에 빠르게 배포하기 위해 AWS CloudFront(CDN)를 자주 사용합니다.
그런데 CloudFront가 속한 계정(A)실제 정적 파일을 담은 S3 버킷이 있는 계정(B) 이 서로 다를 때가 있죠.

  • 보안 격리

    • 팀·조직·고객사 별로 S3를 분리해 두고, 공용 CloudFront 계정에서만 CDN 비용을 관리하고 싶다.
  • 운영 분리

    • 스토리지를 담당하는 인프라팀(계정 B)과, 퍼블리싱을 담당하는 플랫폼팀(계정 A)이 구분돼 있다.
  • 재무/청구 분리

    • 대규모 SaaS에서 고객별 S3 비용은 고객 계정에, CDN 비용은 서비스 계정에 귀속시키고 싶다.

이때 Origin Access Control(OAC)S3 버킷 정책을 조합하면 퍼블릭 URL을 전혀 공개하지 않으면서 계정 간 안전하게 연동할 수 있습니다.
아래 글에서는 실제 콘솔 단계, 정책 샘플, Prefix(경로) 처리 등 실무 팁까지 모두 다룹니다.


1️⃣ 연동 개요

1‑1. 구성 요소

역할계정서비스비고
CDN, 캐싱ACloudFrontOAC 서명 사용
정적 파일 저장BAmazon S3버킷 정책으로 CloudFront만 허용

1‑2. 동작 흐름도

[User or Browser]
        │
        │ HTTP/HTTPS
        ▼
[CloudFront (Origin Access Control)]
        │
        │ SigV4 Signed Request
        ▼
(S3 Bucket - Account B)
        ▲
        │
        │ Object
        ▼
[CloudFront (Cache)]
        ▲
        │
        │ Cached Content
        ▼
[User or Browser]
  • SigV4: CloudFront가 요청 시 OAC로 서명(Signature Version 4)
  • Public Access: S3는 Block Public Access 설정 ON

2️⃣ OAC 설정

2‑1. OAC란?

OAI(구 방식)OAC(신 방식)
서명 방식Canonical User IDSigV4 (IAM‑like)
리전 제약Global리전별 지정
관리 편의성중간콘솔·CLI 모두 직관적
미래 지향성단계적 폐지 예정신규 서비스 권장

2‑2. OAC 생성하기

  1. CloudFront 콘솔Distributions → 대상 배포 선택

  2. OriginsCreate origin

  3. Origin domain: my-bucket.s3.ap-northeast-2.amazonaws.com (계정 B 버킷엔드포인트)

  4. Origin access control settingsCreate control

    • Signing behavior: Sign requests
    • Signing protocol: SigV4
    • Origin type: Amazon S3
    • Signing region: ap-northeast-2 (버킷 리전)
  5. 저장 후, Access control 칸에 방금 만든 OAC 선택 → Create origin
    `

2‑3. Distribution에 연결하기

  • 기존 Origin이라면 EditOrigin access control → OAC 선택
  • 변경 후 Deploy 를 눌러 배포 업데이트

3️⃣ S3 버킷 정책 구성

모든 퍼블릭 액세스 차단(Block Public Access) = ON 상태를 전제로!

3‑1. 단일 OAC 허용 예시

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"AllowCloudFrontOAC",
      "Effect":"Allow",
      "Principal":{"Service":"cloudfront.amazonaws.com"},
      "Action":"s3:GetObject",
      "Resource":"arn:aws:s3:::my-bucket/*",
      "Condition":{
        "StringEquals":{
          "AWS:SourceArn":"arn:aws:cloudfront::123456789012:origin-access-control/ocontrol/EXAMPLE",
          "AWS:SourceAccount":"123456789012"
        }
      }
    }
  ]
}
  • Principal: cloudfront.amazonaws.com (서비스 주체)
  • AWS\:SourceArn: OAC ARN (ocontrol/…)
  • AWS\:SourceAccount: CloudFront 배포가 속한 계정 ID

3‑2. 다건 OAC 허용 방법

  1. 배포마다 Statement 분리
  2. 또는 SourceArn 배열 사용
"Condition":{
  "StringEquals":{
    "AWS:SourceArn":[
      "arn:aws:cloudfront::123456789012:origin-access-control/ocontrol/AAA111",
      "arn:aws:cloudfront::123456789012:origin-access-control/ocontrol/BBB222"
    ],
    "AWS:SourceAccount":"123456789012"
  }
}

4️⃣ Origin Path 활용하기

4‑1. Origin Path란?

CloudFront → Origin 요청 시 자동으로 붙는 고정 Prefix

  • Viewer URL에는 표시되지 않음
  • S3 객체 Key(namespacing) 만으로 스테이지·환경 분리 가능

4‑2. 설정 예시

Origin PathViewer 요청Origin 요청 (S3)
(빈 값)/logo.png/logo.png
/assets/logo.png/assets/logo.png
/review/img/a.jpg/review/img/a.jpg

4‑3. 주의사항

  • 반드시 /로 시작 · 끝 슬래시 필요 없음
  • Prefix 제거(Strip)는 Origin Path만으로 불가 → CloudFront Function 사용

5️⃣ URL Prefix 처리 – CloudFront Function

5‑1. 필요 시나리오

  • Viewer URL: /review/... 유지
  • Origin URL: /... (Prefix 제거)
    → e.g. SEO·라우팅 통일, 리팩터링 중 단계적 이전 등

5‑2. Viewer Request Function 예시

function handler(event) {
  var req = event.request;
  // "/review" 앞부분 제거
  req.uri = req.uri.replace(/^\/review/, '') || '/';
  return req;
}
  • Associations

    • Event type: Viewer request
    • Behavior: /review/* 또는 Default (*)

5‑3. 배포 및 Behavior 연결 절차

  1. CloudFront FunctionsCreate function → 코드 입력

  2. BuildPublish

  3. 배포의 BehaviorsEditFunction associations → Viewer request에 붙이기

  4. Deploy 후 테스트

    • curl -I https://d123.cloudfront.net/review/test.txt
    • S3 로그에서 /test.txt 로 접근되는지 확인

✍️ 마무리하며

  • OAC 는 Cross‑Account일 때도 강력한 최소 권한 모델을 제공합니다.
  • S3는 Block Public Access ON + Bucket Policy 로 CloudFront만 허용 → 퍼블릭 URL 노출 없음.
  • Origin Path 로 환경·폴더를 논리적으로 분리하고, 필요하다면 CloudFront Function 으로 URI를 유연하게 조작하세요.
  • 캐싱 정책(Cache Policy)·WAF·TLS 암호화까지 함께 고려하면 보다 탄탄한 글로벌 콘텐츠 배포 아키텍처를 구축할 수 있습니다.

참고 자료 & 공식 문서

profile
일하며 겪은 문제를 나눠요

0개의 댓글