5 common pain points with AWS Lambda

Starting without a framework

One of the biggest mistakes made when creating a serverless architecture using AWS Lambda is writing functions without a framework. There are multiple frameworks available to deploy and wire up Lambda functions to the events which will be triggering them. These frameworks handle the deployment of individual Lambda functions, setup of API Gateway to pass through HTTP events or a Cloudwatch Scheduled Event to trigger a Lambda on a cron-job.

At orangejellyfish our favourite is the Serverless framework which allows you to quickly create a serverless architecture on many different FaaS platforms including AWS Lambda, Azure Functions and Google Cloud Functions. It’s quick and easy to get started with, as simple as:

npx serverless create -t aws-nodejs

Logging

By default AWS Lambda logs to AWS Cloudwatch. Unfortunately many people view Cloudwatch as one of the weakest tools in the AWS repository and because of this it can make logging in a serverless architecture a real pain.

By utilising a logging library like Bunyan you can log JSON output displaying the input events and the responses sent, this allows you to easily integrate AWS Lambda into an ELK stack or other third party logging solution.

Bunyan setup can be done in as little as 8 LOC:

import { createLogger } from 'bunyan';

const log = createLogger({
 name: process.env.SERVICE_NAME,
 src: process.env.IS_OFFLINE,
});

export default log;

Large bundle sizes

When starting out with AWS Lambda large bundle sizes aren’t typically a problem, however when your architecture grows and you start to amass a large number of Lambda functions max bundle size starts to become an issue. There is a default deployment size limit of 50MB.

To get around this you can utilise webpack to bundle each entrypoint/Lambda into its own file. Another added benefit of individual bundling is faster deployment and spin up of individual functions meaning you can update and deploy just a single function instead of the entire architecture.

You can enable this in the Serverless framework with the serverless-webpack plugin like this:

# serverless.yml
package:
 individually: true

API Gateway rejects your response

It’s possible for API Gateway to return an error 502 Bad Gateway, which states that the response the Gateway received from your Lambda is malformed. The biggest cause for this that I encountered when getting started with AWS Lambda is the requirement to return a string as the body of the request. It’s a good idea to create helper functions to format your responses and add any extra appropriate headers like CORS.

This helper function adds a CORS Access Control header and stringifies the payload:

const handler = (
  callback,
  status = 200,
  headers = {},
  body = ''
) => {
  callback({
    statusCode: status,
    headers: {
      'Access-Control-Allow-Origin': '*',
      ...headers
    },
    body: typeof body !== 'string' ? JSON.stringify(body) : body,
  });
}

Local development

Many of the frameworks mentioned above, as well as AWS’s own AWS SAM Local allows for offline execution of your serverless application which assists with being able to replicate and investigate issues encountered when running your serverless application on AWS Lambda with API gateway.

When using the Serverless framework there’s a plugin called serverless-offline which emulates AWS Lambda and API Gateway for local development. Getting started is as simple as adding the plugin and running:

sls offline start

This means you can easily attach a debugger to view event execution in real time.

AWS SAM Local offers a more comprehensive event emulation allowing you to emulate events from S3, API Gateway, DynamoDB and more. It does however also require a lot of the same configuration as serverless, with a yaml file to list all Lambda functions stating the runtime they use and the events they receive.

If working with functions using a framework like Serverless excites you, and it’s something you’d like to do more of, we’d love to hear from you hello@orangejellyfish.com.

Twitter