I've been playing a lot with the Serverless framework since they moved from v0.x to v1 (which is currently in beta). I really like the direction they've taken it, and have been using it for my own projects.
One of the first things I wanted to do was hook my functions up to a data source: DynamoDb (DDB). While DDB is an obvious choice for a server-less application, keep in mind it's definitely not for all use-cases.
Here's a quick step by step guide to giving your Serverless Service DDB access:
Create Resources
Add the following snippet to the bottom of your serverless.yml
file:
resources:
Resources:
DynamoDbTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: my-table
AttributeDefinitions:
- AttributeName: my_key
AttributeType: S
KeySchema:
- AttributeName: my_key
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
DynamoDBIamPolicy:
Type: AWS::IAM::Policy
DependsOn: DynamoDbTable
Properties:
PolicyName: lambda-dynamodb
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:PutItem
Resource: arn:aws:dynamodb:*:*:table/my-table
Roles:
- Ref: IamRoleLambdaExecution
What this snippet is doing is creating additional AWS resources via a YAML-based representation of the CloudFormation definitions; A DDB Table and an IAM Policy.
DDB Table
The first resource is a DynamodDb table called DynamoDbTable
(feel free to rename. Pick your own hash key, and change the provisioned throughput if you need to.
Other than the hash key, take note of the TableName
parameter that you set, as this is what you'll reference in your function (there's a usage snippet below). Obviously change it (from "my-table") as you want.
IAM Policy
In order to give your Lambda function(s) access to the table, you'll need to give them permission through an IAM Policy. Make sure that the TableName
you set in the DDB Table resource is updated in the Resource
ARN in the statement (i.e. "...table/my-table").
The other interesting part of the IAM Policy snippet is the Ref: IamRoleLambda
line at the end. IamRoleLambda
is the name of the IAM Role given your Lambda functions by default in Serverless, so it assigns this policy to your functions.
In Your Function
Once you've deployed your Serverless service with the additional resources, you can reference it in your functions.
Here's an using the DynamoDb Document Client:
const AWS = require('aws-sdk');
const dynamo = new AWS.DynamoDB.DocumentClient();
...
module.exports.handler = (event, context, cb) => {
...
const params = {
TableName: 'my-table',
Item: myItem,
};
...
return dynamo.put(params, cb);
};
Obviously you should update your table name value as needed. Remember the aws-sdk
module is always available in Lambda, so you don't need to include it in your function bundle.
Variables
There's currently a PR under discussion, which might make it easier to reference things like the TableName
value throughout your configuration dynamically (i.e. define it once in your serverless.yml
), but it hasn't been merged at the time of writing.