현재 배포되어 있는 CloudFront 에는 Custom Domain(image.itthatcat.xyz) 이 적용되어있다. 그리고 S3 와 API Gateway 에 연결되어 있는 상태이다.
Cloudfront 배포 서버로 접근하면 라우팅 경로에 따라 API Gateway(/api/), S3(/ 기본값) 을 바라볼 수 있도록 하였다.
CloudFront 에는 아무런 Routing 이 적용되어 있지 않아 원하는 이미지를 조회하기 위해서는 버킷 경로를 Path 에 적어야하는 문제가 있다. 이미지를 조회하기 위해 s3 경로에 맞게 적어줘야 한다. 이는 s3 이미지 저장 경로가 조금이라도 바뀌면 요청하는 API 경로도 바꿔야 하는 문제가 있다.
현재 potenday-img-resized 라는 이름의 Budget 하위에 원본 사이즈 크기별 디렉토리가 존재한다.
potentday-img-resized
- 50(directory)
--- 237beb84-eca4-4746-bd9e-19640dd8ccff.jpg(filename)
- 200
--- 237beb84-eca4-4746-bd9e-19640dd8ccff.jp g
- 500
---237beb84-eca4-4746-bd9e-19640dd8ccff.jpg
...
크기가 width 가 50px 인 이미지를 가져오고 싶다면 `https://image.itthatcat.xyz/50/237beb84-eca4-4746-bd9e-19640dd8ccff.jpg` 로 요청하면 된다.
즉 `https://image.itthatcat.xyz/{directory}/{file_name}` 형태로 s3 의 디렉토리 구조에 맞춰 요청해야한다.
이는 이미지를 조회하는 URI 경로가 S3 디렉토리 구조에 의존적이다. 이는 S3 디렉토리 구조가 조금이라도 바뀌게 될 경우 이미지를 조회하는 URI 경로도 바꿔야 하는 문제가 생긴다.
쉽게 말해 저장된 이미지의 경로가 바뀌면 URI 도 그에 맞게 수정해야하는 문제가 있었다.
AWS S3 with Cloudfront CDN for different files according to behavior query string
실제로 CloudFront 에서는 관련한 기능을 제공한다. 크게 CloudFront 와 Lambda@Edge 가 존재한다. 나는 치 CloudFront Function 을 사용하여 경로가 아닌 QueryString 을 이용하여 원하는 사이즈의 이미지를 가지고 올 수 있도록 하였다.
경로에는 S3에 디렉토리가 이름이 들어나는 것이 아닌 queryString 으로 사이즈를 줄 수 있도록 하였다.
이전
50/237beb84-eca4-4746-bd9e-19640dd8ccff.jpg
이후
237beb84-eca4-4746-bd9e-19640dd8ccff.jpg?size={weight}
그리고 CloudFront Function 에서는 size 별로 해당되는 s3 디렉토리 경로에 맵핑하여 원하는 이미지를 찾아 반환하도록 한다. 이렇게 된다면 설령 s3 디렉토리 구조가 바뀌었다 하더라고 function 만 수정하면 되기 때문에 클라이언트는 매번 API 경로를 수정할 필요가 없게 된다.
CloudFront 배포 페이지에 가면 좌측에 함수 > 함수생성 버튼을 누른다.

함수의 이름을 입력하고 함수를 실행할 Js Runtime 버전을 선택한다. CloudFront Function Runtime 는 JS 로 동작된다.

함수를 만들고 상세정보에 들어가면 다음과 같다.

생긴 모습이 Lambda Console 화면과 비슷하다. Lambda 와 마찬가지로 함수 코드를 작성하는 부분, 테스트, 그리고 개시(Publish) 하는 부분이 있다.

Publish(개시) 하기 위해서는 Distributaion 을 추가해야한다. 기존에 만들어놓은 CloudFront 자원가 연결해준다.


적용하려고 하는 Cloud Front 와 캐시 동작을 선택한다. 이때 캐시 동작의 경우에는 기존에는 기본 경로로 캐시가 동작되었지만 이제는 쿼리 파라미터로 동작해야하기 때문에 이 부분은 수정이 필요하다. 이 부분은 추후에 다루어 보도록 하겠다.
원하는 S3 이미지 URI 경로로 라우팅 하기 위해 Cloudfunction 에 들어갈 함수를 작성한다.
적용하려고 하는 Cloud Front 와 캐시 동작을 선택한다. 이때 캐시 동작의 경우에는 기존에는 기본 경로로 캐시가 동작되었지만 이제는 쿼리 파라미터로 동작해야하기 때문에 이 부분은 수정이 필요하다. 이 부분은 추후에 다루어 보도록 하겠다.
원하는 S3 이미지 URI 경로로 라우팅 하기 위해 Cloudfunction 에 들어갈 함수를 작성한다.
function handler(event) {
var request = event.request;
var uri = request.uri;
const pathSegments = request.uri.split('/')
const filename = pathSegments[1]
var size;
try {
size = request.querystring['size'].value;
} catch(err){
// 기본 사이즈 weight = 200 로 요청
request.uri = `/200/${filename}`;
return request;
}
const newUri = `/${size}/${filename}`;
request.uri = newUri;
return request;
}
237beb84-eca4-4746-bd9e-19640dd8ccff.jpgsize 를 가져온다.size 를 파싱하는 과정에 에러가 발생한다면 200 사이즈의 s3 이미지 경로를 가리킬 수 있도록 하는 요청 uri 를 반환한다.함수 작성이 끝나면 저장 후 해당 함수를 개시합니다.
이후 https://image.itthatcat.xyz/237beb84-eca4-4746-bd9e-19640dd8ccff.jpg?size=200 URI 로 요청했을 때 원하는 이미지가 나오는 것을 알 수 있다
cloudfront 를 이용해 라우팅처리를 한 uri : https://image.itthatcat.xyz/200/237beb84-eca4-4746-bd9e-19640dd8ccff.jpg