A fully serverless AI chatbot built on AWS using Lambda, Amazon Bedrock (Nova Lite), DynamoDB, API Gateway, and a static HTML frontend hosted on S3.
Frontend hosted on AWS S3 Static Website Hosting
API powered by Amazon API Gateway + Lambda + Bedrock
- Project Overview
- Architecture
- Folder Structure
- Services Used
- Step-by-Step Setup From Scratch
- Step 1 — AWS Account Setup
- Step 2 — Region Selection
- Step 3 — IAM Role Creation
- Step 4 — DynamoDB Table Creation
- Step 5 — Lambda Function Creation
- Step 6 — Bedrock Model Access Setup
- Step 7 — API Gateway Creation
- Step 8 — Resource Policy Setup
- Step 9 — S3 Static Website Hosting
- Step 10 — Testing with Hoppscotch / Postman
- Step 11 — Frontend Integration
- API Reference
- Troubleshooting
- Future Improvements
- Resume Description
AI is a serverless conversational AI chatbot that:
- Accepts user messages from a browser-based chat UI
- Sends them to Amazon Bedrock (Nova Lite model) for AI-generated responses
- Stores full conversation history in DynamoDB per session
- Returns AI replies back to the frontend in real time
No servers to manage. No infrastructure to maintain. 100% AWS serverless.
User (Browser)
│
▼
HTML Frontend (S3 Static Website)
│ HTTP POST /chat
▼
Amazon API Gateway (REST API)
│
▼
AWS Lambda (Python 3.12)
│ │
▼ ▼
Amazon Bedrock DynamoDB
(Nova Lite AI) (chat-history)
│
▼
Lambda returns AI reply
│
▼
API Gateway → Frontend → User sees response
Full flow:
User → S3 Frontend → API Gateway → Lambda → Bedrock → DynamoDB → Lambda → API Gateway → User
ai-chatbot/
│
├── index.html # Frontend chat UI (deployed to S3)
│
├── lambda/
│ └── lambda_function.py # Lambda function (Python)
│
├── docs/
│ └── screenshots/
│ ├── 01-iam-role.png # placeholder
│ ├── 02-dynamodb-table.png # placeholder
│ ├── 03-lambda-function.png # placeholder
│ ├── 04-bedrock-access.png # placeholder
│ ├── 05-api-gateway.png # placeholder
│ ├──
│ ├── 06-s3-hosting.png # placeholder
│ ├── 07-hoppscotch-test.png # placeholder
│ └── 08-chat-ui.png # placeholder
│
├── README.md # This file
├── ARCHITECTURE.md # Detailed architecture + flowchart
├── TROUBLESHOOTING.md # Common errors and fixes
├── FUTURE_IMPROVEMENTS.md # Roadmap
└── RESUME.md # Resume-ready project description
| Service | Purpose |
|---|---|
| AWS Lambda | Runs backend logic (Python) |
| Amazon Bedrock (Nova Lite) | Generates AI responses |
| Amazon DynamoDB | Stores chat history per session |
| Amazon API Gateway | Exposes REST API endpoint |
| Amazon S3 | Hosts static HTML frontend |
| AWS IAM | Manages permissions and roles |
| Hoppscotch / Postman | API testing |
- Go to https://aws.amazon.com and click Create an AWS Account
- Enter your email, set a root password, and complete billing setup
- Verify your identity (phone + credit card required — free tier available)
- Sign in to the AWS Management Console
📸 Screenshot placeholder:
docs/screenshots/01-aws-console.png
- In the top-right corner of the AWS Console, click the region dropdown
- Select US East (N. Virginia) — us-east-1
⚠️ Important: All services (Lambda, DynamoDB, Bedrock, API Gateway) must be in the same region:us-east-1
The Lambda function needs permission to call Bedrock and DynamoDB.
- Go to IAM → Roles → Create Role
- Select Trusted entity type: AWS Service
- Select Use case: Lambda → click Next
- Attach these policies:
AmazonDynamoDBFullAccessAmazonBedrockFullAccessAWSLambdaBasicExecutionRole
- Name the role:
ai-lambda-role - Click Create Role
📸 Screenshot placeholder:
docs/screenshots/01-iam-role.png
- Go to DynamoDB → Tables → Create Table
- Fill in:
- Table name:
chat-history - Partition key:
session_id(String) - Sort key:
timestamp(String)
- Table name:
- Leave all other settings as default
- Click Create Table
- Wait until the table status shows Active
📸 Screenshot placeholder:
docs/screenshots/02-dynamodb-table.png
- Go to Lambda → Functions → Create Function
- Select Author from scratch
- Fill in:
- Function name:
ai-chatbot - Runtime: Python 3.12
- Architecture: x86_64
- Function name:
- Under Permissions, choose Use an existing role → select
nova-ai-lambda-role - Click Create Function
Upload the code:
- In the Lambda code editor, delete the default code
- Copy the full contents of
lambda/lambda_function.pyand paste it - Click Deploy
Increase timeout:
- Go to Configuration → General Configuration → Edit
- Set Timeout to 30 seconds
- Click Save
📸 Screenshot placeholder:
docs/screenshots/03-lambda-function.png
- Go to Amazon Bedrock → Model Access (left sidebar)
- Click Manage Model Access
- Find Amazon Nova Lite in the list
- Check the checkbox next to it
- Click Request Model Access
- Wait for status to change to Access Granted (usually instant)
📸 Screenshot placeholder:
docs/screenshots/04-bedrock-access.png
⚠️ If you skip this step, Lambda will throw aAccessDeniedExceptionwhen calling Bedrock.
- Go to API Gateway → Create API
- Choose REST API → click Build
- Select New API
- Fill in:
- API name:
ai-api - Endpoint Type: Regional
- API name:
- Click Create API
Create Resource:
- Click Actions → Create Resource
- Resource name:
chat - Resource path:
/chat - ✅ Enable CORS checkbox
- Click Create Resource
Create POST Method:
- Select
/chatresource → Actions → Create Method → POST - Integration type: Lambda Function
- Lambda Function:
ai-chatbot - Click Save → click OK on the permission popup
Enable CORS:
- Select
/chat→ Actions → Enable CORS - Click Enable CORS and replace existing CORS headers
- Click Yes, replace existing values
Deploy API:
- Actions → Deploy API
- Deployment stage: [New Stage]
- Stage name:
prod - Click Deploy
- Copy the Invoke URL — it will look like:
https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/chat
📸 Screenshot placeholder:
docs/screenshots/05-api-gateway.png
This policy allows public access to your API endpoint.
- In API Gateway, go to your API → Resource Policy
- Paste the following JSON (replace the ARN values with your own):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:<YOUR_ACCOUNT_ID>:<YOUR_API_ID>/prod/POST/chat"
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:<YOUR_ACCOUNT_ID>:<YOUR_API_ID>/prod/OPTIONS/chat"
}
]
}- Click Save
- Re-deploy the API (Actions → Deploy API → prod stage)
📸 Screenshot placeholder:
docs/screenshots/06-resource-policy.png
⚠️ You must redeploy after saving the resource policy, otherwise changes won't take effect.
- Go to S3 → Create Bucket
- Fill in:
- Bucket name:
ai-frontend(must be globally unique) - Region:
us-east-1
- Bucket name:
- Uncheck "Block all public access" → confirm the warning
- Click Create Bucket
Enable Static Website Hosting:
- Open the bucket → Properties tab
- Scroll to Static website hosting → click Edit
- Enable it, set:
- Index document:
index.html
- Index document:
- Click Save changes
Upload index.html:
- Go to Objects tab → Upload
- Upload your
index.htmlfile - Click Upload
Set Bucket Policy (public read):
- Go to Permissions tab → Bucket Policy → Edit
- Paste:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::nova-ai-frontend/*"
}
]
}- Click Save changes
- Copy the Bucket website endpoint URL from the Properties tab
📸 Screenshot placeholder:
docs/screenshots/07-s3-hosting.png
Before opening the frontend, test the API directly.
Using Hoppscotch (free, browser-based):
- Go to https://hoppscotch.io
- Set method to POST
- Enter your API URL:
https://<YOUR_API_ID>.execute-api.us-east-1.amazonaws.com/prod/chat - Go to Body tab → select JSON
- Paste:
{ "message": "Hello! What is AWS Lambda?", "session_id": "test-session-001" } - Click Send
Expected Response:
{
"statusCode": 200,
"body": "{\"message\": \"AWS Lambda is a serverless compute service...\", \"session_id\": \"test-session-001\"}"
}📸 Screenshot placeholder:
docs/screenshots/08-hoppscotch-test.png
The index.html file already has the API URL hardcoded. If you deployed your own API, update line in index.html:
const API = "https://<YOUR_API_ID>.execute-api.us-east-1.amazonaws.com/prod/chat"Replace with your own Invoke URL from Step 7.
Then re-upload index.html to S3 and open the bucket website URL in your browser.
📸 Screenshot placeholder:
docs/screenshots/09-chat-ui.png
POST https://<api-id>.execute-api.us-east-1.amazonaws.com/prod/chat
{
"message": "What is Amazon Bedrock?",
"session_id": "user-abc123"
}| Field | Type | Required | Description |
|---|---|---|---|
| message | string | Yes | The user's chat message |
| session_id | string | No | Unique session ID (auto-generated if omitted) |
{
"statusCode": 200,
"body": "{\"message\": \"Amazon Bedrock is a fully managed service...\", \"session_id\": \"user-abc123\"}"
}| Field | Type | Description |
|---|---|---|
| statusCode | number | HTTP status code |
| body.message | string | AI-generated reply |
| body.session_id | string | Session ID echoed back |
See TROUBLESHOOTING.md for detailed fixes.
| Error | Likely Cause | Fix |
|---|---|---|
AccessDeniedException on Bedrock |
Model access not granted | Go to Bedrock → Model Access → Enable Nova Lite |
ResourceNotFoundException on DynamoDB |
Table name mismatch | Ensure table is named exactly chat-history |
| CORS error in browser | CORS not enabled on API Gateway | Re-enable CORS and redeploy API |
502 Bad Gateway |
Lambda crash | Check Lambda CloudWatch logs |
| API returns empty response | Lambda timeout | Increase Lambda timeout to 30s |
| S3 page shows 403 | Bucket not public | Check bucket policy and unblock public access |
See FUTURE_IMPROVEMENTS.md for full roadmap.
- Add user authentication with Amazon Cognito
- Switch to streaming responses for real-time typing effect
- Add support for multiple Bedrock models (Claude, Titan, etc.)
- Deploy frontend with CloudFront CDN for HTTPS + performance
- Add conversation export (download chat as PDF/text)
- Implement rate limiting on API Gateway
- Add voice input using Amazon Transcribe
See RESUME.md for the full resume-ready write-up.
AI Chatbot** — Built a fully serverless AI chatbot on AWS using Lambda (Python), Amazon Bedrock (Nova Lite LLM), DynamoDB for persistent chat history, API Gateway REST API, and S3 static website hosting. Implemented session-based conversation memory, CORS-enabled API, and a responsive HTML/CSS/JS frontend. Reduced infrastructure cost to near-zero using AWS free tier serverless architecture.