프로필사진
DevOps 부트캠프 기록일지
DevOps_04_김재환
2023.05.11(서버리스 사진첩)
2023.05.11(서버리스 사진첩)

2023. 5. 12. 06:18부트캠프/DevOps (TIL)

주요기능

우리가 만들려는 서버리스 사진첩 서비스는, 여느 클라우드 사진 저장 서비스들처럼 단순히 사진을 업로드하는 것 외에도, 인증 기능과 썸네일 생성 기능을 제공합니다

 

Getting Started

1. sam init 명령을 이용해 Quick Start Template으로부터 Standalone function을 하나 생성합니다.

2. lambda 함수의 파라미터를 정의합니다. 이는 이벤트 소스로부터 트리거가 발생했을 때 이벤트의 형태를 확인하기 위함입니다. 다음과 같이 코드를 작성합니다.

exports.helloFromLambdaHandler = async (event, context) => {
    console.log(event)

    console.log(context)

    return 'Hello from Lambda!';
}

3. sam build 후 sam deploy --guided 로 빌드 후 배포합니다.

4.S3 버킷을 하나 만들고, 트리거로 연결합니다. 다음과 같이 설정합니다.

5. 이제 해당 버킷에 jpeg 이미지를 하나 올리면, 람다 함수가 실행됩니다.

6. eventcontext가 어떻게 콘솔에 출력되는지 확인하기 위해 "모니터링" 탭의 "CloudWatch에서 로그 보기"를 클릭하여 로그를 확인합니다.

  • 테스트" 탭 내 템플릿에서 S3 이벤트가 마련되어 있어서, 실제로 jpeg 이미지를 올리지 않고도 이벤트를 흉내 낼 수(mocking) 있습니다.

7. event 객체 내용을 확인했다면, 이를 바탕으로 썸네일 생성 코드와, 버킷 저장 코드를 활용하여 썸네일 생성을 목적으로 하는 람다 함수를 작성합니다.

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

// get reference to S3 client
const s3 = new AWS.S3();

exports.helloFromLambdaHandler = async (event, context) => {
    console.log(JSON.stringify(event))
    let s3Object = null
    let data = null
    let result = null

     // 원본 버킷으로부터 파일 읽기
    try {
        const s3Object = await s3.getObject({
            Bucket: "serverless-photo",
            Key: "test.jpeg"
          }).promise()
    } catch (e) {
        console.log(e)
 }      

  
  // 이미지 리사이즈, sharp 라이브러리가 필요합니다.
    try {
        const data = await sharp(s3Object.Body)
        .resize(200)
        .jpeg({ mozjpeg: true })
        .toBuffer()
    } catch (e) {
        console.log(e)
    }      

  
  // 대상 버킷으로 파일 쓰기
    try {
        const result = await s3.putObject({
            Bucket: "serverless-photo-target", 
            Key: "test.jpeg",
            ContentType: 'image/jpeg',
            Body: data,
            ACL: 'public-read'
          }).promise()
    } catch (e) {
        console.log(e)
    }      


    return { statusCode: 200, body: result };
}

기존 hello-from-lambda.js 또는 app.js을 위와 같이 수정해줍니다.

이때 원본 버킷과 이미지를 리사이즈하고 업로드할 타겟 버킷을 따로 생성해주고 버킷 이름을 넣어줍니다.

이때 aws-sdk와 sharp가 설치되어 있지 않으면 에러가 뜨기 때문에 터미널에서 aws-sdk 설치 후 sharp도 설치해 주도록 합니다.

- m1와 windows 환경에서는 npm install sharp로 설치하면 아래와 같은 에러가 발생하기 때문에 따로 해주어야하는 설정이 있다.

터미널에서 npm install --platform=linux --arch=x64 sharp 로 설치해주도록 하자!

만약 이미 npm install sharp을 한 상태면 npm uninstall sharp을 해주고 설치하도록 하면 에러가 발생하지 않을 것입니다.

그래도 발생한다면

"dependencies": {
        "aws-sdk" : "^2.1111.0",
        "sharp": "^0.30.3" //<-제거
    }

packge.json 파일에서 sharp 항목을 삭제 후 다시 빌드, 배포를 진행하면 오류가 발생하지 않을것입니다.

 

AccessDenied라는 권한 에러가 발생했습니다.

  • A. 우리가 만들려는 람다 함수는 S3 버킷의 접근 권한이 필요합니다.

해당 역할에 s3 관련 권한을 직접 추가하거나 sam build 및 deploy 때 바로 생성할 수 있도록 template.yaml의 Policies 아래 항목에 아래와 같이 추가 후 빌드 배포하여 추가할 수 있습니다.

만약 AccessControlListNotSupported라는 권한 에러가 발생한다면 S3에서 객체 소유권 편집 기능을 이용해 ACL을 활성화하고, 소유권은 "버킷 소유자 선호"로 바꿔주면 됩니다.

 

이제 s3 원본 버킷에 하드코딩한 test.jpeg 파일을 업로드하면 썸네일 이미지가 타겟 버킷에 생성 됩니다.