1. 도입부: "왜 S3 단독 배포가 아닌 CloudFront인가?"
React 프로젝트 빌드 파일을 S3에 올리고 '정적 웹 사이트 호스팅'을 켜는 것만으로도 배포는 가능합니다. 하지만 'Control Tower'와 같은 SaaS 서비스를 운영하기에는 다음과 같은 한계가 있었습니다.
- 보안 이슈: S3 단독 호스팅은 HTTP만 지원하여 데이터 전송 시 보안에 취약합니다.
- 속도 문제: 특정 리전에만 데이터가 존재하여 글로벌 사용자에게 일관된 속도를 제공하기 어렵습니다.
- 비용과 효율: 데이터 전송료(Data Transfer Out)와 캐싱 부재로 인한 비효율이 발생합니다.
이를 해결하기 위해 **CloudFront(CDN)**를 결합하여 HTTPS 보안과 글로벌 캐싱 성능을 동시에 확보했습니다.
2. 아키텍처 설계 및 서비스별 역할
- Amazon S3: 정적 파일(Build Artifacts)의 안전한 저장소 역할을 합니다.
- Amazon CloudFront: 전 세계 엣지 로케이션을 통해 콘텐츠를 캐싱하고 HTTPS 게이트웨이 역할을 수행합니다.
- ACM (Certificate Manager): SSL/TLS 인증서를 관리합니다.
- Route 53: 도메인 연결 및 DNS를 관리합니다.
3. 실전 구축 프로세스 (핵심 요약)
🔒 S3 & OAC 설정
버킷을 퍼블릭으로 열어두는 것은 보안상 매우 위험합니다. 저는 OAC(Origin Access Control) 설정을 통해 오직 CloudFront를 통해서만 S3 버킷에 접근할 수 있도록 권한을 제한했습니다.
🔑 ACM 인증서 리전 팁
CloudFront에 커스텀 도메인과 HTTPS를 적용하려면 인증서가 필요합니다. 여기서 주의할 점은 CloudFront가 글로벌 서비스이기 때문에 인증서는 반드시 버지니아 북부(us-east-1) 리전에서 발급받아야만 목록에 나타난다는 것입니다.
4. 💡 Deep Dive: 트러블슈팅 경험
🛠 SPA 404 Error 해결
React Router와 같은 CSR 기반 라이브러리를 사용하면 /login 같은 경로로 직접 접속할 때 S3에는 해당 경로의 실제 파일이 없으므로 404 에러가 발생합니다.
- 해결: CloudFront의 Error Pages 설정에서 403/404 발생 시 응답 페이지를 /index.html로 리다이렉트하고 상태 코드를 200으로 반환하게 설정하여 해결했습니다.
🔄 CloudFront Invalidation (캐시 무효화)
코드 수정 후 S3에 업로드해도 바로 반영되지 않는 문제가 있었습니다. 이는 CDN의 캐시 정책 때문입니다.
- 해결: 배포 시마다 /* 경로로 Invalidation 처리를 해주어 전 세계 엣지의 캐시를 초기화하고 최신 코드가 즉시 반영되도록 구현했습니다.
✨ 마치며
이번 AWS 정적 배포 과정을 통해 단순한 코드 작성을 넘어, '어떻게 하면 사용자에게 더 안전하고 빠르게 서비스를 전달할 수 있을까?'를 고민하는 인프라적 시야를 가질 수 있었습니다. 특히 OAC를 활용한 보안 강화와 SPA 라우팅 이슈 해결은 실제 배포 환경에서 겪을 수 있는 값진 경험이었습니다.
'Projects > Team Projects' 카테고리의 다른 글
| [Control Tower] 개발 및 운영 회고 (0) | 2026.03.14 |
|---|---|
| [Control Tower]Spring Boot + AWS RDS + Nginx 배포기: 삽질하며 배운 인프라의 중요성 (0) | 2026.03.07 |
| [Control Tower] Spring AI로 구현한 항공사 사원 가입 자동화 (명함 OCR & 프롬프트 엔지니어링) (0) | 2026.03.07 |
| [Control Tower] Spring AI(Gemini)로 근태 증빙서류 자동 완성(OCR) 구현하기 🚀 (Zero-Click UX 적용기) (0) | 2026.02.12 |
| [Control Tower] 2차 개발 구현 계획(Spring Ai & OCR) (0) | 2026.02.11 |