serverless-image-handler
Serverless Image Handler는 AWS에서 제공하는 다양하고 검증된 서비스들을 조합하여 만들어진 솔루션(?)입니다.
운영하는 서비스에 종속적인 기능들이 아니라면 한번 찾아보면 이미 만들어져 있을 법한 것들이 있기 때문에 한번 서칭해보면 좋을 듯 한데요. 그 예로, 로깅 중앙화, 제가 사용해본 서버리스 이미지 핸들러 등등이 존재합니다.
https://github.com/aws-solutions/
아키텍처
< 출처: https://github.com/aws-solutions/serverless-image-handler >
해당 기능은 말그대로 서버리스 환경에서 이미지를 요청 시에 즉시 핸들링해주는 솔루션입니다. 제가 맡고 있는 서비스는 원본 이미지를 다양한 크기로 이미지를 노출시킬 수 있어야 했는데요. 미리 만드는 방법도 있지만 이는 정적이고, 마이그레이션이 다소 불편하며, 관리하는 측면에서 만족스럽지 못 했습니다.
이것 이외에도 CloudFront + Lambda@Edge를 사용하는 방법도 있으니 참고하시기 바랍니다.
- https://aws.amazon.com/blogs/networking-and-content-delivery/resizing-images-with-amazon-cloudfront-lambdaedge-aws-cdn-blog/
- https://medium.com/daangn/lambda-edge%EB%A1%9C-%EA%B5%AC%ED%98%84%ED%95%98%EB%8A%94-on-the-fly-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%A6%AC%EC%82%AC%EC%9D%B4%EC%A7%95-f4e5052d49f3
기능
- 이미지를 다양한 형태로 핸들링할 수 있습니다.
- 해당 기능은 런타임 환경이 Nodejs에서 이루어지며, Nodejs에서 이미지 처리하는 라이브러리인
sharp
를 사용하고 있습니다. - 리사이징
- 포맷 변경
- 퀄리티 변경
- ...
- 해당 기능은 런타임 환경이 Nodejs에서 이루어지며, Nodejs에서 이미지 처리하는 라이브러리인
- 이미지 URL 변조
- 만약 우리가 300x300 사이즈의 이미지를 제공하고 이를 어느 누구나 변경해서 요청할 수 있다면 어뷰징 대상이 될 수 있을 것 입니다.
- 300x301, 300x302, 300x303, 300x... 😱
signature
라는 파라미터를 받아서 이를 변조하지 못하도록 제공하고 있습니다. (해당 기능은 secret-manager를 통해 별도의 키를 만들어서 사용합니다.)
- 이미지 자르기, Amazone Rekognition을 활용한 분석 등등을 제공합니다.
- ...
사용방법
Default 방식
const imageRequest = JSON.stringify({
bucket: "<myImageBucket>",
key: "<myObjectKey>",
edits: {
resize: {
width: ...,
height: ...
}
}
});
const url = `${CloudFrontUrl}/${btoa(imageRequest)}`;
<img src=`${url}` />
위 방식은 url을 json문자열을 base64으로 인코딩해서 전달하는 방식으로 json 안에는 bucket, object key, sharp 정보(?) 등을 포함되어 있습니다. sharp 관련된 내용은 관련 문서를 참고해서 적용하면 손쉽게 적용할 수 있습니다.
Thumbor 방식
const url = `${CloudFrontUrl}/filter:format(webp)/${object_key}`;
<img src=`${url}` />
위 방식은 기존 url과 비슷하게 유지하면서 사용할 수 있는 방법 중에 하나로, path 중간에 filters:~~~
를 넣어 옵션을 적용할 수 있습니다.
사용 후기
장점
-
CloudFormation으로 제공되기 때문에 손쉽게 구축할 수 있습니다.
- AWS 솔루션의 공통적인 장점이겠지만, cdk를 활용해 CloudFormation으로 빌드하여 제공하고 있습니다.
-
CloudFront를 사용하기 때문에 한번 요청되면 캐시되어 비용 절감이 가능하다.
- CloudFront라는 CDN 서비스를 사용하고 있기 떄문에(사실 누가 CloudFront없이 S3를 바로 붙이겠냐만은...) 응답이 캐싱되어 첫 요청이외에는 비용이 많이 절감됩니다.
-
On the fly 방식이기 때문에 관리가 용이합니다.
단점
-
람다 자체가 요청/응답에 대한 페이로드가 6MB 제한이 있기 때문에 큰 이미지를 전달할 수 없습니다.
- base64로 인코딩해서 전달하기 때문에 6MB보다 더 작아야 합니다. 😥
-
다소 과할 수 있다.
- 어느 것이나 그렇지만 단순하게 쓰고자한다면 조금 과할 수 있다.
-
6.0.0 버전까진 gif 대응이 안된다.
sharp
가0.30.0
버전부터 gif를 지원하기 시작했지만,0.27.0
버전을 사용하고 있기 때문에 대응이 안된다.- gif를 지원하려면 결국엔 별도 빌드를 거쳐서 사용해야함
결국, 1,3번 단점 때문에 나의 서비스는 api gateway에 별도 path를 추가 및 직접 S3 서비스를 연결해서 사용하고 있습니다.