This lab introduces how to build serverless applications using Python and AWS Lambda.
You will deploy a Lambda function, connect it to Amazon DynamoDB, extend it with additional functionality, and write unit tests using pytest.
By the end of this lab, you will be able to:
- Understand how Python code runs inside AWS Lambda
- Interact with AWS services using
boto3 - Structure Lambda functions using clean, testable Python patterns
- Extend a Lambda function to support CRUD operations
- Write unit tests using pytest
This lab simplifies some patterns for learning purposes:
| Lab Approach | Production Best Practice |
|---|---|
| One Lambda for all CRUD operations | One Lambda per endpoint/action |
| Broad IAM permissions | Least-privilege IAM policies |
| Resources created via AWS Console | Infrastructure as Code (CloudFormation, Terraform, AWS CDK) |
Manual .zip upload |
CI/CD pipelines |
Before starting, ensure your local environment meets the following requirements:
- Python: version 3.13 or higher
- Git: Git for Windows
- IDE: PyCharm or VS Code is recommended
- AWS Account: Provided here for the duration of the lab
Clone this repository to your local machine:
git clone <repository-url>
cd <repository-directory>Open the project in your IDE and familiarise yourself with the Lambda handler logic and how it uses the boto3 library to communicate with AWS services.
Then set up your virtual environment:
-
Create the virtual environment:
python -m venv venv
-
Activate the environment:
- Linux/macOS:
source venv/bin/activate - Windows:
If you encounter a permission issue when running the above command in PowerShell, run the following command to allow scripts to be executed and try again.
.\venv\Scripts\activate
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
- Linux/macOS:
-
Install dependencies:
pip install -r requirements.txt
- Log in to the AWS Management Console and navigate to DynamoDB.
- In the sidebar, click Tables, then click Create table.
- Configure the following settings:
- Table name:
YourNameTable(e.g.,JohnDoeTable) - Partition key:
ItemID(Type:String)
- Table name:
- Keep all other settings as default and click Create table.
- Log in to the AWS Management Console and navigate to DynamoDB.
- In the sidebar, click Tables, then select your newly created table.
- Click Actions and then Create item.
- Provide ItemID a value of 1.
- Click Add new attribute, then String
- Set Attribute name as Name and provide it a value (e.g Chicken Burger)
- Click Create item.
- Navigate to the Lambda service in the AWS Console.
- Click Create function and select Author from scratch.
- Configure the following:
- Function name:
your_name_function(e.g.,john_doe_lambda) - Runtime: Python 3.13
- Function name:
- Click Create function.
- Click the Code tab, Scroll down to the Runtime settings section and Click Edit
- Change Handler from
lambda_function.lambda_handlertolambda_handler.lambda_handler. Click Save.
Your Lambda uses an environment variable to determine which DynamoDB table to use.
-
In your Lambda function, go to Configuration → Environment variables.
-
Click Edit → Add environment variable.
-
Add the following:
Key Value TABLE_NAMEYourNameTable
To allow the Lambda to interact with DynamoDB:
- In your Lambda function dashboard, go to the Configuration tab and select Permissions.
- Click on the Role name to open the IAM Console.
- Click Add permissions → Attach policies.
- Search for and select
AmazonDynamoDBFullAccess, then click Add permissions.
- Navigate back to the Code tab of your Lambda function.
- Create a
.zipfile containing your Python files. - Click the Upload from dropdown and select .zip file.
- Upload your file and click Save.
- Go to the Test tab.
- Create a new test event.
- Click Test.
- Confirm a successful expected response.
You are provided with a working "get all" endpoint.
Your task: implement full CRUD functionality.
| Operation | Description |
|---|---|
| Create | Add a new item |
| Read | Get a single item by ID |
| Update | Modify an existing item |
| Delete | Remove an item |
Add new methods to food_service.py:
def create_item(data): ...
def get_item(item_id): ...
def update_item(item_id, data): ...
def delete_item(item_id): ...Route logic in the handler using the event action:
action = event.get("action")Then when testing the lambda function, provide the appropriate Event JSON like so:
{
"action": "delete"
}Best practice: In production, each operation would typically be a separate Lambda mapped to its own API endpoint.
📖 Docs: https://docs.pytest.org/
Run the test suite:
pytestKey principles:
- Test your Python functions, not the Lambda infrastructure itself
- Keep business logic separate from AWS dependencies
- Mock external services (e.g., DynamoDB) where needed
-
Create an HTTP API in API Gateway.
-
Connect it to your Lambda function.
-
Deploy and test the following endpoints:
GET /items POST /items
Best practice: In production, each route maps to a separate Lambda, and API configuration is defined using Infrastructure as Code.
Important
To avoid unnecessary AWS costs, delete the AWS resources you created (DynamoDB Table and Lambda Function) once you have completed the lab.