DEVOPS

AWS S3 + CloudFront 정적 사이트 배포법

junetapa 2026. 2. 23 8 min read

정적 사이트를 배포하는 방법은 많지만, 가격 대비 성능과 제어권에서 AWS S3 + CloudFront 조합은 압도적이다. 버킷 설정부터 CDN 배포, 캐싱 정책, 비용 비교까지 실전 경험을 바탕으로 정리했다.

왜 AWS S3 + CloudFront 조합인가

정적 사이트를 배포하는 방법은 정말 많다. Netlify, Vercel, GitHub Pages 모두 좋은 서비스다. 그런데 AWS S3와 CloudFront 조합을 고집하는 이유가 있다. 한마디로 가격 대비 성능과 제어권이 압도적이다.

AWS S3는 아마존의 오브젝트 스토리지 서비스인데, 단순히 파일 저장소가 아니라 정적 웹사이트 호스팅 기능을 기본 내장하고 있다. 여기에 CloudFront라는 글로벌 CDN을 앞에 붙이면, 전 세계 어디서든 빠른 응답 속도를 보장하면서도 월 비용이 몇백 원~수천 원 수준에 불과하다. 트래픽이 폭증해도 자동으로 스케일링되니까 서버 다운 걱정도 없다.

S3 + CloudFront가 특별한 3가지 이유

  • 글로벌 엣지 로케이션: CloudFront는 전 세계 400개 이상의 엣지 로케이션을 보유하고 있어서, 한국 사용자든 미국 사용자든 가장 가까운 서버에서 콘텐츠를 받아간다.
  • 무제한 확장성: EC2처럼 서버 사양을 고민할 필요가 없다. 하루 방문자가 100명이든 100만 명이든 S3와 CloudFront가 알아서 처리한다.
  • 완전한 인프라 제어: 커스텀 도메인, HTTPS 인증서, 캐싱 정책, 접근 제어, Lambda@Edge 함수까지 배포 파이프라인의 모든 요소를 직접 컨트롤할 수 있다.

비용은 정말 저렴할까

솔직히 말하면, 무료 플랜이 있는 Netlify나 Vercel과 비교하면 "공짜"는 아니다. 하지만 AWS 프리 티어 기준으로 S3 5GB 저장 + CloudFront 1TB 전송이 1년간 무료이고, 프리 티어 이후에도 일반적인 블로그나 포트폴리오 사이트라면 월 $0.5~$2 수준이다. 커피 한 잔 값도 안 되는 비용으로 엔터프라이즈급 CDN 배포 인프라를 갖출 수 있다.

AWS S3 버킷 설정 - 정적 사이트 호스팅

S3 버킷 생성

AWS 콘솔에 로그인한 뒤 S3 서비스로 이동한다. "버킷 만들기"를 클릭하고, 버킷 이름은 사용할 도메인과 동일하게 설정하는 것을 추천한다. 예를 들어 www.mysite.com이라면 버킷 이름도 www.mysite.com으로. 리전은 서울(ap-northeast-2)을 선택하면 된다.

중요한 포인트가 하나 있는데, 버킷 생성 시 "이 버킷의 퍼블릭 액세스 차단 설정"에서 모든 퍼블릭 액세스를 차단해 둬야 한다. "웹사이트인데 퍼블릭 차단하면 어떻게 접근하냐"고 생각할 수 있는데, CloudFront의 OAC(Origin Access Control)를 통해서만 접근을 허용할 거라서 S3 자체는 직접 노출시키지 않는 게 보안상 훨씬 안전하다.

정적 웹사이트 호스팅 활성화

버킷의 "속성" 탭으로 가서 맨 아래 "정적 웹사이트 호스팅"을 활성화한다. 인덱스 문서는 index.html, 오류 문서도 index.html(SPA인 경우) 또는 404.html을 지정한다. 이 설정만으로 S3가 웹서버 역할을 시작한다.

파일 업로드와 폴더 구조

빌드된 정적 파일(HTML, CSS, JS, 이미지 등)을 버킷에 업로드한다. AWS CLI를 사용하면 훨씬 편하다.

