author
postNo
status
thumbnail
description
category
tags
createdAt
updatedAt
시작하기에 앞서
스터디에서 혹은 개인, 팀을 이뤄서 프로젝트를 하는 경우가 종종 있습니다. 그럴 때 고민되는 게 API 서버를 어디에 어떻게 올릴 것인가에 대한 문제이죠.
테스트, 개인용 프로젝트인데 AWS에서 저렴하게 EC2 하나를 생성하더라도 한 달에 최소 몇 만원 정도는 비용이 발생합니다.
이 비용조차 아까워지기 마련이죠. 그래서 더 저렴한 방법은 없을까 고민해 보았어요.
Why Lambda?
API 서버를 띄우기 위해 AWS EC2를 받았다고 가정해 봅시다.

메모리가 2기가 정도는 되어야 하기에
t4g.small사양으로 할당받았다고 가정해 보면, 한 달 사용료는 0.0208 24 30 = $14.976 가 발생합니다. 대략 2만원 정도 발생합니다.
하루에 1~2번 호출될 서버에 2만원도 과하다고 생각할 수 있어요.
그럼, AWS Lambda 가격도 살펴보겠습니다.

lambda 는 무기한 프리티어를 제공합니다.
즉, 월별 100만건 요청까지는 무료이고, 그 이후로는 100건당 $0.20 가 발생합니다.
($0.20 per 1 million requests thereafter, or $0.0000002 per request)이는 사이드프로젝트에서 사용하기에 충분한 요청량으로 보이고 또한 월 100만건 요청이 들어오고, 추가 요청까지 들어온다면 충분히 요금을 더 낼 의사가 있습니다. (사이드프로젝트의 성공일까요)
요청이 1건이던 100건이던 상관없이 항상 서버 비용을 내야하는 EC2와 비교해서, 실행 횟수에 따라 요금을 책정하는 Lambda는 사이드프로젝트에서 사용하기 더 적절해보입니다.
물론 Lambda의 요금 책정은 단순히 요청 횟수 뿐 아니라, 호출에 대한 실행시간도 비용이 영향을 미칩니다.
실행 시간은 요청이 들어오고, 리턴이 나가는 시간까지의 비용입니다. 아래에서 더 자세히 설명합니다.

월별 10,000건의 호출이 호출당 2초가 걸린다고 가정해보고 계산해보아도 월 0원이 발생하는걸 볼 수 있습니다.
(참고) AWS Pricing
- <a href="https://aws.amazon.com/ko/lambda/pricing/" target="_blank">AWS Lambda Pricing</a>
- <a href="https://aws.amazon.com/ko/ec2/pricing/on-demand/" target="_blank">AWS EC2 Pricing</a>
AWS Lambda Service
그럼 위에서 설명한 Lambda는 뭐하는 서비스이길래 EC2보다 더 저렴하게 사용할 수 있을까요?
Lambda Service에 대해 AWS 공식 홈페이지에는 아래와 같이 설명하고 있습니다.
즉, serverless로 함수를 실행할 수 있도록 해주는 AWS 서비스입니다.
(cloud에 많은 serverless라고하는 서비스들은 실제로 서버가 없다는 뜻은 아닙니다. 사용자가 서버를 관리하지 않아도 된다는 의미지요)
여기서 중요한건
함수 를 실행하는 것입니다.handler 함수를 통해 event를 받아 어떠한 작업을 한 후 return값을 돌려줄 수 있습니다.
하지만, 우리가 실행하고싶은건 단순히 함수 1개가 아니라 서버였습니다. (endpoint가 무수히 많은 api 서버 1대 말이죠.)
그래서 예전에는 실제로 한개의 웹/앱 서비스를 구성하기위해 무수히 많은 lambda 함수를 사용하기도 했었습니다.
본 글에서는 이 방법이 아닌 Serverless npm 모듈을 사용해서 함수가 아닌 NestJS 프로젝트를 Lambda 한개의 서비스로 담아 배포하는 방법에 대해 설명하려 합니다.
(참고) AWS Lambda
- <a href="https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/welcome.html?tag=mochaglobal20-20" target="_blank">AWS Lambds란 무엇입니까?</a>
- <a href="https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/nodejs-handler.html" target="_blank">AWS Lambda Function Handler (Node.JS)</a>
그럼 Lambda가 무조건 좋은걸까?
결론부터 말씀드리면 꼭 그렇지는 않습니다.
이런 Lambda역시 단점이 존재합니다. 바로 Cold Start의 문제입니다.
Lambda 의 실행순서를 보면 다음과 같습니다.

