728x90

AWS의 CDN 제품인 CloudFront는 원본 서버에서 제공하는 기본 오브젝트를 지정할 수 있는 기능을 제공하고 있습니다. 보통은 원본 서버에서 사용하는 웹 서버에서 기본 오브젝트를 지정하는 경우가 많지만 S3 등 다른 제품을 함께 사용할 때는 기본 오브젝트를 지정할 수 있는 방법이 없기 때문에 파일명을 지정할 수 있는 기능이 필요합니다.

기본 루트 오브젝트 설정 Set Default Root Object

CloudFront Distribution의 기본 설정 탭에서 기본 루트 오브젝트를 설정할 수 있습니다. Distribution 목록에서 작업하려는 Dist ID를 선택하여 상세 화면으로 진입합니다. 상단 탭중 첫번째 탭인 General 탭으로 이동합니다. Settings 섹션의 `Edit` 버튼을 눌러 상세 설정 화면으로 진입해 봅니다. 

Edit 화면의 중간 정도를 살펴보면 `Default root object - optional` 항목을 찾으실 수 있습니다. 이곳에 지정된 파일 이름이 CloudFront를 통해 접근시 사용되는 기본적인 파일 이름이 됩니다. 가령 www.iamnopd.com  이라는 도메인이 있다고 가정했을 때, 브라우저에 www.iamnopd.com  만 입력해도 알아서 index.html 을 찾아 사용자 브라우저로 응답을 하게 되는 거죠. 

 

다양한 경로에 대한 기본 오브젝트 설정 

그런데 문제가 있습니다. `Default root object`에 지정한 파일 이름은 진짜, 레알, 루트 경로에 대한 요청에 대해서만 적용되는 한계가 있습니다. 가령 원본이 S3 버킷이라고 했을 때, 버킷의 최상위 경로에도 index.html 이 있고, 버킷에 생성되어 있는 api 폴더의 하위에도 index.html 이 있다고 해봅시다.

아마도 여러분이 기대하는 것은 www.iamnopd.com  접근시에도 index.html 을 읽어들이고 www.iamnopd.com/api  접근시에도 index.html 을 읽어들여 사용자에게 제공되는 시나리오였을겁니다. 하지만 첫번째 케이스와 달리 두번째 api 경로에 대한 접근은 index.html 을 알아서 패칭해오지 않습니다. 반드시 www.iamnopd.com/api/index.html  로 호출을 해야 컨텐츠를 읽어오게 됩니다.

원본의 서로 다른 경로를 특정 사용자 Path의 루트로 바인딩 하기 위해서는 (아시겠지만) 아래와 같이 동일 원본을 Origin Path만 분기하여 등록하면 됩니다. 이 구성과 Default root object 의 조합은 /api 경로에 대해서 적용되지 않는다는 상황으로 이해하지면 될 것 같습니다. 그러면 어떻게 하면 될까요?

 

CloudFront Function을 이용한 경로 조작

S3에서 뭔가를 하면 되지 않을까? 하고 생각했을지도 모르지만 그것보다는 CloudFront Function을 쓰면 간단하게 구현할 수 있습니다. 아시겠지만 Lambda@Edge를 쓰는 것보다 CloudFront Function을 쓰는 것이 사용도 간편하고(=기능이 다소 적고) 비용도 저렴합니다. 묻지도 따지지도 말고 바로 코드를 보겠습니다.

function handler(event) {
    var pathFrom = /^\/api$/g
    var pathTo   = '/api/index.html'
    var pathDecided = '';   
	var request = event.request;
    pathDecided = request.uri;

	if (pathDecided.match(pathFrom) != null) {
    	pathDecided = pathDecided.replace(pathFrom, pathTo);
	}

    request.uri = pathDecided;
    return request;
}

코드는 무척 간단합니다. 간단한 Regex 를 이용하여 들어온 URI (request.uri)를 단순히 문자열 비교한 후에 실제로 원본이 받게될 URI 를 변경해서 return 해주는 코드입니다. 요청량이 많아도 크게 부담스러운 금액이 나오지는 않을것 같습니다. 간단하지만 Default root object가 단일 경로에 대해서만 적용되는 제약을 회피(?)하는 방법을 살펴봤습니다 :-)

테스트도 참 쉽죠? 원하는 결과를 테스트를 통해 얻었다면, 만든 함수를 적용하고자 하는 Distribution의 Behavior의 Viewer Request 함수로 지정하면 됩니다. 끝!

 

 

 

 

728x90

+ Recent posts