Lambda 이미지 리사이징 #1

chu·2021년 4월 30일
0

이번 시간도 나를 위한 정리하는 포스트

배포과정이 거의 마무리가 되어간다. S3를 이용해서 이미지도 서버에 업로드도 해보고 말이지!
이번 포스트는 S3에 업로드 한 원본 이미지가 아닌 리사이징을 하는 과정을 다룬다.
여기서 Lambda라는 AWS에서 제공하는 컴퓨팅 서비스다.

Lambda (람다)

AWS Lambda는 서버를 프로비저닝하거나 관리하지 않고도 코드를 실행할 수 있게 해주는 컴퓨팅 서비스입니다.

라는데 AWS 홈페이지에서 더 많은 내용을 확인할 수 있다.

람다에서는 함수를 생성해서 트리거를 추가하여 트리거한 대상이 작동할 때 람다의 함수가 작동이 된다고 알고 있다.

현재 트리거할 대상은 AWS S3에서 만든 나의 버킷이다. S3에 이미지가 업로드 될 때 람다에서 생성한 함수가 작동을 하고, 이미지를 리사이징을 한다. 여기서 리사이징은 람다에서 하는건 아니고 sharp 라는 패키지로 리사이징한다.

🔎 작업 순서

  1. 프로젝트 폴더 내부에 람다 폴더를 추가로 생성한다.
    ex) project -> front폴더 , back폴더 , lambda폴더
  2. 람다 폴더에 npm init을 통해 package.json을 생성하고, 패키지 두 가지를 설치한다.
    aws-sdk , sharp
  3. index.js 파일을 생성하여 람다 함수 코드를 작성한다.
  4. 깃헙에 커밋 푸시를 해준다.
  5. 터미널에서 ubuntu back 경로에서 git pull하여 업데이트
  6. ubuntu lambda 경로에서 폴더 내부 파일을 zip으로 압축하여, AWS S3 버켓으로 업로드한다.
  7. AWS S3, Lambda에서 설정을 해준다.

1번 2번은 어려운게 없으니 생략을 하겠다.

📌 람다 함수 작성

람다 함수를 위한 코드를 작성해야한다. 일반 자바스크립트 문법으로 진행을 하며, 여기서는 람다에 대한 내부적인 내용을 알면 좋다. 그건 AWS 공식 홈페이지에서 확인할 수 있고, 예제도 있으니 보면 도움이 된다.

여기 자습서를 확인해보세요!

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

// AWS 자체에서 진행되기 때문에 따로 권한 검사는 없다.
const s3 = new AWS.S3();
 
exports.함수명 = async (event, context, callback) => {
  const Bucket = event.Records[0].s3.bucket.name;
  const Key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
  const filename = Key.split('/')[1];
  const ext = filename.match(/\.([^.]*)$/)[1]; // . 제외한 확장자명

  if (ext !== 'jpg' && ext !== 'png' && ext !== 'gif') {
    return console.log(`${ext} 확장자를 지원하지 않습니다. jpg, png, gif 확장자로 이용해주세요.`)
  }

  try {
    const s3Object = await s3.getObject({ Bucket, Key }).promise();
    const resizedImage = await sharp(s3Object.Body)
    .resize(400, 400, { fit: 'inside' })
    .toBuffer();
    await s3.putObject({
      Bucket, // 해당 S3 버켓
      Key: `thumb/${filename}`, // 해당 S3 버켓의 thumb 폴더에 이미지
      Body: resizedImage, // 이미지 데이터
    }).promise();
    return callback(null, `thumb/${filename}`);
  } catch (error) {
    console.error(error)
    return callback(error);
  }
}

하나하나 알아보자.

📍 exports.handler - exports는 그대로하고, 뒤에 붙는 함수명은 추후 설정에도 쓰인다.

📍 event - S3 대상으로 진행하기 때문에, S3에 이미지가 업로드 되는 이벤트 내용이다.

📍 event.Records - Records 내부는 제일 아래에 소개

📍 Bucket - s3 버켓 이름

📍 Key - 경로/이미지파일명.확장자

📍 filename - 위 Key값을 split하여 [경로, 이미지파일명.확장자]로 만들고,
끝에 [1]을 하여 이미지파일면.확장자만 추출한다.

