어제 티스토리 서버가 불안정하길래 어제 TIL은 워드에다 작성했는데 날아갔다..
요약하자면 Express, MySQL, Redis로 이루어진 앱을 AWS 상으로 올리는 중이다.
Express는 Serverless 프레임워크를 통해 AWS Lambda + API Gateway로 변환,
MySQL은 RDS로,
Redis는 ElastiCache로 Migrate하기로 하였다.
Serverless Framework로 Express Lambda+ API Gateway 변환하기
serverless-http라는 라이브러리로 Express를 Serverless 용도로 Wrap할수 있다.
import * as ServerlessHttp from 'serverless-http';
import 'source-map-support/register';
import app from './src/app';
export const handler = ServerlessHttp(app);
이렇게 감싸주는 것으로 handler 작성을 끝낼수 있다.
service:
name: serverless
useDotenv: true
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
serverless-offline:
httpPort: 4000
plugins:
- serverless-webpack
- serverless-offline
provider:
name: aws
runtime: nodejs12.x
region: us-west-2
apiGateway:
minimumCompressionSize: 1024
environment:
AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1
functions:
hello:
handler: handler.handler
events:
- http: ANY /
- http: 'ANY /{proxy+}'
이제 serverless의 yml을 작성하여 AWS CloudFormation 템플릿을 생성한다.
useDotEnv
local 상태에서 .env의 환경 변수를 사용하게 해줌
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
webpackConfig는 웹팩 설정의 위치를 정의하고,
includeModules는 자동으로 external modules을 packing함. 기본적으로 package.json을 사용함.
serverless-offline:
httpPort: 4000
배포를 하기전 serverless-offline이라는 플러그인을 통해서 로컬 환경에서 서버리스 프레임워크를 테스트할 수 있는데, 이때 서버의 포트 번호를 httpPort를 통해 설정할 수 있다.
provider:
name: aws
runtime: nodejs12.x
region: us-west-2
apiGateway:
minimumCompressionSize: 1024
environment:
AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1
region을 통해 지역을 설정,
minimumCompressionSize는 REST API에 대한 최소 압축크기를 설정한다.
AWS_NODEJS_CONNECTION_REUSE_ENABLED는
Node.js HTTP 에이전트는 모든 새 요청에 대해 새 TCP 연결을 하는데, 이것이 다 비용이므로 기존 연결을 재사용할 수 있도록 설정해주는 환경변수다.
functions:
hello:
handler: handler.handler
events:
- http: ANY /
- http: 'ANY /{proxy+}'
functions에서는 Lambda function을 설정하는데,
handler는 아까 우리가 Wrap한 app의 handler의 위치를 설정해준다.
events는 function이 동작할 trigger을 의미하는데,
우리는 handler가 모든 내부의 라우터 등을 모두 처리할 것이기 떄문에 모든 하위 URL에 대하여 트리거되도록 하였다.
Node.js에서 연결 유지를 이용해 연결 재사용 - AWS SDK for JavaScript
이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.
docs.aws.amazon.com
const path = require('path');
const slsw = require('serverless-webpack');
const nodeExternals = require('webpack-node-externals');
module.exports = {
context: __dirname,
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
entry: slsw.lib.entries,
devtool: slsw.lib.webpack.isLocal
? 'eval-cheap-module-source-map'
: 'source-map',
resolve: {
extensions: ['.mjs', '.json', '.ts'],
symlinks: false,
cacheWithContext: false,
},
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, '.webpack'),
filename: '[name].js',
},
target: 'node',
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.(ts)$/,
loader: 'ts-loader',
exclude: [
[
path.resolve(__dirname, '/node_modules'),
path.resolve(__dirname, '.serverless'),
path.resolve(__dirname, '.webpack'),
],
],
options: {
transpileOnly: true,
experimentalWatchApi: true,
},
},
],
},
};
웹팩은 이런식으로 작성할수 있다.
개발빌드일떄는 보다 빠른 eval-cheap-module-source-map를, 프로덕션에는 source-map을 사용하였고,
ts-loader는 transpileOnly로 트랜스파일링만 하고, type check는 fork-ts-checker-webpack-plugin을 사용하며
experimentalWatchApi로 파일이 변경되면 내부의 watch API를 통해 변경된 파일만 재컴파일하여 Webpack의 번들링 속도를 높일수 있다.
serverless를 전역으로 설치하고
AWS IAM에서 사용자를 생성하고 받은 키와 키ID로
serverless config credentials --provider aws --key ACCESS_KEY --secret SECRET_KEY
를 통해서 serverless가 AWS에 접근할 수 있도록 설정해준다.
그리고 serverless deploy를 통해서 Express로 만든 serverless를 AWS에 deploy할수 있다.
RDS와 Redis가 모두 제대로 설정이 되어있어야 Lambda Function이 제대로 작동하는데, RDS만 설정해놓고 왜 안되지 시간 낭비하다가 CloudFront log를 보고 알았다... 항상 에러 로그를 잘 보자..
Lambda Bcrypt 불가능 이슈
Bcrypt 라이브러리를 사용한 앱을 deploy하면
invalid ELF Header라는 에러와 함께 람다 함수가 작동 안되는 이슈가 발생하였다.
윈도우 상에서 하면 안되고 Linux 상에서 설치하면 된다는데, Lambda는 리눅스 상에서 작동하고, window 측의 node package가 linux 측의 패키지와 다르기 떄문이라고 한다.
bcryptjs라는 dependency가 없는 다른 라이브러리를 사용하면 된다.
'TIL' 카테고리의 다른 글
TIL 2022-01-07 MySQL Case Sensitivity, OAuth, OAuth2.0 (0) | 2022.01.07 |
---|---|
TIL 2022-01-06 NextJs API, Typescript 제네릭 함수, git ignore 적용 (0) | 2022.01.07 |
TIL 2022-01-03 AWS EC2, RDS, API Gateway, Lambda (0) | 2022.01.04 |
TIL 2021-12-29 Github Action Release, __dirname is not defined (0) | 2021.12.29 |
TIL 2021-12-28 Github-action, Cron (0) | 2021.12.29 |