이번에는 aws 서비스인 s3와 cloudfront를 활용하여 정적 웹을 배포하는 방법을 살펴보겠다.
s3와 cloudfront를 활용하여 배포를 시작해보자.
나는 기존의 토이 프로젝트를 netilfy로 배포하여 발생한 이슈가 있었기때문에 해당 방법으로 배포해보려한다.
나의 프로젝트의 경우 리액트로 만든 프로젝트이다.
Amazon S3(Amazon Simple Storage Service)는 AWS에서 제공하는 객체 스토리지(Object Storage) 서비스이다.
쉽게 말해, 인터넷을 통해 파일을 저장하고 가져올 수 있는 클라우드 저장소이다.
S3를 객체 스토리지 서비스라고 하였는데, 우리가 생각하는 객체에 파일 관련 여러 정보를 담는다고 생각하면 된다.
객체
파일을 URL을 통해 접근 가능
S3의 제일 큰 특징이라고 볼 수 있다.
HTTP 요청으로 직접 접근 가능하다는 것인데 이를 통해 여러 클라이언트에서 파일에 접근할 수 있게 된다.
정적 웹사이트 배포
파일을 업로드하여 여러 클라이언트가 URL을 통해 접근할 수 있게 한다는 것을 생각해보면 정적 웹사이트를 배포할 수 있다는 것이다.
이러한 접근성으로 우리는 React와 같은 앱을 S3에 올려 배포를 할 수 있는 것이다.
정적 웹사이트
정적 웹사이트(Static Website) 는 서버에서 동적으로 HTML을 생성하는 것이 아니라, 미리 만들어진 HTML, CSS, JavaScript 파일을 클라이언트(브라우저)에게 그대로 제공하는 웹사이트
자, 이제 그럼 간단히 S3에 대해 알아봤으니 바로 S3를 생성하러 가보자.
해외 서비스를 하지않고 국내 서비스를 한다면 서울 리전으로 선택해주면 된다.
ACL 비활성화됨(권장
)을 선택해준다.ACL(Access Control List)
ACL(Access Control List) 는 S3 버킷과 객체(파일)에 대한 접근 권한을 설정하는 기능이다.
즉, 누가 어떤 파일에 대해 어떤 권한을 가지는지를 지정하는 방식이다.
ACL 비활성화됨(권장)
ACL 활성화됨
파일 업로드를 하면 해당 데이터가 aws disk에 저장이 될텐데 특정키를 통해 이를 암호화하여 저장을 하고 불러올 때에는 해당 키를 통해 복호화한다.
아래 이미지처럼(기본으로 선택되어있는 옵션임) 선택되어있는 옵션은 키관리와 암호화,복호화를 알아서 관리해주는 옵션이다.
버킷이 성공적으로 생성되었다.
버킷의 정적 웹 호스팅 설정은 다음과 같이 속성 탭에서 확인할 수 있다.
하지만 나는 cloudfront를 통하여 호스팅할 것이기 때문에 비활성화인채로 두겠다.
만약 cloudfront를 사용하지않고 s3만을 통해 호스팅한다면 이를 활성화시켜주면 끝이다.
이제 리액트로 빌드한 정적 파일을 s3에 업로드해보자.
빌드 디렉터리에 있는 정적 파일들을 업로드해준다.
조금의 시간 뒤 잘 업로드되었다.
위 생성된 버킷에 파일을 업로드하여 반환받는 URL에 접근하면 다음과 같이 접근할 수 없다.
이유는 위에서 해보았듯이 퍼블릭 엑세스를 차단 설정해놓았기때문이다.
때문에 아무나 S3 객체에 접근하지 못한다.
퍼블릭 엑세스 차단 설정을 해지하지않고 객체를 퍼블릭하게 접근하게 하기 위해서는 CloudFront를 사용하면 된다.
Amazon CloudFront는 AWS에서 제공하는 CDN(Content Delivery Network, 콘텐츠 전송 네트워크) 서비스이다. 즉, 전 세계 여러 위치(엣지 로케이션, Edge Location)에 캐시 서버를 배포하여, 사용자에게 더 빠르고 안정적으로 콘텐츠를 제공하는 서비스이다.
CloudFront의 특징은 여러가지가 있다.
이 중에 위에서 언급했듯이 CloudFront를 사용하면 S3 버킷을 퍼블릭으로 공개하지 않고도 정적 파일을 제공 가능하다.
S3를 원본(origin)으로 설정하고, CloudFront를 통해서만 접근하도록 설정하면 보안 강화를 할 수 있다.
CloudFront 특징은 간략히 다음과 같다.
1. 성능 최적화 (전 세계 어디서든 빠른 로딩)
2. 대량 트래픽 처리 (확장성 + DDoS 보호)
3. S3와 연계하여 보안 강화 (S3 퍼블릭 차단 가능)
4. HTTPS 및 사용자 인증 (SSL/TLS 자동 지원)
이제 s3에 업로드된 정적 파일을 cloudfront를 통해 배포해보자.
프리티어면 다음과 같은 조건하에 서비스를 이용할 수 있다.
CloudFront 배포 생성 버튼을 누른다.
원본 도메인 선택
원본 도메인에서 방금 내가 만든 s3 버킷에 대한 도메인을 선택한다.
S3 버킷 엑세스
s3 버킷에 접근 권한을 설정하는 부분인데 cloudfront에서만 접근할 수 있게 할 것이므로 원본 엑세스 제어 설정(권장)
을 선택해주고 제어 설정 생성을 해준다
OAC(Origin Access Control)-제어 설정
OAC (Origin Access Control) 는 CloudFront가 S3에 안전하게 접근할 수 있도록 설정하는 기능이다.
창이 띄워진 위 이미지처럼 아무 옵션을 건드리지않고 생성해주면 된다.
서명 요청이란 CloudFront => S3로 접근시 서명을 통해 접근한다는 것이다.
보안성을 위함이다.
예
를 선택함으로써 활성화해준다.Origin Shield(오리진 실드) 는 CloudFront에서 제공하는 추가적인 캐싱 계층으로, 원본 서버(S3)에 대한 부하를 줄이는 역할을 한다.
- CloudFront의 엣지 로케이션 → Regional Edge Cache → “Origin Shield” → S3
Redirect Http to Https
를 선택해준다.자동으로 객체 압축
Gzip, Brotli 압축을 사용하여 HTML, CSS, JavaScript 파일 크기를 줄여 성능 최적화한다.
React 정적 웹사이트 배포 시 여러 파일을 올릴 것이기에 체크해놓는게 좋다.
허용된 HTTP 방법
Get,Head 옵션을 선택하자.
정적 웹사이트 배포가 목적이기에 Get이외에 다른 HTTP Method는 필요없다.
뷰어 액세스 제한
공개된 정적 웹사이트라면 No로 설정하자.
그래야 사용자들이 접근가능하다.
캐시 키 및 원본 요청
이 부분 또한 recommended
로 선택되어있는 부분을 선택해준다.
그리고 제어 설정 생성
을 누른 뒤 생성
버튼을 눌러준다.
웹 애플리케이션 방화벽(WAF)
AWS WAF(Web Application Firewall)는 웹 애플리케이션을 보호하는 방화벽 서비스로, 악의적인 트래픽을 차단하고 웹 공격으로부터 보호하는 기능을 제공한다.
SQL 인젝션, XSS(크로스 사이트 스크립팅) 등 일반적인 웹 공격 차단해준다.
나는 1천만 요청에 14달러니 활성해주겠다.
설정
설정 옵션 중에 여러가지 옵션이 있는데 이 중 기본값 루트 객체-선택 사항
이 부분에만 index.html
을 입력해준다.
나머지 옵션은 기본으로 선택되어있는 상태로 선택해준다.
기본 루트로 접속하였을 때 index.html을 자동으로 반환해주기 위하여!
배포 생성
이제 배포생성 버튼을 통해 해주자.
생성하고 난뒤 다음과 같은 메시지가 나타났다.
cloudfront에서 s3에 접근하게 하기 위해서는 s3 정책을 업데이트를 해줘야한다고 한다.
정책 복사버튼을 누른 뒤 s3로 이동하여 버킷 정책을 업데이트해주자.
s3로 이동한 뒤 권한 탭으로 이동한다.
그리고 버킷 정책에서 편집 버튼을 눌러준다.
아까 복사한 정책을 붙여넣어준다.
이제 변경 사항을 저장해준다.
이제 다시 cloudfront로 가서 배포된 uri를 확인해보자.
잘 접속되는 것을 확인할 수 있다.
만약 유저가 index.html이 아닌 다른 페이지를 실수로 요청한다 했을 때 index.html로 리다이렉트해주도록 해보자.
우선 cloudfront에서 오류 페이지 탭으로 이동한 뒤 사용자 정의 오류 응답 생성을 클릭한다.
http오류 코드는 403을 선택해주고 오류 페이지가 요청이 왔을 때 사용자에게 다시 index.html을 응답해주도록 설정한다.
아래와 같이 오류 응답 사용자 정의에서 예
를 체크해주고 응답 페이지 경로에는 /index.html
을 입력해준다.
Http 응답 코드는 200
을 선택해준다.
url에 다른 페이지를 입력하여도 index.html을 잘 응답해주고 있다.
이상으로 s3와 cloudfront를 통하여 리액트 프로젝트를 배포하는 방법을 살펴봤다.
나의 경우 이전에 해당 프로젝트를 netlify를 통해 배포하였는데 이미지 로딩이 느린 이슈가 있었다.
서버와의 물리적 거리 때문이다.
netlify는 한국에 서버를 두고 있지 않다.
이러한 이슈가 있기도 하고 프론트 서버를 배포하는 법을 살펴보고 있기도 하여 s3,cloudfront를 활용하여 호스팅해보았다.
결과적으로 이전보다 이미지가 매우 빨리 로딩되는 만족스러운 결과를 얻었다.