Cloud/AWS

[AWS] NodeJS로 만든 Lambda 함수로 이미지 사이즈 줄이는 법

백엔드 규니 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 함수를 생성해서 이미지 사이즈를 줄이는 것을 해보았습니다. 확실히 사이즈가 많이 줄어든 것을 보니 이미지가 많고 썸네일을 필요로 하는 화면에서 사용하면 여러므로 도움이 많이 될 거 같습니다.

반응형