Share Config Properties between Serverless Config and Lambda Functions
The Problem
Today, I was deploying a serverless backend to AWS with with Serverless. At one point, I ran into a cryptic error from the Lambda like “Server Error”. In the Lambda logs in the AWS console, I discovered the cause of the error: the DynamoDB table name in the serverless.yml
config file was different from the table name in the Lambda function. So the Lambda was trying to access a DynamoDB table which didn’t exist. I thought to myself, there has to be a better way. Can the table name be shared between the config and the code? Of course it can!
The Solution
See corresponding code snippets below. Lines of interest are in bold.
- Create a
constants.json
file with an object containing the config property key-value - In your lambda file, you can import a JSON file just like a normal JS file; Below we use destructing to grab the exact property we need
- In your
serverless.yml
, you can import a property with the syntax:${file(<relative_path_to_file>):<object_key_in_file>}
… Below we save the value in a top levelcustom
section so it can be referenced later in the file - Now to reference the property in the
serverless.yml
, use the syntax${self:custom.<property_name>}
// constants.json
{ "dynamoTableName": "myTable" }
// lambda.js
const { dynamoTableName } = require('./constants');
const AWS = require('aws-sdk');
module.exports.getAllRecords = (event, context, callback) => {
const dynamo = new AWS.DynamoDB.DocumentClient();
const params = { TableName: dynamoTableName };
dynamo.scan(params, (error, data) => {
...
// serverless.yml
service: my-service
custom:
dynamoTableName: ${file(./constants.json):dynamoTableName}
provider:
name: aws
runtime: nodejs12.x
iamRoleStatements:
- Effect: 'Allow'
Action:
- 'dynamodb:*'
Resource:
Fn::Join:
- ':'
- - 'arn:aws:dynamodb'
- 'Ref': 'AWS::Region'
- 'Ref': 'AWS::AccountId'
- 'table/${self:custom.dynamoTableName}'
resources:
Resources:
MyDynamo:
Type: 'AWS::DynamoDB::Table'
Properties:
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:custom.dynamoTableName}
functions:
...