In this tutorial, we’ll explore how to use AWS Lambda Layers to organize and reuse code across multiple AWS Lambda functions. Specifically, we’ll move DynamoDB queries to a separate Lambda Layer and integrate it with a Serverless API. This approach enhances maintainability and promotes code reuse, making your serverless applications more scalable and efficient.
Overview
Our solution involves creating a Lambda Layer containing DynamoDB operations (list, add, and get countries) and integrating this layer with our existing Serverless API. We will define the required resources using the Serverless Framework and deploy them to AWS.
Architecture
- A DynamoDB table to store country information.
- A Lambda Layer to encapsulate DynamoDB operations.
- Multiple Lambda functions to handle API requests (add, list, get countries).
- API Gateway to expose these Lambda functions as RESTful endpoints.
Directory Structure
Here is the directory structure for our project:
Step-by-Step Guide
1. Create a Separate Folder for Lambda Layers
Create a folder named Dynamo_layer and add the following:
- A folder named modules-layer.
- A folder named dynamo-sdk-layer.
- A serverless.yml file.
2. Add Layers Resources in serverless.yml
In the Dynamo_layer directory, add the following content to serverless.yml:
# Service name has to be unique for your account.
service: my-dependencies
# framework version range supported by this service.
frameworkVersion: ">=1.1.0 <8.0.0"
# configuration of the cloud provider. As we are using AWS so we defined AWS corresponding configuration.
provider:
name: aws
lambdaHashingVersion: 20201221
runtime: nodejs14.x
#stage: dev
region: us-east-2
# Create an ENV variable to be able to use it in my JS code. *** Check line 4 in get-country-by-name JS file ***
environment:
tableName: ${self:custom.tableName}
# To Give a permission to each lambda function to access DynamoDB table
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:*
# - dynamodb:Query
# - dynamodb:Scan
# - dynamodb:GetItem
# - dynamodb:PutItem
Resource: "*"
layers:
ModulesLayer:
path: ./modules-layer
description: "my dependencies"
DynamoSdkLayer:
path: ./dynamo-sdk-layer
description: "my dynamo dependencies"
custom:
tableName: countries
3. Deploy Lambda Layers
Deploy the Dynamo_layer to create a CloudFormation stack for Lambda Layers by running the following command:
sls deploy
4. Navigate to the my-service folder, which contains the serverless.yml file for your API Gateway endpoints and Lambda functions.
Ensure the configuration includes:
- A DynamoDB table.
- Lambda functions for countries_loadData, add-country, list-countries, and get-country-by-name.
serverless.yml
# Service name has to be unique for your account.
service: my-service
# framework version range supported by this service.
frameworkVersion: ">=1.1.0 <8.0.0"
# configuration of the cloud provider. As we are using AWS so we defined AWS corresponding configuration.
provider:
name: aws
lambdaHashingVersion: 20201221
runtime: nodejs14.x
#stage: dev
region: us-east-2
# Create an ENV variable to be able to use it in my JS code. *** Check line 4 in get-country-by-name JS file ***
environment:
tableName: ${self:custom.tableName}
NODE_PATH: "./:/opt/node_modules"
# To Give a permission to each lambda function to access DynamoDB table
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:*
# - dynamodb:Query
# - dynamodb:Scan
# - dynamodb:GetItem
# - dynamodb:PutItem
Resource: "*"
# package:
# exclude:
# - Dynamo-SDK/**
custom:
tableName: countriees
# As shown below, when the HTTP POST or GET request is made, the handler should be invoked.
functions:
#(1) Lambda function to initially fill DynamoDB
FillDynamoDB:
handler: lambdas/countries_loadData.fill
description: fill DynamoDB table with set of countries.
events:
- http:
path: fill-dynamoDB
method: POST
cors: true
layers:
- arn:aws:lambda:us-east-2:<ACCOUNT-ID>:layer:ModulesLayer:3
- arn:aws:lambda:us-east-2:<ACCOUNT-ID>:layer:DynamoSdkLayer:3
#(2) Lambda function to list all the countries
GetAllCountries:
handler: lambdas/list-countries.list
description: get all the countries information.
events:
- http:
path: list-countries
method: GET
cors: true
layers:
- arn:aws:lambda:us-east-2:<ACCOUNT-ID>:layer:ModulesLayer:3
- arn:aws:lambda:us-east-2:<ACCOUNT-ID>:layer:DynamoSdkLayer:3
#(3) Lambda function to get a country by name
GetCountryByName:
handler: lambdas/get-country-by-name.get
description: get country By Name.
events:
- http:
path: get-country/{NAME}
method: GET
cors: true
layers:
- arn:aws:lambda:us-east-2:<ACCOUNT-ID>:layer:ModulesLayer:3
- arn:aws:lambda:us-east-2:<ACCOUNT-ID>:layer:DynamoSdkLayer:3
#(4) Lambda function to add a new country
AddNewCountry:
handler: lambdas/add-country.add
description: add a new country.
events:
- http:
path: add-country
method: POST
cors: true
layers:
- arn:aws:lambda:us-east-2:<ACCOUNT-ID>:layer:ModulesLayer:3
- arn:aws:lambda:us-east-2:<ACCOUNT-ID>:layer:DynamoSdkLayer:3
#Resources are AWS infrastructure components which your Functions use.
#The Serverless Framework deploys an AWS components your Functions depend upon.
resources:
Resources:
myDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
#DeletionPolicy: Retain
Properties:
TableName: ${self:custom.tableName}
AttributeDefinitions:
-
AttributeName: "NAME"
AttributeType: "S"
KeySchema:
-
AttributeName: "NAME"
KeyType: "HASH"
BillingMode: PAY_PER_REQUEST
# Custom resource to invoke lambda function to fill the countries DynamoDB table
TriggerFillDynamoDBFunction:
Type: AWS::CloudFormation::CustomResource
Properties:
ServiceToken: !GetAtt 'FillDynamoDBLambdaFunction.Arn'
5. Deploy Serverless API
Deploy the serverless configuration by running:
sls deploy
6. Access API Endpoints
You can access the endpoints using the following URLs:
List countries: GET
https://nymaeazapc.execute-api.us-east-2.amazonaws.com/dev/list-countries
Get country by name: GET
https://nymaeazapc.execute-api.us-east-2.amazonaws.com/dev/get-country/{NAME}
Add a country: POST
https://nymaeazapc.execute-api.us-east-2.amazonaws.com/dev/add-country
7. Remove All Functions, Events, and Resources
To clean up, remove all AWS resources created by running:
sls remove
Conclusion
By following these steps, you have successfully utilized AWS Lambda Layers to modularize and reuse DynamoDB queries across multiple Lambda functions. This approach demonstrates the power of Lambda Layers in promoting code reuse and maintainability, making your serverless applications more efficient and scalable.
Top comments (1)
Very nice, i will try, thanks!