📍 ext - 정규표현식으로 확장자 추출되며, 내부에는 배열이있다. 배열에는 2개 있다.
ex) [0].png / [1]png

📍 s3Object - S3의 bucket과 key 객체를 가져온다.

📍 resizedImage - sharp로 리사이징을 하며, s3Object.Body에 이미지 데이터가 들어있고, sharp에 대해서는 따로 알아보자.

📍 s3.putObject - 채워 넣을 데이터를 넣어주면 된다.

📍 callback - 패스포트의 done같은 역할로 생각하면 된다.

Records

{
  "Records": [
    {
      "eventVersion": "2.0",
      "eventSource": "aws:s3",
      "awsRegion": "us-west-2",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "EXAMPLE"
      },
      "requestParameters": {
        "sourceIPAddress": "127.0.0.1"
      },
      "responseElements": {
        "x-amz-request-id": "EXAMPLE123456789",
        "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "testConfigRule",
        "bucket": {
          "name": "my-s3-bucket",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::example-bucket"
        },
        "object": {
          "key": "HappyFace.jpg",
          "size": 1024,
          "eTag": "0123456789abcdef0123456789abcdef",
          "sequencer": "0A1B2C3D4E5F678901"
        }
      }
    }
  ]
}

이제 함수 코드를 작성했으니 AWS s3에 업로드하는 과정을 알아보자!

📌 s3 업로드

일단 폴더 및 파일을 추가했으니 깃헙에 커밋과 푸시를 해주자. 했다 치고~
우분투에서도 추가 작업을 해줘야한다.

// back에서 git 업데이트
ubuntu@ip주소:~/{githubrepositories}/back$ git pull

// 람다 폴더로 경로 변경
ubuntu@ip주소:~/{githubrepositories}/back$ cd ../lambda

// 람다 폴더 경로
ubuntu@ip주소:~/{githubrepositories}/lambda$

// 람다 폴더에서 패키지를 설치했으니 우분투에서도 해주자.
ubuntu@ip주소:~/{githubrepositories}/lambda$ npm i

// 람다 폴더 내부
ubuntu@ip주소:~/{githubrepositories}/lambda$ ls
-> index.js  node_modules  package-lock.json  package.json

현재 위 내용만 보면 크게 한건 없다. 람다 폴더 내부에 4개의 파일이 있고, 이 파일들을 zip으로 묶어서 AWS에 업로드를 할거다. 여기서 추가적으로 zip, AWS를 설치해야한다.

이제 부터 ubuntu@ip주소:~/{githubrepositories}/lambda 까지 생략하고 $로 기재...
너무 길어서 보기에도 불편!!!

// zip 설치
$ sudo apt install zip

// 파일 묶기 - './*' 꼭 작성
$ zip -r aws-upload.zip ./*
// 람다 폴더 내부
$ ls
-> aws-upload.zip index.js  node_modules  package-lock.json  package.json

// awscliv2.zip 설치 (aws 커맨드를 사용하기 위해서)
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"

// awscliv2.zip 해제
$ unzip awscliv2.zip

// awscliv2 설치
$ sudo ./aws/install

awscli 공식 홈페이지
os별 설치 방법도 확인해보세요! 우분투는 리눅스 기반이기 때문에 리눅스 설치방법으로 진행했습니다.

// 접근 권한 확인
$ aws configure

여기서 네 가지를 확인해야한다

1번, 2번 - 액세스키 발급 받을 때 2가지 키에 대한 값
3번 - region에 대한 값을 적어주면 된다.
(1번 ~ 3번을 모른다면 여기에서 확인!)
4번 - json

// s3에 묶은 zip을 보내자
$ aws s3 cp "aws-upload.zip" s3://S3버켓명

이렇게까지 진행을 했으면 해당 s3 버켓을 확인해보면 zip파일이 들어가 있을 것이다.
이제부터는 AWS 페이지에서 작업을 진행한다.

다음 시간에 이어서 진행을 하겠다!! 이미지 캡처하구 준비해야지!!

profile
한 걸음 한걸음 / 현재는 알고리즘 공부 중!

0개의 댓글