Using AWS Lambda to Read and Write to AWS DynamoDB
The following shows how to read and write to a DynamoDB table using AWS Lambda.
I have a composte heap in my backyard with a thermometer to measure the temperature. This blog goes over how to write to and read from a DynamoDB database in AWS. The data the lambda receives is the current temperature of the composte heap.
Writing to Dynamo DB
Two configured test events used with the lambda function.
// freezing-temp
{
"temp": 32
}
// hot-temp
{
"temp": 140
}
// WriteComposteHeapTemperature.js
const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient({region: "us-west-2"});
exports.handler = async (event, context, callback) => {
const requestId = context.awsRequestId;
const temperature = event.temp
await createHeapReport(requestId, event.temp).then(() => {
callback(null, {
statusCode: 201,
body: '',
headers: {
'Access-Control-Allow-Origin' : '*'
}
}).catch((err) => {
console.log(err)
})
});
};
function createHeapReport(requestId, temp) {
const params = {
TableName: 'FarmHeap',
Item: {
"messageId": requestId,
"temp": temp
}
}
return ddb.put(params).promise();
}
Execution Results when triggering ‘hot-temp’ event
Test Event Name
hot-temp
Response
{
"statusCode": 201,
"body": "",
"headers": {
"Access-Control-Allow-Origin": "*"
}
}
Function Logs
START RequestId: e1ff895b-65a0-4d87-839b-f8fddec82c93 Version: $LATEST
END RequestId: e1ff895b-65a0-4d87-839b-f8fddec82c93
REPORT RequestId: e1ff895b-65a0-4d87-839b-f8fddec82c93 Duration: 724.30 ms Billed Duration: 725 ms Memory Size: 128 MB Max Memory Used: 88 MB Init Duration: 494.19 ms
Request ID
e1ff895b-65a0-4d87-839b-f8fddec82c93
If the function fails to write to the database its execution role needs to be modified. On your Function Overview page, click the Configuration Tab, and click on the Role Name. Then you will want to modify the role so that it has the permissions required. For DynamoDB you can give a lambda function permission to run for all tables, or only a specific table. In this case, since this function is specific to a table, such as saving the temperature of the Composte Heap, then it should only have the ability to Write to the ‘FarmHeap’ DynamoDB table.
Since we are seeing a statusCode of 201 we know the insert into DynamoDB is working correctly.
Now lets read from the table.
ReadFarmHeapTemperature
The following reads 10 temperatures from the ‘FarmHeap’ table and logs the temperature.
const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient({region: 'us-west-2'});
exports.handler = async (event, context, callback) => {
await readFarmHeap().then(data => {
data.Items.forEach(function(item) {
let temperature = item.temp
console.log(temperature)
});
});
};
function readFarmHeap(requestId) {
const params = {
TableName: 'FarmHeap',
Limit: 10
};
return ddb.scan(params).promise();
}
To configure the lambda to have the correct read access you will need to do the following.
On your Function Overview page, click the Configuration Tab, and click on the Role Name. Then you will want to modify the role so that it has the permissions required.
The policy you will need to add is “AmazonDynamoDBReadOnlyAccess”.
With that policy you should be able to read from the table. After triggering several test events from the WriteComposteHeapTemperature you can run the ReadFarmHeapTemperature and you should see something like the following.
Test Event Name
readDataFromHeap
Response
null
Function Logs
START RequestId: a230dd11-179f-4574-ac9f-047048337dcf Version: $LATEST
2021-09-01T14:30:13.498Z a230dd11-179f-4574-ac9f-047048337dcf INFO 140
2021-09-01T14:30:13.537Z a230dd11-179f-4574-ac9f-047048337dcf INFO 32
2021-09-01T14:30:13.537Z a230dd11-179f-4574-ac9f-047048337dcf INFO 140
2021-09-01T14:30:13.537Z a230dd11-179f-4574-ac9f-047048337dcf INFO 28
2021-09-01T14:30:13.537Z a230dd11-179f-4574-ac9f-047048337dcf INFO 140
2021-09-01T14:30:13.537Z a230dd11-179f-4574-ac9f-047048337dcf INFO 140
2021-09-01T14:30:13.537Z a230dd11-179f-4574-ac9f-047048337dcf INFO 140
2021-09-01T14:30:13.538Z a230dd11-179f-4574-ac9f-047048337dcf INFO 28
2021-09-01T14:30:13.538Z a230dd11-179f-4574-ac9f-047048337dcf INFO 28
2021-09-01T14:30:13.538Z a230dd11-179f-4574-ac9f-047048337dcf INFO 28
END RequestId: a230dd11-179f-4574-ac9f-047048337dcf
REPORT RequestId: a230dd11-179f-4574-ac9f-047048337dcf Duration: 753.28 ms Billed Duration: 754 ms Memory Size: 128 MB Max Memory Used: 89 MB Init Duration: 414.85 ms
Request ID
a230dd11-179f-4574-ac9f-047048337dcf
The temperature of the composte heap has a different meaning. Personally I use a 16 inch thermometer, and to maximize the growth of the organisms in the composte that break down the organic matter into usable soil it is important to keep the Heap at specific temperatures for specific reasons. A high temperature such as 158 will likely kill weed seeds, and an even hotter temperature such as 170 may be too hot and kill the bacteria. There is a balance to be found, and for that reason we could use lambda to track the temperature readings, and connect a wifi enabled thermometer to send the data it receives.
So lets make a function that takes in our temperature and returns a description of the heap temperature.
For your Read Lambda function lets create a new file next to your index.js called ‘heap.js’. Hmm… I wonder how many people have created a file called ‘heap’ and referred to a composte heap, and not a heap.
That aside… here is our heap.js.
// heap.js
function heapHealth(temp) {
if (temp < 80) {
return "nothing";
} else if (80 <= temp && temp < 100) {
return "warm";
} else if (100 <= temp && temp < 130) {
return "active";
} else if (130 <= temp && temp < 160) {
return "hot";
} else {
return "really hot! Maybe too hot?!";
}
}
module.exports = { heapHealth };
Then call that from our original function.
const AWS = require('aws-sdk');
const ddb = new AWS.DynamoDB.DocumentClient({region: 'us-west-2'});
const { heapHealth } = require('./heap')
exports.handler = async (event, context, callback) => {
await readRecentHeap().then(data => {
data.Items.forEach(function(item) {
let temperature = item.temp;
let heapDescription = heapHealth(temperature);
console.log(temperature,heapDescription);
});
});
};
function readRecentHeap(requestId) {
const params = {
TableName: 'FarmHeap',
Limit: 10
};
return ddb.scan(params).promise();
}
Deploy the changes, and run the test again.
Test Event Name
readDataFromHeap
Response
null
Function Logs
START RequestId: 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f Version: $LATEST
2021-09-01T14:40:20.461Z 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f INFO 140 hot
2021-09-01T14:40:20.480Z 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f INFO 32 nothing
2021-09-01T14:40:20.480Z 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f INFO 140 hot
2021-09-01T14:40:20.480Z 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f INFO 28 nothing
2021-09-01T14:40:20.480Z 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f INFO 140 hot
2021-09-01T14:40:20.480Z 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f INFO 140 hot
2021-09-01T14:40:20.480Z 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f INFO 140 hot
2021-09-01T14:40:20.480Z 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f INFO 28 nothing
2021-09-01T14:40:20.481Z 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f INFO 28 nothing
2021-09-01T14:40:20.481Z 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f INFO 28 nothing
END RequestId: 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f
REPORT RequestId: 2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f Duration: 462.14 ms Billed Duration: 463 ms Memory Size: 128 MB Max Memory Used: 91 MB
Request ID
2b85f0f8-a9e3-4c2f-ad90-bda853a0b76f
You are now on your way to building a serverless application for monitoring your farm composte heap.
May the composte be nutrient rich, and may the harvest be bountiful.
Happy coding.