WiseN

Lambda@Edge를 활용한 이미지 리사이즈 자동화

Jun 20,2018   |   AWS

작성자_최준승

페이스북 공유하기 트위터 공유하기
Blog thumbnail

여기서 다루는 내용



· Lambda@Edge 개요
· Lambda@Edge 서비스를 활용한 이미지 리사이즈 WorkFlow
· 부록: AWS 블로그 버전과 김세준님 버전의 차이점
· 정리







What is Lambda@Edge?






안녕하십니까, GS네오텍 최준승입니다.
오늘은 평소와 다르게 여러분들이 좀 관심있을만한 실용적인 내용을 소개해 드리려고 합니다.

제목을 다시 한번 보겠습니다. "Lambda@Edge를 활용한 이미지 리사이즈 자동화" 네요.
문맥으로 보아 이미지 리사이즈를 Lambda@Edge라는 친구가 자동으로 해주는 모양입니다.
Lambda는 대충 알겠는데, Lambda@Edge는 뭔지 잘 모르시는 분들을 위해 이 친구부터 간단히 소개드리죠.



원문이 제일 정확하니, 원문의 정의를 그대로 가져와 보겠습니다.


  • Lambda@Edge is an extension of AWS Lambda

  • a compute service that lets you execute functions that customize the content that CloudFront delivers



약간 풀어 설명하면 다음과 같습니다.


  • Lambda@Edge는 Cloudfront Edge 전후 위치에서 실행되는 Lambda 서비스임

  • 함수가 실행되는 지점은 4개 중 선택할 수 있음 (그림에 체크 표시된 곳 중 원하는 지점을 선택)

  • HTTP 헤더를 조작하거나 아주 간단한 수준(리사이징같은)의 연산을 수행할 수 있음



자, 똑똑한 여러분들은 이제 이해가 딱! 되실겁니다. 그리고 질문 하나가 떠오르실 겁니다.
① ~ ④ 중에서 리사이즈는 어디서 한다는거야??

답부터 알려드리면 ③ Origin Response 에서 합니다.
그리고 이걸 구현하기 위해 ① Viewer Request 가 약간 서포트해주는 형태입니다.

이제 세부 동작을 살펴보시죠.





이미지 리사이즈 동작 방식






오늘은 두가지 원문을 참고할 예정입니다.

하나는 AWS Blog 버전이고
다른 하나는 해당 글을 기반으로 틀린 부분을 수정하고 친절한 설명을 덧붙인 김세준님의 버전입니다.

Resizing Images with Amazon CloudFront & Lambda@Edge | AWS CDN Blog
Lambda@Edge를 이용한 DIMS 구현

해당 기능을 구현하는 방법이나 컨셉은 위 링크를 참고하시면 되구요.
저는 거시적인 동작흐름만 집중해서 내용을 다루고, 두 원문이 어떻게 다른지를 추후에 보충하겠습니다.

기본 동작은 이렇습니다.



  • 우선 Origin에는 원본 이미지만 있습니다. 리사이즈 버전은 없습니다.

  • Client는 원하는 이미지 크기 정보를 Query String에 "d" 이름의 필드로 넣어 경로와 함께 요청합니다.

  • Edge에서는 해당 요청에 부합하는 리사이즈된 이미지를 반환합니다. (Hit or Miss)

  • 물론 Origin에는 원본 크기의 이미지만 있으므로, 이와중에 어디선가 이미지를 리사이즈하는 로직이 있어야 합니다.



우선 CloudFront 캐싱 정책에 d라는 이름의 Query String 항목을 설정해줘야 합니다.
그래야 100X100 크기도 캐싱하고, 200X200 크기도 캐싱하고. 크기별로 각기 따로따로 캐싱하지 않겠습니까?
CloudFront 설정에는 아래처럼 들어갑니다. 간단하죠?



자, 이제 다음 단계로 넘어가 봅시다.

Client는 CF에 다음과 같은 URI로 요청합니다.
{CLOUDFRONT_DOMAIN_NAME}/twice.jpg?d=100x100
하지만 Origin인 S3는 이렇게 복잡한? 구조를 이해할 수 없습니다. 따라서 URI를 조금 바꿔줘야 합니다. 이런식으로.
{Origin}/100x100/webp/twice.jpg

그림으로 표현하면 이런식입니다.



