The AWS Cloud Resume Challenge: Your Gateway to Cloud Engineering (Part 2)


Overview
In this section of the Cloud Resume Challenge, you'll build a complete back-end API system to track and display visitor counts on your resume website. This involves creating a DynamoDB database, writing a Lambda function, setting up an API Gateway, and connecting everything to your frontend.
Architecture Overview
Frontend (JavaScript) → API Gateway → Lambda Function → DynamoDB
Prerequisites
AWS CLI configured with appropriate permissions
Basic knowledge of Python and JavaScript
Completed frontend setup from previous steps
Step 1: Create DynamoDB Table
1.1 Navigate to DynamoDB Console
Log in tothe AWS Console
Search for "DynamoDB" and select it
Click "Create table"
1.2 Configure Table Settings
Table name:
resume-visitor-count
Partition key:
id
(String)Sort key: Leave blank
Table settings: Use default settings
Click "Create table"
1.3 Add Initial Data
Once the table is created, click on it
Go to the "Items" tab
Click "Create item"
Add the following attributes:
id
:visitor-count
(String)count
:0
(Number)
Click "Create item"
Step 2: Create an IAM Role for Lambda
2.1 Navigate to IAM Console
Search for "IAM" in AWS Console
Click "Roles" in the left sidebar
Click "Create role"
2.2 Configure Role
Trusted entity type: AWS service
Service: Lambda
Click "Next"
2.3 Create Custom Policy for DynamoDB
Click "Create policy"
Select "JSON" tab
Replace the default policy with:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/resume-visitor-count"
}
]
}
Click "Next: Tags" (skip tags)
Click "Next: Review"
Name:
DynamoDBResumeCounterPolicy
Click "Create policy"
2.4 Attach Policies to Role
Go back to role creation and attach:
AWSLambdaBasicExecutionRole
(managed policy)DynamoDBResumeCounterPolicy
(your custom policy)
2.5 Name and Create
Role name:
lambda-dynamodb-role
Click "Create role"
Step 3: Create Lambda Function
3.1 Navigate to Lambda Console
Search for "Lambda" in AWS Console
Click "Create function"
3.2 Configure Function
Function name:
resume-visitor-counter
Runtime: Python 3.9 (or latest)
Execution role: Use existing role →
lambda-dynamodb-role
Click "Create function"
3.3 Write Lambda Function Code
Replace the default code with:
import json
import boto3
from botocore.exceptions import ClientError
# Initialize DynamoDB client
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('resume-visitor-count')
def lambda_handler(event, context):
try:
# Get current count
response = table.get_item(
Key={'id': 'visitor-count'}
)
# If item doesn't exist, start with 0
if 'Item' not in response:
current_count = 0
else:
current_count = response['Item']['count']
# Increment count
new_count = current_count + 1
# Update count in DynamoDB
table.put_item(
Item={
'id': 'visitor-count',
'count': new_count
}
)
# Return response with CORS headers
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS'
},
'body': json.dumps({
'count': new_count
})
}
except ClientError as e:
print(f"Error: {e}")
return {
'statusCode': 500,
'headers': {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS'
},
'body': json.dumps({
'error': 'Internal server error'
})
}
3.4 Deploy Function
Click "Deploy"
Test the function by clicking "Test"
Create a test event (use default template)
Test to verify it works
Step 4: Create API Gateway
4.1 Navigate to API Gateway Console
Search for "API Gateway" in AWS Console
Click "Create API"
Choose "REST API" (not private)
Click "Build"
4.2 Configure API
API name:
resume-api
Description:
API for resume visitor counter
Endpoint Type: Regional
Click "Create API"
4.3 Create Resource and Method
Click "Actions" → "Create Resource"
Resource Name:
visitor-count
Resource Path:
/visitor-count
Enable API Gateway CORS: Check this box
Click "Create Resource"
With
/visitor-count
selected, click "Actions" → "Create Method"Select "GET" from dropdown
Click the checkmark
4.4 Configure GET Method
Integration type: Lambda Function
Lambda Region: Your region
Lambda Function:
resume-visitor-counter
Click "Save"
Click "OK" to permit API Gateway to invoke Lambda
4.5 Enable CORS
Select
/visitor-count
resourceClick "Actions" → "Enable CORS"
Access-Control-Allow-Origin:
*
Access-Control-Allow-Headers:
Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token
Access-Control-Allow-Methods: Select GET
Click "Enable CORS and replace existing CORS headers"
4.6 Deploy API
Click "Actions" → "Deploy API"
Deployment stage: New Stage
Stage name:
prod
Click "Deploy"
4.7 Get API URL
Copy the "Invoke URL" from the stage editor
Your API endpoint will be:
https://your-api-id.execute-api.region.amazonaws.com/prod/visitor-count
Step 5: Connect Frontend to API
5.1 Add JavaScript to Your HTML
Add this JavaScript code to your resume HTML file:
// Function to fetch and display visitor count
async function updateVisitorCount() {
try {
const response = await fetch('https://your-api-id.execute-api.region.amazonaws.com/prod/visitor-count', {
method: 'GET',
headers: {
'Content-Type': 'application/json',
}
});
if (response.ok) {
const data = await response.json();
document.getElementById('visitor-count').textContent = data.count;
} else {
console.error('Failed to fetch visitor count');
document.getElementById('visitor-count').textContent = 'Error';
}
} catch (error) {
console.error('Error:', error);
document.getElementById('visitor-count').textContent = 'Error';
}
}
// Call function when page loads
document.addEventListener('DOMContentLoaded', updateVisitorCount);
5.2 Add HTML Element
Add this HTML element where you want to display the count:
<div class="visitor-counter">
<p>Visitor Count: <span id="visitor-count">Loading...</span></p>
</div>
5.3 Style the Counter (Optional)
Add CSS to style your visitor counter:
.visitor-counter {
text-align: center;
margin: 20px 0;
padding: 10px;
background-color: #f0f0f0;
border-radius: 5px;
}
#visitor-count {
font-weight: bold;
color: #007bff;
}
Step 6: Testing Your Implementation
6.1 Test Lambda Function
Go to the Lambda console
Test function with sample event
Verify DynamoDB count increases
6.2 Test API Gateway
Use the API Gateway test feature
Or test directly with curl:
curl https://your-api-id.execute-api.region.amazonaws.com/prod/visitor-count
6.3 Test Frontend Integration
Open your resume website
Check browser developer tools for any errors
Verify visitor count displays and increments on refresh
Troubleshooting Common Issues
Lambda Function Issues
Permission Errors: Verify IAM role has DynamoDB access
Table Not Found: Check table name matches exactly
Timeout: Increase Lambda timeout in configuration
API Gateway Issues
CORS Errors: Ensure CORS is properly enabled
404 Errors: Verify resource path and deployment
403 Errors: Check API Gateway permissions
Frontend Issues
Network Errors: Check the API URL is correct
JavaScript Errors: Use the browser console to debug
Element Not Found: Verify HTML element ID matches JavaScript
Best Practices
Security
Use least privilege IAM policies (as shown in Step 2)
Consider API throttling for production
Validate input data in the Lambda function
Regularly review and audit permissions
Performance
Use DynamoDB on-demand billing for low traffic
Consider CloudFront for API caching
Minimise Lambda cold starts
Monitoring
Enable CloudWatch logging
Set up CloudWatch alarms for errors
Monitor DynamoDB metrics
Cost Optimization
DynamoDB: Use on-demand pricing for low volume
Lambda: First 1M invocations per month are free
API Gateway: First 1M calls per month are free
Data Transfer: Minimal costs for typical resume traffic
Next Steps
After completing this section:
Test thoroughly: Try different browsers and devices
Add error handling: Improve user experience with better error messages
Consider analytics: Track more detailed visitor information
Security hardening: Implement rate limiting and input validation
Automation: Set up Infrastructure as Code (CloudFormation/Terraform)
Your visitor counter API is now complete and integrated with your resume! This demonstrates several key AWS services working together and shows practical cloud development skills to potential employers.
Subscribe to my newsletter
Read articles from Praneeth Perera directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Praneeth Perera
Praneeth Perera
As a Senior System Administrator at NoeHow, I specialise in network analysis, troubleshooting, automation, and system migrations using Python, Perl, Bash, and MySQL. I'm passionate about training teams and staying current with emerging technologies to optimise system functionality and user experiences. With RHCE and AWS Certified Solutions Architect Associate certifications, a B.Sc. in Information Systems from the University of Colombo, an MBA from the University of Bedfordshire, and a strong accountancy background, I bring technical expertise and business acumen to every project. I thrive in collaborative environments and am eager to connect with innovative professionals.