AWS lambda

AWS lambda

Author: Agata Werszler

In the beginning, let’s get familiar with the basic definitions.

AWS Lambda – it’s the code (actually a function), which is being executed in the cloud. The main advantage of this solution is that we don’t need to take care about the environment setup e.g. if it’s hardware server or virtual machine (read more about AWS Lambdas here: https://aws.amazon.com/lambda/)

DynamoDB – NoSQL database, which has high performance and scalability (read more about it here: https://aws.amazon.com/dynamodb)

IAM – it’s the abbreviation of Identity and Access Manager, in other words, user, groups, AWS resources and accesses management (read more here: https://aws.amazon.com/iam/)

API Gateway – the service opening the access to the services inside AWS from the Internet via the REST API (read more: https://aws.amazon.com/api-gateway/)

Region – physical localization in the world, which includes two or more Availability Zones. Availability Zone is the one or more separate data centers (read more about AWS infrastructure here: https://aws.amazon.com/about-aws/global-infrastructure/)

First of all, we need to choose the region, where we want to work.

Click in the right upper corner (next to the user name) on the current region in order to extend the dropdown list with available regions to choose.

AWS lambda, Borsuque Squad

Application description:

The application will be gathering messages sent by the users – something like “guest book” which we can see in museums or other interesting places and write down: “I’ve been here! XYZ!” or “I strongly recommend this museum!”.

Let’s begin with creating the table in DynamoDB and giving it name ‘messages’, then create the IAM role for our future lambda function. This role will be holding two policies:

– the permission to create logs in the CloudWatch Logs service,

– the permission to create new records in our ‘messages’ table in DynamoDB

In the next steps we’re going to finally create lambda function with the code responsible for records creation in the table and, of course, we’re going to test everything works as it should. In the end, we’re going to create API endpoint, which will allow us to run lambda from external network (via the HTTP POST method)

DynamoDB – table creation.

1. Choose the DynamoDB service in AWS Management Console

2. Click on ‘Create table’ button

3. In the ‘Table name’ field write ‘messages’

4. In the ‘Primary key’ field write ‘messageId’ and change the type of this field to String – simply, it’s a unique attribute identifying data in our database (it’s more complex, I strongly recommend to read more about it here: https://aws.amazon.com/blogs/database/choosing-the-right-dynamodb-partition-key/)

5. Leave other options as default and then click on ‘Create’

6. Once the table is created, copy the ARN (Amazon Resource Name) from the ‘Table details’ section and keep it noted. It’s a unique address of our table (our resources can communicate with each other using this address).

arn:aws:dynamodb:eu-central-1:613708629411:table/messages

Creation of the IAM role for the lambda function

Before we write the lambda function, we should create the IAM role, which will define the services allowed to communicate with the lambda.

We’ll give the following permission in our IAM role:

– permission to create logs in CloudWatch Logs service,

– permission to create records in ‘messages’ table in DynamoDB

1. Choose IAM (section: Security, Identity & Compliance) from AWS Management Console

2. Click ‘Roles’ in the menu on the left side

AWS lambda, Borsuque Squad

3. Click on ‘Create New Role’

4. Choose the service, which will be using this role: in our case it’s Lambda

5. Click on the button ‘Next: Permissions‘ at bottom of the screen.

6. Look for the role named AWSLambdaBasicExecutionRole and mark it with the checkbox. This role contains policies with the permissions to write in the CloudWatch Logs service (but don’t worry, we’ll fix it in a while and add write access to the ‘messages’ table)

7. Click on ‘Next Step’

8. Here we need to set the name of our role, let’s name it ‘MessagesLambda’

AWS lambda, Borsuque Squad

9. Click on ‘Create role’, once the role is created the site redirects to the view with the list of all roles

So as to differentiate our role with additional policies like e.g. possibility to write records in ‘messages’ table we need to follow the following steps:

10. Set the name of the previously created role in the search field: ‘MessagesLambda’

11. Got to the ‘Permissions’ tab and click the link ‘Add inline policy’ (on the right side)

12. Click on ‘Choose a service’

13. Type ‘DynamoDB’ in the search field and choose this service

14. Click on ‘Actions’ section

15. Type ‘PutItem’ in the search field and choose the result

AWS lambda, Borsuque Squad

16. Then click on ‘Resources’ section’

17. Check the ‘Specific’ radio button and click on the link ‘Add ARN’

18. In the new window paste previously noted ARN of the ‘messages’ table (fields like Region, Account and Table name will be filled in automatically)

19. Click on ‘Add’

20. Click on ‘Review policy’ (at the bottom of the screen)

21. Set the new policy name in the ‘Name’ field: DynamoDBWriteAccess

22. Click on ‘Create policy’

Now our role contains two policies, sufficient to complete the application.

A new policy giving the write access to the table should look like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "dynamodb:PutItem"
            ],
            "Resource": [
                "arn:aws:dynamodb:eu-central-1:613708629411:table/messages"
            ]
        }
    ]
}

AWS Lambda function creation

We will now create the center of all the confusion – our function!

1. Choose the Lambda service from AWS Management Console (in the Compute section)

2. Click on Create a function

AWS lambda, Borsuque Squad

3. In the Name field type the function name: SaveMessages

4. Choose Node.js 8.10 as the Runtime

5.  In the Role field choose Choose an existing role option

6. In the Existing Role field choose the previously created role: MessagesLambda

6. Click on Create function (in the right down corner)

7. In the Function code section type the following code:

const AWS = require('aws-sdk');
const db = new AWS.DynamoDB.DocumentClient();
const randomBytes = require('crypto').randomBytes;

exports.handler = async (event) => {
    let requestBody;
    try {
        requestBody = JSON.parse(event.body);
        console.log(requestBody)
    } catch (err) {
        console.error(`Could not parse requested JSON ${event.body}: ${err.stack}`);
        return {
            statusCode: 500,
            error: `Could not parse requested JSON: ${err.stack}`
        };
    }
    
    const messageId = toUrlString(randomBytes(16));
    const messageContent = requestBody.messageContent
    
    const params = {
        TableName: 'messages',
        Item: {
            messageId: messageId,
            content: messageContent,
        },
    };
    
    return await new Promise((resolve, reject) => {
        db.put(params, (error, data) => {
            if (error) {
                console.log(`Could not create message, ERROR=${error.stack}`);
                resolve({
                    statusCode: 400,
                    error: `Could not create message: ${error.stack}`
                });
            } else {
                console.log(`message created data=${JSON.stringify(data)}`);
                resolve({ statusCode: 200, body: JSON.stringify(params.Item) });
            }
        });
    });
  
};

function toUrlString(buffer) {
    return buffer.toString('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=/g, '');
}

8. Click on Save (in the right upper corner)

Testing lambda implementation

It’s worth to test our function now. AWS has very simple testing feature, just follow those steps:

1. Choose Configure tests events from the dropdown list (Select a test event) in the right upper corner

2. Leave the radio button Create new test event checked

3. In the Event name field type TestRequestEvent

4.  In the code field type the following JSON object

{
  "path": "/message",
  "httpMethod": "POST",
  "headers": {
    "Accept": "*/*",
    "content-type": "application/json; charset=UTF-8"
  },
  "queryStringParameters": null,
  "pathParameters": null,
  "body": "{\"messageContent\":\"My new message\"}"
}

5. Click on Create button

6. Click Test in the right upper corner (check if the test RequestTestEvent is chosen before)

7. Expand the Details section in order to see the lambda response

AWS lambda, Borsuque Squad

8. Check if the response contains statusCode 200, if so, everything works correctly!

 9. Now we can go to the DynamoDB service and check if our new message has been saved in the messages table.

Our entry is in the table! Congratulations!;)

API Gateway configuration

Let’s continue our travel: API Gateway

With this service we’ll expose our lambda to the world via the REST API.

API creation

1. Choose API Gateway service from AWS Management Console (Network & Content Delivery section)

2. Click on Get Started button

AWS lambda, Borsuque Squad

3. Check the New API radio button

4. In the API name field type Messages

5. Leave the other fields default

6. Click on Creaet API (in the right bottom corner)

Creating API resource

1. Click on the Actions dropdown menu (on the right side), and choose Create Resource option

2. In Resource Name field type message

3.  Leave other fields default

AWS lambda, Borsuque Squad

4. Click on Create Resources (in the right bottom corner)

5. Mark recently created resource (on the left side) and choose Create Method from Actions dropdown.

6. Choose the POST method from the next dropdown list and click the check buton to confirm

7.  In the Integration Type field choose Lambda Function

8. Mark the checkbox Use Lambda Proxy Integration

9. Choose your region in the Lambda Region field

10. Type your function name in the Lambda Function field: SaveMessage

AWS lambda, Borsuque Squad

11. Click Save

12. In the popup window (telling about permission adding for API Gateway to access our lambda). Click OK

API Gateway Testing

Now it’s the time to check if everything works, so:

 1. Mark POST (on the left side), and click button Test

AWS lambda, Borsuque Squad


2.  Paste the JSON below in the new view in the Request Body field:

{
    "messageContent":"My new message from internet!"
}

3.  Click Test

4. We should receive the response from our lambda with 200 status



5.  Now we can check in the DynamoDB if we save into  messages table our message

AWS lambda, Borsuque Squad

We managed to finish the task and create simple serverless application! Congratulations!

Post a comment