Lambda 함수 호출되면 ECR 혹은 S3에서 소스코드를 읽어와서 실행을 준비합니다. 그리고 설정된 서버구성(RAM 등)을 읽어와 서버를 구성합니다. 마지막으로 Hander코드를 통해 함수가 실행된 후 결과를 리턴하죠.
즉, 소스코드를 읽어와 서버를 구성하고 실행하는데까지 어느정도의 시간이 필요합니다. 이렇게 실행되는것을
Cold Start 라고 하고, 이 과정으로 인해 Latency 가 발생합니다.Lambda는 함수 호출이 끝난 다음에는 해당 서버를 즉시 내리지 않고 잠시 기다립니다. 서버가 완전히 내려가기 전에, 해당 함수가 다시한번 더 호출되면 이번엔 소스코드를 읽어오는 과정이 생략되고 서버를 재사용하여 함수가 즉시 실행될 수 있습니다. 그리고 이렇게 실행되는걸
Warm Start라고 부릅니다. 이 때에는 서버구성하는 과정이 빠지기 때문에
Cold Start보다 더 빠르고, Latency 가 발생하지 않습니다. 
(출처: AWS)
이처럼 자주 사용되는 함수는 Warm Start로 빠르게 응답을 주는 반면, 가끔 호출되는 함수의 경우 Cold Start로 실행되어 첫 호출에는 결과받는데 시간이 조금 걸립니다 (1초 이상 걸릴 수 있습니다)
그리고 Warm Start로 게속 실행되는 함수 (주기적으로 호출되어서)라고 하더라도 lambda에 새로운 코드가 배포되면 Cold Start로 동작합니다.
그 외에도 동시성에 대한 호출 역시 Cold Start로 실행될 수 있는데, 아래 링크의 AWS 공식문서를 참고 바랍니다.
참고
- <a href="https://aws.amazon.com/ko/blogs/compute/operating-lambda-performance-optimization-part-1/" target="_blank">AWS Lambda Performance Part1</a>
NestJS, Serverless, AWS Lambda
NestJS
NestJS는 TypeScript 언어를 사용해 API 서버를 손쉽게 구성할 수 있는 Framework입니다.
Serverless
Serverless 는 어떤 프로젝트를 serverless 로 실행할 수 있도록 구성해주는 프레임워크 입니다. (여기서는 NestJS 를 사용하지만 express와 같은 다른 프로젝트도 모두 사용가능합니다.)
이 npm 모듈을 사용해서 NestJS를 serverless로 실행할 수 있는 구성을 하고, Lambda로 배포할 수 있습니다.
(참고)
- <a href="https://github.com/serverless/serverless" target="_blank">Serverless Github Repository</a>
- <a href="https://github.com/nestjs/nest-cli" target="_blank">Nest Cli Github Repository</a>
- <a href="https://serverless.com/" target="_blank">Serverless.com</a>
환경 구성
NestJS Application 프로젝트 생성
nest cli 명령어를 통해 프로젝트를 생성해줍니다.
nest new aws-sample 만약 nest 명령어가 없다면 nest cli 를 먼저 설치합니다.
npm install -g @nestjs/clinest start 롤 통해 생성된 서버를 실행할 수 있고, curl http://localhost:3000으로 잘 실행되는지 확인합니다.AWS account 설정

코드 배포를 위해 AWS 사용자를 생성합니다. AWS의 IAM 서비스로 들어가 새로운 사용자를 생성하고, keyId, secretId 를 잘 저장합니다.

사용자를 추가하고, 필요한 권한을 추가합니다.
(본 글에서 Serverless를 통해 AWS Lambda 서비스로 배포하기 위해서는, S3, Lambda, API Gateway 등의 권한이 필요합니다)
(참고) create user on AWS IAM
- <a href="https://www.youtube.com/watch?v=KngM5bfpttA" target="_blank">IAM 사용자 생성 Youtube 영상</a>
NestJS Application 배포를 위한 serverless 설정

마지막으로 NestJS 프로젝트에 AWS Lambda로 배포하기위해 Serverless Framework 를 세팅합니다.
우선 serverless를 설치합니다.
이후 설치된 serverless 는 sls 라는 명령어를 통해 실행이 가능합니다.
구성을 위해 몇가지 파일을 추가합니다.
- serverless 가 배포될 때 실행할 함수, 배포할 타겟을 지정
serverless.yaml
서울로 배포하기위해 region 설정을
ap-northeast-2를 사용합니다. stage 설정을 통해 env를 분리해서 사용할 수 있습니다.
- 일부 오류처리를 위한 tsconfig 설정 추가
tsconfig.json
(아래 자세한 오류 내용 설명)
- labmda로 요청들어오는 event를 nestjs 컨트롤러로 연결하기 위한 설정
src/lambda.ts
오류 처리
tsconfig.json에
"tsBuildInfoFile": ".tsbuildinfo", 설정을 통해 해결합니다.- 참고 <a href="https://github.com/serverless/serverless-plugin-typescript/issues/236" taget="_balnk">github</a>
tsconfig.json에
"esModuleInterop": false 설정을 통해 해결합니다. - 참고 <a href="https://stackoverflow.com/questions/63744824/getting-express-default-is-not-a-function-error-when-i-run-node-server-in-a-co" taget="_balnk">github</a>
AWS profile 설정
serverless 배포를 위해 위 AWS에서 만든 profile key정보를 설정합니다.
명령어를 통해 프로필을 설정할 수 있습니다.
실행하고나면
~/.aws 경로에 credentials 파일이 생성됩니다. 열어보면 default 가 생겨있을거에요.ex)
만약 이미 파일이 있어서 위 명령어 실행이 안된다면, -o 옵션을 붙여주면 됩니다. (override option)
Deploying to AWS
마지막으로
sls deploy 명령어를 통해 배포할 수 있습니다.
AWS Lambda로 가보면 잘 배포된걸 확인할 수 있습니다.
전체가 동작하는 과정은 아래 그림과 같습니다.

참고
- <a href="https://github.com/kyung-yeon/nestjs-serverless-lambda" target="_blank">nestjs-serverless-lambda example</a>