This project demonstrates how to build a proof of concept for a serverless solution on AWS. The solution is designed for a customer selling cleaning supplies, requiring a scalable architecture that handles spikes in demand while ensuring decoupled application components. These steps are part of a lab in an AWS Solutions Architect Associate preparation course.
The architecture consists of the following components:
- REST API (API Gateway): Receives incoming requests and places a database entry in the Amazon SQS queue.
- Amazon SQS: Stores the data temporarily before triggering the first Lambda function.
- AWS Lambda (Function 1): Inserts the entry into a DynamoDB table.
- DynamoDB Streams: Captures the new entry and invokes a second Lambda function.
- AWS Lambda (Function 2): Passes the database entry to Amazon SNS.
- Amazon SNS: Sends a notification to a specified email address.
- Introduction
- Architecture Diagram
- Setup
- Task 1: Creating IAM Policies and Roles
- Task 2: Creating a DynamoDB Table
- Task 3: Creating an SQS Queue
- Task 4: Creating a Lambda Function and Setting Up Triggers
- Task 5: Enabling DynamoDB Streams
- Task 6: Creating an SNS Topic and Setting Up Subscriptions
- Task 7: Creating a Lambda Function to Publish a Message to the SNS Topic
- Task 8: Creating an API with Amazon API Gateway
- Task 9: Testing the Architecture
- Task 10: Cleaning Up
This README provides step-by-step instructions to set up a serverless backend on AWS for a business dealing in cleaning supplies. The solution is scalable, cost-effective, and designed to handle unpredictable spikes in traffic by decoupling key components.
To follow best practices, create custom IAM policies and roles to grant limited permissions.
- Sign in to the AWS Management Console.
- Search for IAM and select Policies.
- Click Create policy and use the following JSON scripts to create the necessary policies:
Policy 1: Lambda-Write-DynamoDB
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:PutItem",
"dynamodb:DescribeTable"
],
"Resource": "*"
}
]
}Policy 2: Lambda-SNS-Publish
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:Publish",
"sns:GetTopicAttributes",
"sns:ListTopics"
],
"Resource": "*"
}
]
}Policy 3: Lambda-DynamoDBStreams-Read
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetShardIterator",
"dynamodb:DescribeStream",
"dynamodb:ListStreams",
"dynamodb:GetRecords"
],
"Resource": "*"
}
]
}
Policy 4: Lambda-Read-SQS
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sqs:DeleteMessage",
"sqs:ReceiveMessage",
"sqs:GetQueueAttributes",
"sqs:ChangeMessageVisibility"
],
"Resource": "*"
}
]
}
- In the IAM console, navigate to Roles.
- Click Create role and configure the following roles:
Role 1: Lambda-SQS-DynamoDB
- Trusted entity type: AWS service
- Common use case: Lambda
- Attach policies:
Lambda-Write-DynamoDB,Lambda-Read-SQS
Role 2: Lambda-DynamoDBStreams-SNS
- Trusted entity type: AWS service
- Common use case: Lambda
- Attach policies:
Lambda-SNS-Publish,Lambda-DynamoDBStreams-Read
Role 3: APIGateway-SQS
- Trusted entity type: AWS service
- Common use case: API Gateway
- Attach policies:
AmazonAPIGatewayPushToCloudWatchLogs
- In the AWS Management Console, search for DynamoDB and select Create table.
- Configure the following settings:
- Table name:
orders - Partition key:
orderID(String)
- Keep other settings as default and click Create table.
- Search for SQS in the AWS Management Console and select Create queue.
- Configure the following settings:
- Name:
POC-Queue - Access Policy: Basic
- Sender: Only the specified AWS accounts, IAM users and roles
- Paste the ARN of the
APIGateway-SQSrole.
- Paste the ARN of the
- Receiver: Only the specified AWS accounts, IAM users and roles
- Paste the ARN of the
Lambda-SQS-DynamoDBrole.
- Paste the ARN of the
- Click Create queue.
- In the AWS Management Console, search for Lambda and select Create function.
- Configure the following settings:
- Function name:
POC-Lambda-1 - Runtime: Python 3.9
- Execution role: Use an existing role
- Existing role:
Lambda-SQS-DynamoDB
- Click Create function.
- In the Function overview section, click Add trigger.
- Choose SQS as the trigger service and select
POC-Queue. - Click Add.
- In the Code tab, replace the default code with:
import boto3, uuid
client = boto3.resource('dynamodb')
table = client.Table("orders")
def lambda_handler(event, context):
for record in event['Records']:
payload = record["body"]
table.put_item(Item={'orderID': str(uuid.uuid4()), 'order': payload})
- Click Deploy.
- In the Test tab, create a new event:
- Event name:
POC-Lambda-Test-1 - Template: SQS
- Save and run the test.
- Verify the test result and confirm the entry in the DynamoDB table.
- In the DynamoDB console, select the
orderstable. - Go to the Exports and streams tab.
- Enable DynamoDB Streams with the New image view type.
- In the AWS Management Console, search for SNS and select Create topic.
- Configure the following settings:
- Name:
POC-Topic - Type: Standard
- Save the ARN of the created topic.
- In the Subscriptions tab, click Create subscription.
- Topic ARN:
POC-TopicARN
- Protocol: Email
- Endpoint: Your email address
- Confirm the subscription via the email you receive.
- Navigate to the AWS Management Console and search for Lambda.
- Click Create function and configure the following settings:
- Function name:
POC-Lambda-2 - Runtime:
Python 3.9 - Existing role: Select
Lambda-DynamoDBStreams-SNS
- Function name:
- Click Create function.
- In the Function overview section of the Lambda console, click Add trigger.
- Choose DynamoDB from the list of services.
- Select the
orderstable as the trigger source. - Click Add to finalize the trigger setup.
-
In the Code tab of the Lambda console, replace the default code with the following:
import boto3, json client = boto3.client('sns') def lambda_handler(event, context): for record in event['Records']: message = json.dumps(record['dynamodb']['NewImage'], indent=4) client.publish( TopicArn='arn:aws:sns:your-region:your-account-id:POC-Topic', Message=message, Subject='New Order Notification' )
-
Replace
arn:aws:sns:your-region:your-account-id:POC-Topicwith the actual ARN of your SNS topic. -
Click Deploy to save and deploy the function.
- On the Test tab, create a new event and for Event name, enter
POC-Lambda-Test-2. - For Template-optional, enter DynamoDB and from the list, choose DynamoDB-Update.
- The DynamoDB template appears in the Event JSON box.
- Save your changes and choose Test.
After the Lambda function successfully runs, the “Execution result: succeeded” message should appear in the notification banner in the Test section. In a few minutes, an email message should arrive at the email address that you specified in the previous task. Confirm that you received the subscription email message. If needed, check both your inbox and spam folder.
In this task, you will create a REST API in Amazon API Gateway. This API serves as a communication gateway between your application and the AWS services.
-
In the AWS Management Console, search for and open API Gateway.
-
On the REST API card with public authentication, choose Build and configure the following settings:
- Choose the protocol: REST
- Create new API: New API
- API name:
POC-API - Endpoint Type: Regional
- Choose Create API.
-
On the Actions menu, choose Create Method.
-
Open the method menu by choosing the down arrow, and choose POST. Save your changes by choosing the check mark.
-
In the POST - Setup pane, configure the following settings:
- Integration type: AWS Service
- AWS Region: us-east-1
- AWS Service: Simple Queue Service (SQS)
- AWS Subdomain: Keep empty
- HTTP method: POST
- Action Type: Use path override
- Path override: Enter your account ID followed by a slash (/) and the name of the
POC-Queue- Note: If
POC-Queueis the name of the SQS queue that you created, this entry might look similar to the following:/<account ID>/POC-Queue
- Note: If
- Execution role: Paste the ARN of the
APIGateway-SQSrole- Note: For example, the ARN might look like the following:
arn:aws:iam::<account ID>:role/APIGateway-SQS
- Note: For example, the ARN might look like the following:
- Content Handling: Passthrough
- Save your changes.
-
Choose the Integration Request card.
-
Scroll to the bottom of the page and expand HTTP Headers.
- Choose Add header.
- For Name, enter
Content-Type. - For Mapped from, enter
'application/x-www-form-urlencoded'. - Save your changes to the HTTP Headers section by choosing the check mark.
-
Expand Mapping Templates and for Request body passthrough, choose Never.
- Choose Add mapping template and for Content-Type, enter
application/json. - Save your changes by choosing the check mark.
- Choose Add mapping template and for Content-Type, enter
-
For Generate template, do not choose a default template from the list. Instead, enter the following command:
Action=SendMessage&MessageBody=$input.bodyin the box.- Choose Save.
In this task, you will use API Gateway to send mock data to Amazon SQS as a proof of concept for the serverless solution.
- In the API Gateway console, return to the POST - Method Execution page and choose Test.
- In the Request Body box, enter:
{ "item": "latex gloves", "customerID": "12345" } - Choose Test.
- Verification in DynamoDB Table.
-
If you see the "Successfully completed execution" message with the 200 response in the logs on the right, you will receive an email notification with the new entry. If you don’t receive an email but the new item appears in the DynamoDB table, troubleshoot the exercise instructions starting from after you set up DynamoDB. Ensure that you deploy all resources in the
us-east-1Region. -
After API Gateway successfully processes the request pasted in the Request Body box, it places the request in the SQS queue. Amazon SQS, set up as a trigger in the first Lambda function, invokes the function call. The Lambda function code places the new entry into the DynamoDB table. DynamoDB Streams captures this change to the database and invokes the second AWS Lambda function. This function retrieves the new record from DynamoDB Streams and sends it to Amazon SNS. Amazon SNS then sends you an email notification.
In this task, you will delete the AWS resources that you created for this exercise.
-
Delete the DynamoDB table:
- Open the DynamoDB console.
- In the navigation pane, choose Tables.
- Select the
orderstable. - Choose Delete and confirm your actions.
-
Delete the Lambda functions:
- Open the Lambda console.
- Select the Lambda functions that you created in this exercise:
POC-Lambda-1andPOC-Lambda-2. - Choose Actions, then Delete.
- Confirm your actions and close the dialog box.
-
Delete the SQS queue:
- Open the Amazon SQS console.
- Select the queue that you created in this exercise.
- Choose Delete and confirm your actions.
-
Delete the SNS topic and subscriptions:
- Open the Amazon SNS console.
- In the navigation pane, choose Topics.
- Select
POC-Topic. - Choose Delete and confirm your actions.
- In the navigation pane, choose Subscriptions.
- Select the subscription that you created in this exercise and choose Delete.
- Confirm your actions.
-
Delete the API that you created:
- Open the API Gateway console.
- Select
POC-API. - Choose Actions, then Delete.
- Confirm your actions.
-
Delete the IAM roles and policies:
- Open the IAM console.
- In the navigation pane, choose Roles.
- Delete the following roles and confirm your actions:
APIGateway-SQSLambda-SQS-DynamoDBLambda-DynamoDBStreams-SNS
- In the navigation pane, choose Policies.
- Delete the following custom policies and confirm your actions:
Lambda-DynamoDBStreams-ReadLambda-SNS-PublishLambda-Write-DynamoDBLambda-Read-SQS
This serverless architecture provides a scalable solution for processing orders and notifications. Although this is a proof of concept, the principles and components can be expanded to suit production environments.














