Simon Green
Posted on October 4, 2023
Included in this chapter...
- Objective
- AWS services used
- Step 1: Create the DynamoDB table
- Step 2: Create the IAM Role
- Step 3: Create the AWS Lambda function
- Step 4: Create the API Gateway configuration
- Summary
Objective
For this part of implementing the website’s visitor counter I will be working on several steps as follows:
- Create a DynamoDB table that will contain a single row of two columns, the latter column will contain the current visitor count value.
- Create the IAM policy and role to allow Lambda to access and update DynamoDB.
- Create a Lambda function that will 1) access DynamoDB and get the current visitor count, increase it by 1 and 2) replace replace the value back into DynamoDB.
- Create an API Gateway that will invoke the above Lambda function, the API will later be configured to CloudFront and triggered when the resume page is opened.
AWS services used
- DynamoDB
- IAM
- AWS Lambda
- API Gateway
Step 1: DynamoDB - create the table
- Open DynamoDB from the AWS console
- Select the region as ‘Europe (Paris)’, ‘eu-west-3’- Click on ‘Create table’
In the following 'Create table' page, enter the following details:
-
Table details
- Add the table name
- Partition key
- Add ‘id’ and select ‘String’
-
Table settings
- Select ‘Customize settings’
-
Read/write capacity settings
- Select ‘On-demand’
-
Scroll to bottom
- and click on ‘Create table’
--
The below image shows how the table will look once set up. Note that the row count will not increase, only value under 'visitor_count' will be updated.
Step 2: IAM - Create the Role
To enable Lambda to securely access DynamoDB I will need to create a policy and attach it to an IAM role, the role will later be attached to the Lambda function. The role will be based on a policy of allowing ‘read’, ‘write’ and ‘update’ operations when Lambda connects to DynamoDB.
- Open the IAM console
- Click on ‘Policies’ and then ‘Create Policy’
Policy creation (AWS step 1 of 2): Specify permissions
Click on the ‘JSON’ tab and enter the below code into the ‘Policy editor’
IAM policy for Lambda so it can access DynamoDB:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DescribeTable"
],
"Effect": "Allow",
"Resource": "arn:aws:dynamodb:eu-west-3:************:table/visitor_count_table"
}
]
}
Policy creation (AWS step 2 of 2): Review and create
- Add a name for the policy (for example 'access_dynamodb_from_lambda')
The Policy should now be created. You can click on the ‘+/-’ button on the left of the policy name to view more details.
Next, on the left-hand side of the console, click on 'Roles' and 'Create role'. Here I'll be attaching the policy to the role.
Role creation (AWS step 1 of 3): Select trusted entity
On the ‘Select trusted entity’ page, select ‘AWS service’ and under Use case select ‘Lambda’, then click on ‘Next’
Role creation (AWS step 2 of 3): Add permissions
On the ‘Add permissions’ screen add the following two permissions by searching for:
- AWSLambdaBasicExecutionRole
- access_dynamodb_from_lambda (as created in the above step)
Then scroll to the bottom and click ‘Create role’
Role creation (AWS step 3 of 3): Name, review, and create
Enter a name for the role (for example: 'lambda_dynamodb_role'), scroll to the bottom and click ‘Create role’.
Step 3: Create the AWS Lambda function
In this step I´ll be 1) setting up the Lambda function that will connect to DynamoDB, 2) get a value, 3) perform a calculation and 4) return (replace) it back into the database. Let's get started...
- Open AWS Lambda in the AWS console
- Select the region as ‘Europe (Paris)’, ‘eu-west-3’
- Click on ‘Create function’
In the ‘Create function’ section I selected the following:
- ‘Author from scratch’
- 'Basic information'
- ‘Function name’
- Crc_lambda_func_dynamodb_update
- Runtime
- ‘Python 3.11’
- ‘Function name’
-
Permissions
- Expand ‘Change default execution role’
- Under ‘Execution role’, select ‘Use an existing role’
- Under ‘Existing role’ locate the IAM role created above, in my case it is ‘lambda_dynamodb_role.
- Then click the orange ‘Create function’ button at the bottom.
When created, the following screen will appear:
An overview of the Python script
As a reminder the DynamoDB table has been set up like this:
The following Python code that I developed was pasted into the ‘lambda_function.py’ file.
import json
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('visitor_count_table')
def lambda_handler(event, context):
# The 'event' object contains information from the invoking service
# The 'context' object is passed to your function by Lambda at runtime
try:
# 1. Get Item
response = table.get_item(Key={
'id':'visitors'
})
visitor_count = response['Item']['visitor_count']
visitor_count += 1
# timestamp
date_time = datetime.now()
str_date_time = date_time.strftime("%Y-%m-%d, %H:%M:%S")
# print("Current timestamp", str_date_time)
# 2. Put Item
response = table.put_item(Item={
'id':'visitors',
'visitor_count': visitor_count,
'timestamp_utc': str_date_time
})
return{'Count':visitor_count}
status_code = response["ResponseMetadata"]["HTTPStatusCode"]
print("HTTPStatusCode = {}".format(status_code))
print("Successfully updated - visitor_count now = {}".format(visitor_count))
except:
# timestamp
date_time = datetime.now()
str_date_time = date_time.strftime("%Y-%m-%d, %H:%M:%S")
# print("Current timestamp", str_date_time)
# If the item doesn't exist, create it
table.put_item(
Item={
'id': 'visitors',
'visitor_count': 1,
'timestamp_utc': str_date_time
}
)
return{'Count':visitor_count}
status_code = response["ResponseMetadata"]["HTTPStatusCode"]
print("HTTPStatusCode = {}".format(status_code))
print("visitor_count did not exist, recreated, visitor_count now equals: 1")
Here is an overview of what it does:
- Declares that the Lambda function will be working with DynamoDB
- States the DynamoDB table 'visitor_count_table'
- Function:
- get_item: return the row where 'id' = 'visitors'
- Declare 'visitor_count' from the DynamoDB table as a variable
- Increase the count by 1
- Put_item: replace the visitors row with the new value
- Returns the updated visitor_count value
- Print the httpstatus code to the console
- Print confirmation that operation has been performed with new count
- get_item: return the row where 'id' = 'visitors'
Step 4: Create the API Gateway configuration
- Open API Gateway in the AWS console
- Select the region as 'Europe (Paris)', 'eu-west-3'
- Click on 'Create API'
- Choose the API type 'REST API' and click 'Build'
Create REST API
- API details
- ‘New API’
- Add an API name -(for example: 'api_lambda_update_visitor_count')
- API endpoint should be ‘Regional’
- Click the orange ‘Create API’ button.
Resources
- In the ‘Methods’ section, click on ‘Create method’
Here I need to create a ‘GET’ method that I did with these steps:
- For ‘Method type’, select ‘GET’
- For ‘Integration type’, select ‘Lambda function’
- Select the Availability Zone, the same as used for the Lambda function (eu-west-3)
- From the drop down menu, select the Lambda function that we previously created
- Click ‘Create method’
Back on the ‘Resources’ Page
- Open up the ‘Test’ tab
- Then click on the orange ‘Test’ button
- This should invoke the Lambda function
Checking the DynamoDB table, the visitor_count value should now increment by 1 each time the API is triggered.
Summary
This was a challenging section to complete, mainly focussed around getting the Lambda function to replace the updated value back into the database. As a result I now have a much better understanding of how this works.
Aside from this, I found it just a simple case of connecting the individual components together.
Next step, connecting the frontend and the backend!
Thanks for reading!
Posted on October 4, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.