[AWS] Lambda@Edge를 이용한 이미지 리사이징

Lambda@Edge를 이용한 이미지 리사이징







이미지 생성과 삭제가 빈번할 수록, 이미지를 처리에 많은 cpu, memory, storage 가 사용됩니다.

이러한 문제를 해결하기 위한 하나의 방법으로 많이 알려진 cloudfront에서 lambda@edge를 활용해 이미지를 리사이징하는 방법을 알아보겠습니다 . 





Lambda@Edge


AWS Lambda를 사용하면 서버를 프로비저닝하거나 관리하지 않고도 코드를 실행할 수 있습니다.

 사용한 컴퓨팅 시간에 대해서만 비용을 지불합니다. 코드가 실행되지 않을 때는 비용이 부과되지 않습니다.

Amazon CloudFront 배포의 각 캐시 동작에 대해 다음 CloudFront 이벤트 중 하나 이상이 발생할 때 Lambda 함수가 실행되도록하는 트리거 (연결)를 최대 4 개까지 추가 할 수 있습니다.


  1. CloudFront 뷰어 요청 –이 함수는 CloudFront가 뷰어로부터 요청을 수신하고 요청 된 객체가 엣지 캐시에 있는지 확인하기 전에 실행됩니다.
  2. CloudFront 오리진 요청 –이 함수는 CloudFront가 오리진에 요청을 전달할 때만 실행됩니다. 요청 된 개체가 엣지 캐시에 있으면 함수가 실행되지 않습니다.(cache miss발생 시 실행됨)
  3. CloudFront 오리진 응답 –이 함수는 CloudFront가 오리진 으로부터 응답을 수신 한 후 응답에서 객체를 캐시하기 전에 실행됩니다.
  4. CloudFront 뷰어 응답 – 요청 된 객체를 뷰어에게 반환하기 전에 함수가 실행됩니다. 이 함수는 객체가 이미 에지 캐시에 있는지 여부에 관계없이 실행됩니다.







Architecture




  • CloudFront는 이미지를 캐싱 및 Lambda함수를 배포할 edge location입니다.
  • Lambda는 이미지를 리사이징 하기 위한 함수입니다.
  • S3는 리사이징할 이미지가 저장된 storage입니다.



S3 버킷 생성 및 설정

s3 버킷을 생성한 후, 리사이징할 이미지를 넣습니다. 생성할 버킷의 리전은 상관이 없습니다.



 

버킷 정책의 경우, cloudfront를 생성하면서, 자동으로 업데이트할 것이기 때문에 따로 수정하지는 않습니다.




CloudFront 배포 생성

s3의 이미지를 캐싱할 cloudfront 배포를 생성합니다. 
































  • Origin Domain Name : 이미지를 넣었던 버킷을 선택합니다.
  • Origin ID : 자동으로 기입됩니다.
  • Restrict Bucket Access : 버킷에 접근 제한을 활성화합니다.
  • Origin Access Identity : s3 접근 권한을 얻기 위해서 새로운 identity를 생성합니다.
  • Grant Read Permission on Bucket : 해당 cloudfront 배포에서 오리진 s3 객체에 대해서 읽기위해서 자동으로 Bucket 정책을 생성할 수 있습니다.























































  • Viewer Protocol Policy : Redirect HTTP to HTTPS를 선택합니다.
  • Cache and origin request settings : Use legacy cache settings 를 선택합니다.
  • Query String Forwarding and Caching : Forward all, cache based on whitelist를 선택합니다. (리소스를 캐싱할때 QueryString을 인식하여 구분하도록 설정)
  • Query String Whitelist : w, h, q, f 를 입력합니다. (w : 너비, h : 높이, q : 퀄리티, f : 이미지 포멧)
  • Compress Objects Automatically : 리소스 자동 압축 기능을 활성화합니다.


생성 버튼을 클릭하고, cloudfront 배포 설정이 완료될때 까지 기다립니다.














생성이 완료되면 S3 버킷의 정책이 수정됩니다 . 

 {                                                                                                                              
  "Version": "2008-10-17",                                                                                               
  "Id": "PolicyForCloudFrontPrivateContent",                                                                        
  "Statement": [                                                                                                            
    {                                                                                                                           
      "Sid": "1",                                                                                                              
      "Effect": "Allow",                                                                                                     
      "Principal": {                                                                                                          
        "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E1B5N1FPAV2X1P"    
      },                                                                                                                        
      "Action": "s3:GetObject",                                                                                          
      "Resource": "arn:aws:s3:::imagebucketthum/*"                                                               
    }                                                                                                                          
  ]                                                                                                                            
}                                                                                                                               



