개발스토리

AWS 람다 사용하기 본문

AWS

AWS 람다 사용하기

무루뭉 2021. 2. 19. 23:53

이번에는 S3에 올린 이미지를 리사이징한 후 줄어든 이미지를 다시 S3에 저장하는 작업을 거칠려고 한다.

■ 사용자가 너무 큰 사이즈의 이미지를 올렸을 때, 적절한 크기와 용량으로 이미지를 변경하는 것이다. 이미지 리사이징은 CPU를 많이 사용하는 작업으로 람다로 분리한다.

 

aws-upload 폴더를 생성해보자.

//package.json

{
  "name": "aws-upload",
  "version": "1.0.0",
  "description": "Lambda 이미지 리사이징",
  "main": "index.js",
  "author": "joo",
  "license": "ISC",
  "dependencies": {
    "aws-sdk": "^2.663.0",
    "sharp": "^0.25.2"
  }
}

 

 

// index.js

const AWS = require('aws-sdk');
const sharp = require('sharp');

const s3 = new AWS.S3();

exports.handler = async(event, context, callback) => {
  const Bucket = event.Records[0].s3.bucket.name;
  const Key = event.Records[0].s3.object.Key;
  const filename = Key.split('/')[Key.split('/').length - 1];
  const ext = Key.split('.')[Key.split('.').length - 1];
  const requiredFormat = ext === 'jpg' ? 'jpeg' : ext; //sharp에서는 jpg대신 jpeg 사용
  console.log('name', filename, 'ext', ext);

  try {
    const s3Object = await s3.getObject({ Bucket, Key }).promise(); // 버퍼로 가져오기
    console.log('original', s3Object.Body.length);
    const resizedImage = await sharp(s3Object.Body) // 리사이징
      .resize(200, 200, {fit: 'inside'})
      .toFormat(requiredFormat)
      .toBuffer();
    await s3.putObject({ // thumb 폴더에 저장
      Bucket,
      Key: `thumb/${filename}`,
      Body: resizedImage,
    }).promise();
    console.log('put', resizedImage.length);
    return callback(null, `thumb/${filename}`);
  } catch (error) {
    console.error(error);
    return callback(error);
  }
};

■ handler 함수가 람다 호출 시에 실행되는 함수이다. 매개변수로 event와 context, callback이 주어진다. event는 호출 상황에 대한 정보가 담겨 있고, context는 실행되는 함수 환경에 대한 정보가 담겨 있다. callback은 함수가 완료되었는 지를 람다에게 알리는 역할을 한다. callback의 첫 번째 인수는 에러 여부를 의미하고, 두 번째 인수는 반환값을 의미한다.

■ event 객체로 부터 버킷 이름과 파일 경로(Key)를 받아온다. 또한, 이들을 통해 파일명과 확장자(ext)도 얻는다.

■ s3.getObject 메서드로 버킷으로부터 파일을 불러온다. s3Object.Body에 파일 버퍼가 담겨져 있다.

■ sharp 함수에 파일 버퍼를 넣고 resize 메서드로 크기를 지정한다.현재 가로와 세로 너비가 200씩 주어져 있다. 하지만 세 번째 인수에 따라 리사이징 된다. 현재 fit: inside를 주었는데 주어진 가로 세로 사이즈 안에 딱 맞게 이미지를 조정하라는 것이다. toBuffer 메서드는 리사이징된 이미지 결과를 버퍼로 출력한다. 

■ s3.putObject 메서드로 리사이징된 이미지를 thumb 폴더 안에 저장한다. 성공적으로 저장이 되면 callback 함수를 호출해 람다 함수가 종료되었음을 알린다.

 

// .gitignore

node_modules

 

위 코드를 생성해본다.

 

이제 람다에 배포를 해야한다. Lightsail에서 빌드하고 S3로 배포하고, 람다는 S3에서 배포된 파일을 가져와 함수로 만들어준다.

> Lightsail에서 빌드하는 이유는 sharp가  윈도우와 맥, 리눅스 용으로 구분되기 때문이다. 

 

■ 깃허브에 코드를 push 한다. 예를 들어 upload-test라는 레포지토리에 push한다.

■ Lightsail 인스턴스 SSH에 접속하여 레포지토리를 clone 받는다.

■ upload-test 폴더 아래의 모든 파일을 압축하여 upload-test.zip 파일을 만든다.

■ Lightsail에서 S3로 파일을 업로드 해보자. 먼저 aws-cli를 설치해야 한다. aws configure 명령어를 입력한 후에 키 파일 정보들을 입력한다.

■ 설정을 다 하면 aws-cli를 사용해서 upload-test.zip을 업로드 한다.

 

 

이제 람다 서비스를 설정해야 한다.

■ aws 서비스에서 Lambda 메뉴로 들어간다.

■ 함수 생성 버튼을 누른다.

■ 함수명은 함수의 용도를 설명하는 이름으로 짓고, 런타임은 Node.js 12.x로 설정한다, 람다는 지원하는 노드 버전에 제약을 두고 있다. 그리고 함수 생성 버튼을 누른다.  

■ 핸들러는 파일명.함수명이어야 합니다.

aws.amazon.com/ko/blogs/compute/node-js-14-x-runtime-now-available-in-aws-lambda/

 

Node.js 14.x runtime now available in AWS Lambda | Amazon Web Services

You can now develop AWS Lambda functions using the Node.js 14.x runtime. This is the current Long Term Support (LTS) version of Node.js. Start using this new version today by specifying a runtime parameter value of nodejs14.x when creating or updating fu

aws.amazon.com

하지만 이제는 Node.js 14.x로도 람다 함수를 개발할 수 있다고 하네요~

 

■ 그럼 아래 사진처럼 생성됩니다.

 

■ 함수 코드 섹션에서 드롭다운을 열고 Amazon S3에서 파일 업로드를 선택해줍니다.

 

- 링크 URL은 <https://버킷명.s3.지역명.amazonaws.com/파일명>형식입니다.

 

■ 기본 설정 섹션을 찾고 편집 버튼을 누릅니다. 

 

■ 실행 역할은 AWS 정책 템플릿에서 새 역할 생성을 선택하고 역할 이름은 맘대로 작성해주셔도 됩니다. 그러고 저장합니다. 

 

■ 이제 S3에 이미지를 업로드할 때마다 람다 함수가 동작하도록 해야 합니다. 상단으로 돌아가 트리거 추가 버튼을 누릅니다.  트리거 구성 화면에서 S3를 선택하고, 버킷에서 우리가 만들었던 버킷을 선택합니다. 이벤트 유형을 모든 객체 생성 이벤트로 설정합니다. 그러면 버킷에 파일이 생성되면 함수가 호출 됩니다. 

 

 

 

 

 

 

 

 

 

Node.js 교과서 개정 2판에 내용을 따릅니다.

'AWS' 카테고리의 다른 글

S3 이미지 업로드  (0) 2021.02.19
S3  (0) 2021.02.10
AWS 소개  (0) 2021.02.04
Comments