'Problem in serverless function (serverless framework) when using sequelize orm to make requests to the database
I’m trying to set up a simple serverless environment using serverless framework, there is only one lambda function that makes a call to the database using ORM sequelize. Later it will grow.
I can run the entire flow using serverless-offline, it works perfectly, including communication with the database using sequelize. However, when I deploy to AWS and run the function’s endpoint, I get a 502 error in postman and cloudwatch, I don’t get any errors, only information that the function was executed.
I believe the problem is related to the esbuild plugin that is configured in the serverless.ts file and the pg and pg-hstore dependencies.
I will share the serverless.ts files, the file responsible for the function, the database connection file and the model.
serverless.ts:
import type { AWS } from '@serverless/typescript'
const serverlessConfiguration: AWS = {
service: 'sls-certificate',
variablesResolutionMode: '20210326',
frameworkVersion: '3',
plugins: ['serverless-esbuild', 'serverless-offline'],
provider: {
name: 'aws',
runtime: 'nodejs14.x',
region: 'us-east-1',
stage: "${opt:stage, 'dev'}",
apiGateway: {
minimumCompressionSize: 1024,
shouldStartNameWithService: true,
},
environment: {
AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
NODE_OPTIONS: '--enable-source-maps --stack-trace-limit=1000',
},
iamRoleStatements: [
{
Effect: 'Allow',
Action: ['s3:*'],
Resource: ['*'],
},
],
},
package: { individually: false, include: ['./src/template/**'] },
functions: {
generateCertificates: {
handler: 'src/functions/generateCertificate.handler',
events: [
{
http: {
path: 'generateCertificate',
method: 'POST',
cors: true,
},
},
],
environment: {
site_api: '${param:site_api}',
DB_NAME: '${param:DB_NAME}',
DB_HOST: '${param:DB_HOST}',
DB_USER: '${param:DB_USER}',
DB_PASS: '${param:DB_PASS}',
DB_PORT: '${param:DB_PORT}',
stage: '${opt:stage}',
},
},
},
custom: {
esbuild: {
bundle: true,
minify: false,
sourcemap: true,
exclude: ['aws-sdk'],
target: 'node14',
define: { 'require.resolve': undefined },
platform: 'node',
concurrency: 10,
external: ['chrome-aws-lambda', 'pg', 'pg-hstore'],
},
},
}
module.exports = serverlessConfiguration
function
import { APIGatewayProxyHandler } from 'aws-lambda'
import { RegionModel } from '../db/models/RegionModel'
export const handler: APIGatewayProxyHandler = async (
event,
context,
callback,
) => {
console.log('Init Function')
try {
const regions = await RegionModel.findAll({
attributes: ['id', 'region'],
})
console.log('regions', regions)
return callback(null, {
statusCode: 201,
body: JSON.stringify({
regions: regions,
}),
})
} catch (err) {
return err
}
}
Sequelize - connection config:
import { Dialect, Sequelize } from 'sequelize'
const dbName = process.env.DB_NAME as string
const dbUser = process.env.DB_USER as string
const dbHost = process.env.DB_HOST
const dbDriver = 'postgres' as Dialect
const dbPassword = process.env.DB_PASS
const sequelizeConnection = new Sequelize(dbName, dbUser, dbPassword, {
host: dbHost,
dialect: dbDriver,
port: Number(process.env.DB_PORT),
})
export default sequelizeConnection
Model:
import Sequelize from 'sequelize'
import sequelizeConnection from '../config'
export const RegionModel = sequelizeConnection.define('regions', {
id: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true,
},
region: {
type: Sequelize.STRING,
allowNull: false,
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
},
updated_at: {
type: Sequelize.DATE,
allowNull: false,
},
})
EDIT
TIMEOUT ON CLOUDWATCH:
Duration: 50057.30 ms Billed Duration: 50000 ms Memory Size: 1024 MB Max Memory Used: 229 MB Init Duration: 1168.24 ms
Solution 1:[1]
often the default configuration is set up in a way, that you can access the database only from a ip inside the VPC or subnet. Lambda functions are not running on dedicated infrastructure and have therefore some other random ip.
In google cloud a concept of vpc-connector exists to route the traffic from functions into your VPC to the database. I guess there is something similar in AWS.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Simon Hansen |
