[Serverless] 'Serverless' 프레임워크로 s3 presigned url 발급 함수 배포하기

가영·2022년 7월 22일
1
post-thumbnail

이미지 업로드를 서버에서 하는 것은 좋지 않다. 그 이유는 내 예전 글에서 볼 수 있음

이번에도 똑같이 하려고 했으나 직접 만드는 법을 까먹었다. 전에는 aws 콘솔에서 직접 람다 펑션을 작성해줬었다. 근데 생각해보면 이미지 업로드 펑션을 전세계의 많은 개발자가 이미 구현을 많이 해뒀을 것 같았다. 그래. 내가 만든 덜떨어진 함수보다는 똑똑한 사람들이 이미 만들어둔 걸 쓰는게 낫겠다는 생각이 들었다.

바로 구글링

역시 똑똑한 다른 개발자가 만들어둔 샘플이 있었다.
심지어 유튜브에서 설명까지 해줌

샘플 코드는 깃허브에서 확인할 수 있었다.

내가 사용할 샘플 코드는 s3-signed-url이다.

signedUrl을 사용하면 aws 권한이 없는 클라이언트에서도 이미지를 버킷에 업로드 할 수 있다.

다음 샘플코드는 클라의 요청을 처리하는 코드인 셈이다.

handler.js 를 보면

module.exports.createPostUrl = async (event) => {

  const client = new S3Client(clientParams);
  const Key = `${prePath}${(Math.random() + 1).toString(36).substring(2)}`
  const { url, fields } = await createPresignedPost(client, {
    Bucket: config.S3_BUCKET,
    Key,
    Expires: 600, //Seconds before the presigned post expires. 3600 by default.
  });
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        url,
        fields
      },
      null,
      2
    ),
  };
};

쉽다. s3클라이언트를 생성 후, signed url 발급받아서 응답에 포함시켜주는 로직이다

그리고 이 레포를 보면 serverless.yml 이 있는데 이걸 어떻게 사용하는지는 간단히 설명하려 한다.

Serverless Framework

나는 서버리스가 프레임워크 이름인줄 처음 알았다. 보니까 짱 편해보이더라. 앞으로 람다는 이걸로 올릴 것 같다.

서버리스 프레임워크 공식 홈페이지

서버리스 프레임워크 사용법은 간단하다.

  1. serverless를 설치한다.
  2. 배포하고자 하는 함수가 있는 곳에 yml 설정파일을 정의한다.
  3. (원래 돼있다면 하지 않아도 됨) 원하는 프로바이더의 권한 설정을 한다.
    나는 aws 였고, aws profile 설정이 이미 되어있어서 하지 않아도 되었다.
  4. serverless deploy 명령어 갈기면 배포가 됨..
  5. 믿을 수 없다면 aws 콘솔로 달려가 확인해보셈 그럼 함수가 정의돼있을 것

간단히 미리 얘기해보았는데, 조금 더 자세히 보자

1. serverless 설치

npm install -g serverless

serverless 대신 sls 를 사용해도 된다.
설치를 확인하기 위해 버전을 확인해보세요.

sls --version

2. yml 정의하기

나는 이미 샘플코드에 yml이 정의 돼있었다. 근데 저게 좀 오래된거라 프레임워크 버전에서 에러가 났다. 난 그냥 주석처리 했다.

service: s3-signed-url
frameworkVersion: '2' # (1) 여기서 에러가 터질것이다.

provider:
  name: aws
  runtime: nodejs12.x
  lambdaHashingVersion: 20201221
  stage: ${file(config.json):STAGE}
  region: ${file(config.json):REGION}
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "s3:GetObject"
        - "s3:GetObjectVersion"
        - "s3:PutObject"
      Resource:
        - "arn:aws:s3:::${file(config.json):S3_BUCKET}/*"


functions: # 배포 할 함수들
  create-get-url: # 이건 내가 쓰진 않을 거라 뺐다. 쓸거면 쓰셈 (사진 조회도 권한 설정이 되어있는 경우 사진 조회하는 url을 얻는 함수)
    handler: functions/handler.createGetUrl
    events:
      - http:
          path: /object/{fileKey}
          method: get
          cors: true
          request:
            parameters:
              paths:
                fileKey: true 
  create-post-url: # presigned url을 반환하는 함수! 내가 사용할 것.
    handler: functions/handler.createPostUrl
    events:
      - http:
          path: /upload-url
          method: get
          cors: true      

3. aws 프로필 설정하기

serverless 프로그램이 우리의 코드를 aws에 배포하기 위해서는 당연히 권한이 필요하다.

이건 그냥 서버리스 공식문서보고 따라하면 된다.

나는 이미 돼있어서 스킵 ㅎㅎ

4. 이제 serverless로 배포

로컬에서 테스트

serverless invoke local --function create-post-url

진짜 편하다.. 이렇게 하면 배포 전에 로컬로 테스트를 해볼 수 있다.
명령어를 실행해보자구.

잘되는지 확인됐다면, 배포를 해보쟈꾸

서버리스 애플리케이션 배포

sls deploy --aws-profile serverless

잘되면 이렇게 뜸

Deploying s3-signed-url to stage dev (ap-northeast-2)

✔ Service deployed to stack s3-signed-url-dev (142s)

endpoints:
  GET - https://pseqcwj9sc.execute-api.ap-northeast-2.amazonaws.com/dev/object/{fileKey}
  GET - https://pseqcwj9sc.execute-api.ap-northeast-2.amazonaws.com/dev/upload-url
functions:
  create-get-url: s3-signed-url-dev-create-get-url (17 MB)
  create-post-url: s3-signed-url-dev-create-post-url (17 MB)

2 deprecations found: run 'serverless doctor' for more details

Monitor all your API routes with Serverless Console: run "serverless --console"

끝임. 진자 끝임 우하하

그럼 어떻게 사용할까?

포스트맨으로 테스트를 해보았다.

handler에 정의 된 것처럼, 람다 요청 url로 get 요청을 보내면 됨.

그러면 이렇게 필요한 정보들이 응답에 온다.

우리는 이제 이 정보들을 헤더에 넣어 s3에 파일을 등록할 수 있다.

파일 생성 요청이라 204로 응답 바디는 없다. 하지만 잘 된 것이니 웃으면 된다.

비록 우리는 포스트맨으로 테스트 했기 때문에 하나하나 입력해줘야 했지만 클라이언트에서 코드로 구현하면 뚝딱이기 때문에 어려운 요청은 아니니 적용해볼 수 있다면 해보기를 추천!

0개의 댓글