Lambda 함수 구성 및 배포

CloudFront의 Lambda@edge 로 Lambda 함수를 배포하기 위해서는 Lambda 함수를 버지니아 북부(us-east-1)에 생성 해야합니다. 

us-east-1에서 Node.js 10.x 혹은 Node.js 12.x으로 Lambda 함수를 생성합니다



















함수 구성 뒤 제한시간을 10초로 설정합니다 . 

제한 시간을 짧게 구성 시, 최초 요청(Cache miss 상황)에 연산이 많이지면 리사이징 되지 않을 수 있습니다. 또한 Lambda@edge 기본 동작 원리에 의해서 request, response간에도 시간이 소요되므로 최소 4~5초 이상이 권장됩니다.


Lambda 함수 내용

일단 이미지를 resize하기 위한 라이브러리로 sharp가 필요합니다.

lambda 에서 외부 라이브러리를 사용하는 방법은 여러가지가 있습니다.

  • 로컬에서 코드 및 라이브러리 파일을 .zip 파일로 압축하여 lambda에 직접 업로드
  • 로컬에서 코드 및 라이브러리 파일을 .zip 파일로 압축하여 s3에 업로드 후 lambda 함수에서 불러오기
  • aws cloud9 서비스를 이용하여 lambda import - 수정 - lambda 함수로 업로드
  • AWS lambda Layer를 활용하여 함수에서 해당 라이브러리 호출

cloud 9 생성 

코드 수정 후 업로드만 하는 역할이기에 가장 작은 타입으로 진행하겠습니다.






























lambda 함수를 import하겠습니다. 좌측 탭에서 aws 를 클릭 후, 람다함수가 배포된 us-east-1 리전 선택 후, lambda 선택하여 생성한 람다함수를 import합니다. 


import 하게되면 어떤 폴더에 import할지 선택 가능합니다. 저는 기본 default로 진행합니다.

완료되면 import한 람다함수를 터미널이나 좌측 탭에서도 확인 가능합니다.


해당 함수디렉토리로 접근 후 sharp 라이브러리를 설치합니다.

$cd Resizing-Image/    # 생성한 람다 함수 명을 입력                       
$npm init -y                                                                           
$npm install sharp                                                                   





설치가 완료되면 node_module과 package.json,package-lock.json 등을 확인할 수 있습니다. 

index.js 파일을 열어 해당 코드 내용을 아래와 같이 수정합니다.


14번째 줄의 버킷명을 생성하신 버킷명으로 변경





각종 설정을 완료하고 index.js를 저장합니다 . 

upload lambda를 선택합니다.





upload 형식을 Zip으로 할지 Directory를 할지 선택 가능합니다. 






이후 작업한 디렉토리를 선택하여 open 합니다.





















좌측 탭에서 디렉토리를 빌드할 것인지 질문하는데 원하는 것을 선택하고 코드를 즉시 배포할 것인지 선택합니다.

배포이미지가 너무 커서 인라인 편집이 되지 않기 때문에 Lambda@Edge로 배포 하겠습니다. 


Lambda@Edge로 배포

생성한 함수 우측 상단 - 작업 - Lambda@edge로 배포를 클릭합니다













함수를 배포할 cloudfront distribution을 선택하고 어떤 behavior에 동작할 것인지 선택 후 이벤트는 

Origin Response를 선택 후 배포합니다.




















Lambda@edge 함수는 배포 후, 적용까지 5분 정도 소요될 수 있습니다.

만약 함수를 수정하였다면 새로운 버전을 게시하고 해당 버전을 cloudfront와 연결합니다.

배포 완료 시, 해당 cloudfront Behavior에서 연결된 함수를 확인 가능합니다.











이제 cloudfront를 통해 이미지를 Resizing 합니다.

[cloudfront 도메인 이름]/[이미지 이름]

위 요청이 기본적인 이미지를 웹에서 불러오는 요청입니다.

dofetefaul8ei.cloudfront.net/youtube_folder_file_10389.png






댓글