그럼 이런 조작은 Lambda@Edge 中 어느 위치에서 해야 할까요?

정답은 ① Viewer Request 입니다. 여기서 request.uri 값을 변조?해줍니다.
AWS Blog 글 기준으로 Code snippet 1를 보시면 됩니다.



자, 이제 마지막 단계만 남았습니다.

Edge에서는 Origin에 다음과 같은 URI로 요청합니다.
{Origin}/100x100/webp/twice.jpg
하지만 최초 요청시 Origin의 이 경로에는 이런 이미지는 없습니다. 루트 경로에 twice.jpg라는 원본만 있죠.
따라서 404 응답코드를 뱉게 됩니다. 누구한테? Origin에 요청했던 Edge에게.



일반적인 CloudFront 동작이면 아마 Origin의 404 응답을 받아서 Client에게 그대로 전달해 줬을겁니다.
하지만 그럴수는 없죠. 이때 람돠@엣지가 또 개입합니다. 어디에서? ③ Origin Response 에서.



이 시점에 실행되는 Lambda 함수에서는 이런 것들을 수행합니다.

  • Origin 응답코드가 404인지 확인합니다. 아니면 냅둡니다.

  • 응답코드가 404가 맞다면, 루트 경로에서 원본 이미지를 찾습니다.

  • 원본 이미지가 있다면 전달받은 요청 크기에 맞게 리사이즈를 수행하고 S3에 Put합니다.

  • 동시에 리사이즈한 결과를 binary 응답에 포함시키고, 응답코드를 200으로 변경합니다.



그럼 이렇게 끝납니다.



드디어 설명히 끝났네요. 이해가 안되시면 처음부터 다시 한번 읽어보시길 부탁드립니다.





부록: AWS 블로그 버전과 김세준님 버전의 차이점






뭔가 허전하니, 부록으로 AWS 블로그 내용과 김세준님 버전의 차이점을 간단히 짚어보고 마치도록 하겠습니다.
위 링크는 아마도 클릭 안하셨을테니까, 한번 더 링크 걸어드립니다.

AWS: Resizing Images with Amazon CloudFront & Lambda@Edge | AWS CDN Blog
SJ: Lambda@Edge를 이용한 DIMS 구현

1. Lambda@Edge 등 관련 컴포넌트 구성

  • AWS: 제공된 CloudFormation 템플릿으로 스택 구성

  • SJ: 순서에 맞게 Step-by-Step 방식으로 단위 요소를 수동 구성



2. S3 Bucket Policy 설정

  • AWS: 일부 S3 Bucket이 GetObject 요청에 대해 Any(Public) Open 되어 있음

  • SJ: OAI를 사용하여 CF의 요청만 허용하도록 버킷 정책 수정



3. S3 Bucket이 위치하는 Region 선택

  • AWS: 원하는 Region을 선택하여 S3 Bucket을 생성한 후 환경변수에 넣어줌

  • SJ: 한국 사용자 환경이라고 전제하고, Lambda@Edge와 S3 Bucket 구간의 속도를 감안하여 서울 리전에 버킷 생성



크게 이정도의 차이점이 있구요.
따라하기 난이도나 구성요소를 이해한다는 관점에서 김세준님 버전이 완성도가 더 높습니다.





마치며






자, 오늘은 여러분들에게 생소한 Lambda@Edge 서비스의 컨셉과 더불어
이 서비스를 사용하여 이미지 리사이즈를 자동화하는 동작 흐름을 간략하게 살펴보셨습니다.

참고로 Lambda@Edge 서비스의 제약사항은 일반 Lambda와는 또 다릅니다.
예를 들어 일반적인 Lamdba Function의 Timeout이 300초라면. Lambda@Edge의 경우 viewer-*는 5초, origin-@는 30초입니다.
특정 서비스를 도입하실때는 이런 제약사항에 대한 이해가 반드시 선행해야 합니다.

그나저나 실제 Production 환경에서 특정 구성요소를 실험적으로 변경하여 돌려본다는 것이 쉽지만은 않은 일인데요.
그래도 AWS같은 클라우드 환경이라면. 장기판을 통째로 엎지 않고. 한번 물러서 원복이 가능하다는 장점이 있는게 아닐까요?

관련하여 애써주신 김세준님과 H모 고객사 담당자님께 감사를 드리며 글을 마치도록 하겠습니다.

끝!