AWS CLI aws s3 sync ./dist s3://www.mysite.com --delete

--delete 옵션은 로컬에서 삭제된 파일을 S3에서도 삭제해주는 플래그다. 배포 자동화할 때 특히 유용하다. GitHub Actions와 연동하면 push 한 번으로 자동 배포가 가능하다.

CloudFront CDN 배포 설정

CloudFront 배포 생성하기

CloudFront 콘솔에서 "배포 생성"을 클릭한다. 원본(Origin)으로 방금 만든 S3 버킷을 선택한다. 여기서 핵심은 OAC(Origin Access Control) 설정이다. "Origin access" 항목에서 "Origin access control settings"를 선택하고, 새 OAC를 생성한다. 이렇게 하면 CloudFront만 S3에 접근할 수 있고, 직접 S3 URL로는 접근이 불가능해진다.

뷰어 프로토콜 정책은 "Redirect HTTP to HTTPS"로 설정해서 모든 트래픽이 HTTPS를 거치도록 한다. 가격 등급은 "북미, 유럽, 아시아, 중동, 아프리카"까지 선택하면 충분하고, 기본 루트 객체에 index.html을 입력한다.

커스텀 도메인 & HTTPS 인증서

AWS Certificate Manager(ACM)에서 반드시 us-east-1(버지니아) 리전에서 SSL 인증서를 발급받아야 한다. CloudFront는 글로벌 서비스라서 버지니아 리전의 인증서만 사용할 수 있다. 이거 모르면 "인증서가 안 보여요" 하면서 30분을 날린다.

인증서 발급 후 Route 53에서 도메인의 A 레코드를 CloudFront 배포로 가리키면 끝이다. DNS 전파까지 보통 5~10분이면 완료되고, 이후부터는 커스텀 도메인으로 HTTPS 접속이 가능하다.

캐싱 정책 - CDN 배포의 핵심

CloudFront의 진짜 가치는 캐싱에 있다. 기본 캐싱 정책(CachingOptimized)을 적용하면 대부분의 정적 파일이 엣지 로케이션에 캐시된다. 하지만 배포 후 변경사항이 바로 반영되지 않는 문제가 생길 수 있다.

해결법은 캐시 무효화(Invalidation)다. 배포할 때마다 다음 명령어를 실행하면 된다.

AWS CLI aws cloudfront create-invalidation --distribution-id EXXXXX --paths "/*"

또는 더 효율적인 방법으로, CSS/JS 파일에 해시 기반 파일명(app.3a7b2c.js)을 사용하고 index.html만 캐시 TTL을 짧게 설정하는 전략이 있다. 이러면 무효화 요청 없이도 항상 최신 버전이 제공된다.

장단점 비교 - 다른 배포 방식과 뭐가 다를까

주요 정적 사이트 배포 방식 비교

