intro : s3와 cloudfront를 활용한 웹 페이지 배포하는 방법에 대해서 알아보자.
S3는 파일 저장 서비스 아닌가?
이전글에서 S3는 파일을 저장하는 서비스라고 정의하였었다. 사실 S3는 의외의 부가적인 기능을 보유하고 있는데 바로 정적 웹 사이트 호스팅 기능이다. 쉽게 표현하자면 웹 서비스를 다른 사용자들도 쓸 수 있게 인터넷에 배포하는 것을 말한다.
CloudFront란?
컨텐츠(파일, 동영상 등)를 빠르게 전송하게 해주는 서비스이다. AWS의 Cloud Front 서비스가 어떻게 컨텐츠를 빠르게 전송해 주는지 아래 이미지를 통해 작동 과정을 눈으로 확인해보자.
이미지와 같은 정적 파일을 로드할 때, CDN(Content Delivery Network)
를 사용하기 전에는 원본 서버(Origin Server)로부터 물리적으로 거리가 먼 사용자는 파일을 로드하는 데 상당한 시간이 걸릴 수 있다. 이는 네트워크 지연(latency) 때문이다. AWS EC2 인스턴스 생성 시 리전을 한국(서울)으로 설정하는 이유도 같은 맥락이다. 서버와 사용자 간의 물리적 거리가 가까울수록 네트워크 지연이 줄어들고, 응답 속도가 빨라져 사용자 경험이 향상된다. 따라서, CDN은 전 세계 여러 지역에 캐시 서버를 두어 사용자와 가까운 서버에서 콘텐츠를 제공함으로써 이런 문제를 효과적으로 해결할 수 있는 중요한 역할을 하는데 그게바로 AWS의 Cloud Front
이다.
S3 + CloudFront 조합을 사용하는 이유
S3만으로도 웹페이지를 배포하는 것은 충분히 가능하다. 그렇다면 왜 S3 + CloudFront 조합을 사용하는 걸까? 그 이유는 CloudFront가 콘텐츠 전송 성능을 크게 향상시키기 때문이다. 전 세계 여러 엣지 로케이션(Edge Location)을 통해 사용자와 가까운 서버에서 콘텐츠를 제공하여 지연(latency)을 줄이고, 응답 속도를 개선할 수 있다. 또한, HTTPS를 적용하려면 CloudFront를 사용하는 것이 더 간편하고 효과적다. S3 자체로도 HTTPS를 구성할 수 있지만, 추가적인 인증서 설정과 도메인 연결이 필요해 복잡도가 높다. CloudFront를 사용하면 이러한 작업이 간소화되며, 보안을 강화할 수 있는 장점이 있다.
S3, CloudFront를 활용한 아키텍처 구성
S3 + CloudFront 조합으로 웹 페이지 배포하기
이제 본격적으로 S3와 CloudFront를 통해 웹 페이지를 배포해 보도록 하겠다.
Step1. S3 버킷 생성하기
가장 먼저 해야 할일은 S3 버킷을 생성해야하는데 다음과 같이 AWS 콘솔에서 S3를 검색하여 접속하자.
버킨 만들기 버튼을 누르면 다음과 같은 화면이 보이게 되고, 버킷이름을 먼저 작성해주자 나같은 경우는 api-server-web-page
라고 지정하였다.
리전은 항상 서울로 설정하는건 잊으면 안된다.
그 이후에 이 버킷의 퍼블릭 액세스 차단 설정
항목에서 모든 퍼블릭 액세스 차단
을 언체크
해야한다. 체크박스를 풀어주어야 다른 익명의 사용자들이 S3에 저장된 나의 웹 페이지를 접속할 수 있다. 또한 모든 퍼블릭 액세스 차단을 비활성화하면 이 버킷과 그 안에 포함된 객체가 퍼블릭 상태가 될 수 있습니다.
항목에서의 현재 설정으로 인해 이 버킷과 그 안에 포함된 객체가 퍼블릭 상태가 될 수 있음을 알고 있습니다.
는 체크해 주어야 한다. 아래 이미지를 잘 확인하자.
위 과정을 완료한 후에 다른 부분은 변경하지 않고 화면 우측 하단의 버킷 만들기 버튼을 클릭한다.
위 과정을 정상적으로 진행하였다면 다음과 같이 버킷이 생성 완료된것을 확인 할 수 있다.
버킷을 생성하였지만, 위 과정을 통해 생성된 버킷은 아직 권한이 열리는건 아니다. 따로 버킷의 권한을 수정하여 정책을 생성해 주어야 한다. 다음과 같이 생성된 버킷의 권한 탭으로 이동하자.
하단으로 조금 내리면 버킷 정책 영역이 보이는데 이부분의 편집 버튼을 클릭하자.
화면 중앙의 새문 추가 버튼을 클릭하자. 본격적으로 S3의 접근 권한을 설정할 것이다.
작업 필터링 영역에 S3
입력 후 체크, GetObject
입력 후 체크하면 다음과 같은 화면이 된다.
그 뒤에 리소스 추가를 누르고 다음과 같이 리소스 유형으로 object
리소스 ARN는 기존에 arn:aws:s3:::{BucketName}/{ObjectName}
라고 작성되어 있을텐데 {BucketName}
에는 본인의 버킷 이름 즉 나같은 경우는 api-server-web-page
를 입력하고, {ObjectName}
는 *
로 모든 파일에 대해서 접근을 허용해준다. 그 뒤로 리소스 추가 버튼으로 작업을 완료해주자.
정책의 Principal
부분을 보면 기존에는 {}
라고 입력이 되어 있을텐데 "*"
으로 입력해준다. 이후 변경 사항 저장을 눌러서 버킷 정책 편집을 완료해 주자.
다음과 같이 버킷 정책 편집이 잘 완료된 것을 확인 할 수 있다.
Step2. S3에 파일 업로드 및 웹 호스팅 설정하기
일단 가장 먼저, 생성된 버킷을 아래 이미지 페이지로 이동하여 확인하자.
내가 생성한 버킷의 이름이 파란색으로 되어있는데 해당 이름을 클릭하면 다음과 같은 페이지로 이동할수 있고 파일을 업로드할 수 있는 업로드
버튼이 보인다.
그러면 다음과 같은 화면이 나오고 여기서 파일 추가 버튼을 눌러서 간단한 index.html
파일을 업로드 해보자 (업로드 버튼까지 클릭하자.)
그러면 이렇게 버킷에 index.html
파일이 업로드 된 것을 확인할 수 있다.
S3에는 파일 업로드 다운로드 기능 뿐만 아니라, 정적 웹사이트 호스팅 기능도 존재한다고 했는데 우리는 지금 생성한 S3의 index.html 파일을 정적 웹사이트 호스팅 기능을 이용해 볼 것이다. 가장먼저 다음과 같이 버킷의 속성 탭으로 이동해보자.
아래로 화면을 쭉 내리면 정적 웹 사이트 호스팅
영역이 나오는데 편집 버튼을 눌러주자.
지금은 간단한 정적 웹페이지를 호스팅 하는 것이기 때문에 정적 웹 사이트 호스팅
영역은 활성화 버튼 클릭
, 인덱스 문서
는 index.html
을 입력하고 아래로 내려서 변경사항 저장 버튼을 눌러준다.
변경사항 저장 버튼을 클릭하고 나서, 새롭개 갱신된 화면에서의 제일 하단을 보면 다음과 같이 정적 웹 사이트 호스팅
영역이 존재한다. 버킷 웹 사이트 엔드포인트
의 주소값이 현재 정적 웹사이트 호스팅이 된 주소값인데 클릭해보면 index.html
파일로 접근하게 된다.
정상적으로 접근되는것을 확인할 수 있다.
Step3. CloudFront 생성하기
S3의 정적 웹사이트 호스팅을 완료하였으니 이제는 CloudFront를 생성해볼 차례이다. 가장먼저 AWS 콘솔창에서 CloudFront
를 검색해서 접속하자. 다음과 같은 화면이 보일것이다.
CloudFront 배포 생성 버튼을 클릭하자. 그럼 다음과 같은 화면을 볼 수 있다.
가장 먼저 Origin domain
을 설정할 것인데, CloudFront가 원본 파일의 주소가 어디있는지를 물어보는것이다. 우리는 원본파일을 S3에 만들어 두었기에 S3의 주소를 클릭하면 된다.
그 뒤에 Origin domain
의 아래의 경고 문구가 보이는데 웹 사이트 엔드포인트 사용
버튼클릭을 해준다. AWS 내부 구조상 웹사이트 엔드포인트 사용하는것이 더 좋다고 권장하고 있다. 그러면 http://api-server-web-page.s3-website.ap-northeast-2.amazonaws.com/
이렇게 이전에 S3를 정적 웹사이트 호스팅 하고나서 버킷 웹 사이트 엔드포인트의 주소값
을 확인할 수 있었는데 그 주소로 Origin Domain이 설정이 된다.
아래로 내리면 기본 캐시 동작
의 영역이 보이는데 이 부분에서 뷰어 프로토콜 정책
의 Redirect HTTP to HTTPS
를 선택한다. HTTP로 접근하는 요청을 HTTPS로 리디렉션을 하겠다는 설정이다.
기본 캐시 동작 영역 이후에 또 아래로 화면을 더 내리면 웹 애플리케이션 방화벽(WAF)
영역이 보이는데 보안 보호 비활성화
을 선택해준다. 이걸 선택한다고 해서 보안이 엄청 약해지거나 하는건 아니다. 기본적으로 비활성화를 하더라도 보안이 충분하기 때문에 만약 디테일한 보안을 추가하고싶은 경우 보안 보호 활성화
를 눌러주면 된다.
이후 화면을 더 내리면 설정 영역이 보이는데 CloudFront를 어느 지역에 활성화 시킬것인지 선택하는 부분이다. 우리는 아시아권 중심으로만 서비스를 제공한다 가정하고 북미, 유럽, 아시아, 중동 및 아프리카에서 사용
으로 선택한다.
같은 설정 영역에 기본값 루트 객체 - 선택 사항
이 존재하는데 해당 부분은 / 경로로 접근할때 어던 페이지를 보여줄 것인지 작성하는 부분이다. 당연히 우리는 index.html 파일을 보여줘야 하기떄문에 index.html을 입력한다.
이후 아래의 배포 생성
버튼을 클릭하여 마무리한다.
배포 생성 버튼을 클릭하고나서 CloudFront > 배포
페이지로 이동하면 위 단계를 거쳐서 생성된 CloudFront가 보인다. 이때 세부 정보에 배포 도메인 이름이 보이는데 해당 도메인이 CloudFront로 접근할수 있는 주소이다.
어느 정도 시간이 지나고 나면 브라우저에 URL을 입력했을 때, CloudFront를 통해 S3에 호스팅된 정적 웹사이트에 정상적으로 접근할 수 있음을 확인할 수 있다.
Step4. 도메인 연결 및 HTTPS 적용하기
지금까지의 단계를 정리하자면 S3에 index.html을 업로드하고 정적 웹 사이트 호스팅을 한뒤에, CloudFront를 통해서 S3에 접근할수 있도록 설정하였다. 다만 아직 HTTPS가 적용되지 않아서 HTTPS를 적용할 것인데, 가장먼저 ACM 발급 작업이 선행되어야 한다.
주의사항
CloudFront에 ACM을 적용하기 위해서는 발급을 리전이 한국이 아니라, 버지니아 북부
로 설정해야 한다. 굉장히 중요하니 꼭 확인하자.
ACM 페이지로 이동하였다면 요청 버튼을 클릭하여 다음과 같은 화면에서 별 다른 수정 없이 또 다음 버튼을 클릭해 준다.
도메인 이름을 입력한다. 기존에 구매했었던 도메인 주소를 입력하였다.
도메인 이름을 입력한뒤에 다른 부분은 수정하지 않고 화면을 내리면 나오는 요청 버튼을 클릭한다.
그럼 이미지처럼 화면이 보이는데 중앙에 Route 53에서 레코드 생성 버튼이 보인다 도메인에 CNAME을 추가하는 것인데 해당 버튼을 클릭해 준다.
CNAME이 추가된것을 확인 할 수 있다.
여기까지 완료되면 이 인증서를 CloudFront로 이동하여 적용해야 한다. 다음 이미지와 같이 이전 단계에서 생성한 CloudFront의 설정 항목으로 이동하여 편집 버튼을 클릭한다. 그럼 하기 페이지를 확인할 수 있다.
화면을 내리면 대체 도메인 이름(CNAME) - 선택 사항
이 보이는데 여기서 항목 추가버튼을 클릭하여 ACM 인증서 발급을 받은 도메인 이름을 작성한다. 나같은 경우는 visiblego.com
을 작성하였다. 또한 사용자 정의 SSL 인증서 - 선택 사항
에 ACM에서 발급받은 인증서를 선택해 주면 끝이다. 화면 쭉 내려서 변경 사항 저장
버튼을 클릭해서 설정 편집을 완료하자.
그 뒤에 마지막으로 CloudFront에 Route53의 도메인을 연결해야 한다. Route 53
의 호스팅 영역 페이지로 이동하자. 이제 레코드 생성을 해야한다.
그 뒤에 별칭을 활성화 하고, 엔드포인트를 CloudFront 배포에 대한 별칭
으로 설정한다. 그러면 리전 항목이 배포 선택으로 변경되는데 CloudFront의 주소값을 설정할 수 있다. 값을 잘 선택한 뒤에 레코드 생성 버튼을 클릭해 주자.
정상적으로 레코드가 생성되었다고 알림창으로도 알려준다.
어느정도 시간이 지난 뒤에 CloudFront에 연결한 도메인(visiblego.com)으로 접속해보면 정상적으로 HTTPS로 접근되는것을 확인할 수 있다.
S3 + CloudFront 종료하기
먼저 CloudFront를 종료해보도록 하겠다. CloudFront 배포 페이지로 이동해서 비활성화 버튼을 클릭하자.
그럼 다음 이미지 처럼 사용 중지가 된다. 비활성화가 되어야 삭제를 할 수 있기 때문에 시간을 기다려 주어야 한다.
시간이 어차피 걸리는 동안 S3 버킷과 객체를 삭제하자. 가장먼저 버킷을 삭제하기 전에 버킷안의 객체를 전부 먼저 삭제해야한다. index.html 파일을 삭제하자. index.html 파일을 선택하고 삭제 버튼을 클릭하자.
버킷을 삭제하자.
버킷과 객체를 삭제하는동안 CloudFront가 비활성화가 되기를 바라면서 CloudFront 페이지로 이동한다. CloudFront 배포 ID를 선택하고 삭제 버튼을 클릭하여 마무리 하자.
Route53의 호스팅 영역에서의 도메인 레코드 값 CNAME, A타입 레코드 값을 삭제하는건 이미지를 생략한다.
다음으로
다음 글은 기존에 작성했던 AWS 내용을 프로젝트에 적용하는 과정에서 발생한 문제점이나 트러블슈팅에 관한 내용이 될 것 같다. 예를 들어, EC2 인스턴스에 swap을 설정하는 방법이나, RDS 설정 시 불필요한 비용이 발생하지 않도록 항목을 수정하는 방법과 같은 실용적인 주제를 다룰 예정이다. 다음글이 작성된다면, 해당 글의 내용을 수정하고 다음글의 대한 간략한 설명과 링크를 작성하도록 하겠다.