ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AWS] NodeJS로 만든 Lambda 함수로 이미지 사이즈 줄이는 법
    Cloud/AWS 2021. 5. 13. 17:00
    728x90
    반응형

    NodeJS, Lambda로 Image Resize 하는 법

    저번 글 에서 Lambda로 Thumbnail Image를 생성하는 법에 대해서 정리를 해보았는데요. 저번 글에서는 Lambda 함수를 Python을 사용했습니다.

     

    이번 글에서는 NodeJS를 사용하여 Lambda 함수를 만들고 Image Resize를 하는 것에 대해서 정리해보겠습니다.

     

    스크린샷 2021-05-13 오후 1 47 41

    이번 글에서 해보고자 하는 아키텍쳐는 위와 같습니다. 즉 사용될 도구는 아래와 같은데요.

    • NodeJS
    • AWS S3, Lambda

     

    하나씩 어떻게 설정해서 어떻게 진행하는지에 대해서 정리해보겠습니다.

     

     

    AWS Cli 설치하기

    brew install awscli

    스크린샷 2021-05-13 오후 1 53 39

    그리고 IAM 사용자엑세스 키, 비밀 엑세스 키를 등록을 해야 하는데요. IAM 사용자를 만들고 엑세스 키를 발급받는 것은 되어 있다 가정하고 진행하겠습니다.


    자세한 것은 여기 를 참고하시면 됩니다.

     

    스크린샷 2021-05-13 오후 1 57 52

    aws configure
    AWS Access Key ID: IAM 엑세스 키 입력
    AWS Secret Access Key ID: IAM 비밀 엑세스 키 입력
    Default region name: ap-northeast-2
    Default output format: json

    위와 같이 aws configure를 통해서 IAM 사용자 엑세스 키, 비밀 엑세스 키, 리전을 미리 등록해놓겠습니다.

     

     

    IAM 설정하기

    스크린샷 2021-05-13 오후 2 14 27

    AWS Lambda 서비스를 사용하기 위해서는 해당 사용자에게 Lambda 접근 권한을 주어야 합니다. 그래서 위와 같이 사용자 -> 권한 추가를 누르고 AWSLambda_FullAccess를 추가하겠습니다. 그러면 위와 같이 추가가 된 화면을 볼 수 있습니다.


    그리고 사진 업로드도 할 것이기 때문에 S3FullAccess 권한이 없다면 같이 추가해주시면 됩니다.

    위에서는 사용자에게 람다를 사용할 수 있게 권한을 부여했다면 지금부터는 우리가 올릴 lambda Function 개체에 권한을 부여하겠습니다.

     

     

    IAM 역할 생성하기

    스크린샷 2021-05-13 오후 2 19 26스크린샷 2021-05-13 오후 2 20 37스크린샷 2021-05-13 오후 4 18 36

     

    S3FullAccess, AWSLambdaBasicExecutionRole을 선택하겠습니다.(LambdaBasicExecutionRole 은 AWS 서비스 및 리소스에 액세스 할 수 있는 권한을 부여합니다.)
    이런 권한이 있어야 Lambda 함수가 제대로 작동할 수 있습니다. 그리고 역할 이름을 정하고 역할을 만들겠습니다.



     

    Lambda 함수 코드

    스크린샷 2021-05-13 오후 2 27 45

    위와 같이 index.js 파일을 하나 만든 후에 아래의 코드를 추가하겠습니다.

     

    const sharp = require("sharp");
    const aws = require("aws-sdk");
    const s3 = new aws.S3();
    
    const Bucket = "serverless-gyunny-bucket";
    const transforms = [
      { name: "w_200", width: 200 },
      { name: "w_400", width: 400 }
    ];
    
    exports.handler = async (event, context, callback) => {
      const key = event.Records[0].s3.object.key;
      const sanitizedKey = key.replace(/\+/g, " ");
      const parts = sanitizedKey.split("/");
      const filename = parts[parts.length - 1];
    
      try {
        const image = await s3.getObject({ Bucket, Key: sanitizedKey }).promise();
    
        await Promise.all(
          transforms.map(async item => {
            const resizedImg = await sharp(image.Body)
              .resize({ width: item.width })
              .toBuffer();
            return await s3
              .putObject({
                Bucket,
                Body: resizedImg,
                Key: `images/${item.name}/${filename}`
              })
              .promise();
          })
        );
        callback(null, `Success: ${filename}`);
      } catch (err) {
        callback(`Error resizing files: ${err}`);
      }
    };

    스크린샷 2021-05-13 오후 2 30 44

    코드에서 볼 부분은 표시한 부분인데요. 사진 파일을 저장할 S3 Bucket 이름을 지정하고 이미지를 몇 사이즈로 줄일지를 정하는 코드가 있습니다. 좀 더 자세히 보고 싶다면 Github 에서 확인할 수 있습니다.

     

    const trasforms = [
        { name: "w_200", width: 200 },  // w_200 디렉토리에 200x200 사이즈로 이미지 리사이징
        { name: "w_400", width: 400 }   // w_400 디렉토리에 400x400 사이즈로 이미지 리사이징
    ]

    코드의 의미는 위처럼 200x200, 400x400의 Resize 파일이 저장되도록 하였습니다.

     

    npm install --arch=x64 --platform=linux sharp

    위의 명령어를 통해서 모듈을 설치하겠습니다.

     

    스크린샷 2021-05-13 오후 2 37 02

     

    스크린샷 2021-05-13 오후 2 38 37

    그러면 위와 같이 모듈 관련 파일들이 생겼을 것입니다. 이제 전체 프로젝트를 zip으로 압축하겠습니다.

     

    zip -r 원하는이름.zip 압축할폴더이름
    ex) zip -r function.zip .

    위의 명령어를 치면 function.zip으로 프로젝트가 압축이 됩니다.

     

    스크린샷 2021-05-13 오후 4 12 33

    그리고 아까 위에서 LambdaBasicExecutionRole 권한을 주었던 역할로 다시 가보겠습니다.

     

     

    스크린샷 2021-05-13 오후 2 43 38

    들어가면 위처럼 역할 ARN이 존재합니다. 이것을 복사하겠습니다.

     

     

    aws lambda create-function --function-name imageResizing \
    --zip-file fileb://function.zip --handler index.handler --runtime nodejs12.x \ --role 각자역할ARN 넣기

    스크린샷 2021-05-13 오후 2 47 55스크린샷 2021-05-13 오후 2 50 08

    그리고 AWS Lambda로 가보면 위와 같이 CLI에서 지정했던 Lambda Function이 생성된 것을 확인할 수 있습니다.

     

     

    S3 이벤트 트리거 설정

    스크린샷 2021-05-13 오후 2 52 12스크린샷 2021-05-13 오후 2 54 00스크린샷 2021-05-13 오후 3 35 46

    위와 같이 S3 Bucket 내부 /images/origin 경로에 파일이 저장되면 위에서 지정한 트리거가 발생해서 람다 함수가 작동할 것입니다.

     

     

    스크린샷 2021-05-13 오후 3 40 19

    그리고 Lambda 함수를 들어가보면 위와 같이 S3 Trigger가 추가되어 있는 것을 볼 수 있습니다.

     

     

    S3 파일 업로드 해보기

    스크린샷 2021-05-13 오후 3 49 42

    위와 같이 /images/origin 의 디렉토리를 만든 후에 업로드를 S3에서 직접 해보겠습니다.

     

     

    스크린샷 2021-05-13 오후 4 09 56

    429.4KB 크기의 사진 파일을 업로드 하였습니다.

     

     

    스크린샷 2021-05-13 오후 4 23 23

     

    그리고 /images에 경로를 보면 위와 같이 w_200, w_400의 디렉토리가 자동으로 생긴 것을 볼 수 있습니다.(람다 함수 코드에서 지정한 이름대로 생성된 것도 확인할 수 있습니다.)

     

     

    스크린샷 2021-05-13 오후 4 25 15

     

    일단 200x200으로 줄인 사진의 크기는 429.4KB-> 7.6KB로 줄어든 것을 볼 수 있습니다.

     

    스크린샷 2021-05-13 오후 4 26 26

     

    그리고 400x400으로 줄인 사이즈는 429.4KB -> 32.4KB로 줄어든 것도 확인할 수 있습니다.

     

    이렇게 이번 글에서 NodeJSLambda 함수를 생성해서 이미지 사이즈를 줄이는 것을 해보았습니다. 확실히 사이즈가 많이 줄어든 것을 보니 이미지가 많고 썸네일을 필요로 하는 화면에서 사용하면 여러므로 도움이 많이 될 거 같습니다.

    반응형

    댓글

Designed by Tistory.