항목 AWS S3 + CloudFront Netlify / Vercel EC2 + Nginx
초기 설정 난이도 중간 (AWS 콘솔 익숙해야 함) 매우 쉬움 (Git 연결만) 어려움 (서버 직접 관리)
월 비용 (소규모) $0.5~$2 무료~$20 $5~$15
CDN 성능 최상급 (400+ 엣지) 우수 별도 CDN 필요
커스텀 설정 자유도 매우 높음 제한적 매우 높음
자동 확장 무제한 자동 플랜에 따라 제한 수동 스케일링
HTTPS 설정 ACM 무료 인증서 자동 (Let's Encrypt) 직접 설정
배포 자동화 AWS CLI + CI/CD 구성 Git push 자동 배포 직접 스크립트 작성
추천 대상 AWS 이미 사용 중인 팀, 대규모 트래픽 개인 프로젝트, 빠른 프로토타이핑 서버 사이드 로직 필요 시

솔직한 장단점 정리

장점
  • 서버리스 아키텍처라 서버 관리가 아예 필요 없음
  • 트래픽 폭증에도 자동 대응 - 슬래시닷 효과도 거뜬
  • AWS 생태계(Route 53, ACM, Lambda@Edge, WAF)와 긴밀한 연동
  • 글로벌 CDN 배포로 어디서든 빠른 로딩 속도
  • 종량제 과금이라 트래픽 없으면 비용도 거의 제로
단점
  • 초기 설정이 Netlify/Vercel 대비 복잡함 (첫 세팅에 30분~1시간)
  • AWS 콘솔 UX가 직관적이지 않아서 처음엔 헤맬 수 있음
  • 캐시 무효화에 최대 10~15분 소요될 수 있음
  • IAM 권한 설정이 번거로움 (최소 권한 원칙 지키려면 특히)

실전 운영 팁 & 추천 대상

반드시 알아야 할 실전 팁 5가지

Tip 1

S3 버킷 정책은 OAC 전용으로 제한하라. CloudFront 배포를 만들면 자동으로 버킷 정책 JSON이 제안된다. 이걸 그대로 복사해서 S3 버킷 정책에 붙여넣기만 하면 된다. 절대 "Principal": "*" 같은 퍼블릭 정책을 쓰지 말 것. S3 URL이 직접 노출되면 CloudFront 캐시를 우회해서 비용이 폭증할 수 있다.

Tip 2

GitHub Actions로 배포를 완전 자동화하라. main 브랜치에 push할 때마다 자동으로 S3 동기화 + CloudFront 무효화가 실행되도록 워크플로를 구성하면, 로컬에서 AWS CLI를 실행할 필요가 전혀 없다. OIDC 연동을 사용하면 IAM 액세스 키 없이도 안전하게 배포할 수 있다.

Tip 3

에러 페이지를 CloudFront 레벨에서 설정하라. SPA(React, Vue 등)를 배포할 때 새로고침하면 403/404 에러가 나는 문제가 있다. CloudFront의 "오류 페이지" 설정에서 403과 404 에러 모두 /index.html로 리다이렉트(HTTP 200)하도록 설정하면 깔끔하게 해결된다.

Tip 4

CloudFront Functions로 URL 정규화를 처리하라. /about으로 접속하면 S3에서 파일을 못 찾는 경우가 있다. CloudFront Functions에서 뷰어 요청 이벤트를 가로채서 /about/about/index.html로 변환해주는 짧은 함수를 연결하면 된다. Lambda@Edge보다 훨씬 빠르고 저렴하다.

Tip 5

배포 전 로컬 테스트를 습관화하라. aws s3 sync 전에 --dryrun 플래그로 어떤 파일이 업로드/삭제되는지 먼저 확인하라. 실수로 중요한 파일을 덮어쓰거나 삭제하는 사고를 예방할 수 있다.

추천 대상

  • 이미 AWS를 사용 중인 팀: 기존 AWS 인프라와 자연스럽게 통합되고, 통합 빌링으로 비용 관리가 편하다.
  • 트래픽 예측이 어려운 프로젝트: 바이럴 콘텐츠, 이벤트 페이지 등 갑자기 트래픽이 폭증할 수 있는 사이트에 최적이다.
  • 인프라를 직접 컨트롤하고 싶은 개발자: 캐싱 정책, 보안 헤더, URL 리라이트 등 세밀한 제어가 필요하다면 AWS S3 + CloudFront가 정답이다.
  • 글로벌 서비스를 운영하는 경우: CloudFront의 400개 이상 엣지 로케이션 덕분에 CDN 배포 성능이 어떤 서비스와 비교해도 뒤지지 않는다.

마무리

AWS S3와 CloudFront를 이용한 정적 사이트 배포는 처음 설정이 조금 번거롭지만, 한번 세팅해두면 이후로는 정말 편하다. 특히 GitHub Actions와 연동하면 git push 한 번으로 빌드부터 CDN 배포, 캐시 무효화까지 전부 자동으로 처리된다. 월 비용도 커피 한 잔 값이면 충분하고, 성능은 엔터프라이즈급이다. AWS 생태계에 이미 발을 담그고 있다면, 다음 정적 사이트는 S3 + CloudFront 조합으로 배포해보길 강력 추천한다.

AWS S3 CloudFront CDN 배포 정적 사이트 DevOps
junetapa
junetapa
AI 도구를 직접 써보고 솔직한 경험을 공유하는 개발자.
Twitter Facebook URL 복사