CloudFront의 프리티어 전송량이 훨씬 크기 때문에 S3만 단독으로 사용해서 배포하는 것보다 CloudFront를 같이 사용하는 것이 좋다. 속도도 더 빠르다.
S3와 CloudFront를 사용한 정적 웹사이트 배포
원본 도메인에서 정적 웹사이트를 업로드해둔 S3로 선택해준다.
S3는 퍼블릭 액세스를 제한하고, CloudFront로만 하는 것이 바람직하기 때문에 “원본 액세스 제어 설정(권장)“을 선택해준다. 아래 Origin access control에서 제어 설정이 존재하지 않는 경우 기본값으로 하나 생성해주면 된다.
S3 버킷에서 CloudFront의 접근만 허용해야 한다. 위에 보이는대로 정책 복사해서 그대로 붙여넣어주기만 하면 된다.
S3에서 정적 웹사이트를 배포할 때는 인덱스 문서를 설정할 수 있고 리다이렉션 규칙도 지정할 수 있지만 CloudFront에서는 따로 대처해야 한다.
이 문제를 해결하는 몇몇 방법이 있다.
CloudFront Functions를 사용한 라우팅
Gatsby로 만든 정적 웹사이트는 웹페이지 경로마다 index.html 파일이 각각 생성된다. 따라서 웹페이지 접근 요청에 대해서 index.html을 붙여주는 처리가 필요하다.
functionhandler(event) {
varrequest=event.request;
varuri=request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith("/")) {
request.uri+="index.html";
}
// Check whether the URI is missing a file extension.
elseif (!uri.includes(".")) {
request.uri+="/index.html";
}
returnrequest;
}
필요한 작업은 단순히 요청 URL을 검사한 다음 필요한 경우 index.html을 붙여주는 전처리를 추가하는 것이다. Lambda를 사용할 수도 있지만 CloudFront Functions를 쓰는 것이 비용이나 속도 면에서 유리하다. (람다는 100만 회당 0.6달러, Functions는 200만회까지 무료, 초과시 100만회당 0.1달러)
위 스크린샷 예시처럼 함수를 추가하고 연결해주면 된다.
여기서는 Gatsby로 빌드한 정적 웹사이트를 배포했다. Gatsby가 빌드한 결과는 웹페이지마다 index.html 파일을 각각 생성하는 규칙을 갖고 있기 때문에 위와 같은 방법을 사용했다. Next.js를 사용하는 경우는 Gatsby와 디렉토리 구조가 다르기 때문에 거기 맞춰서 처리해주면 된다. url이 /로 끝나거나 또는 확장자를 포함한 파일명이 존재하지 않는 경우, 경로 뒤에 .html 확장자를 붙여주도록 함수를 변경해주면 충분하다.