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

Praneeth PereraPraneeth Perera
6 min read

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

  1. Log in tothe AWS Console

  2. Search for "DynamoDB" and select it

  3. 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

  1. Once the table is created, click on it

  2. Go to the "Items" tab

  3. Click "Create item"

  4. Add the following attributes:

    • id: visitor-count (String)

    • count: 0 (Number)

  5. Click "Create item"


Step 2: Create an IAM Role for Lambda

2.1 Navigate to IAM Console

  1. Search for "IAM" in AWS Console

  2. Click "Roles" in the left sidebar

  3. Click "Create role"

2.2 Configure Role

  1. Trusted entity type: AWS service

  2. Service: Lambda

  3. Click "Next"

2.3 Create Custom Policy for DynamoDB

  1. Click "Create policy"

  2. Select "JSON" tab

  3. 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"
        }
    ]
}
  1. Click "Next: Tags" (skip tags)

  2. Click "Next: Review"

  3. Name: DynamoDBResumeCounterPolicy

  4. 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

  1. Search for "Lambda" in AWS Console

  2. 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

  1. Click "Deploy"

  2. Test the function by clicking "Test"

  3. Create a test event (use default template)

  4. Test to verify it works


Step 4: Create API Gateway

4.1 Navigate to API Gateway Console

  1. Search for "API Gateway" in AWS Console

  2. Click "Create API"

  3. Choose "REST API" (not private)

  4. 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

  1. Click "Actions" → "Create Resource"

    • Resource Name: visitor-count

    • Resource Path: /visitor-count

    • Enable API Gateway CORS: Check this box

    • Click "Create Resource"

  2. With /visitor-count selected, click "Actions" → "Create Method"

    • Select "GET" from dropdown

    • Click the checkmark

4.4 Configure GET Method

  1. Integration type: Lambda Function

  2. Lambda Region: Your region

  3. Lambda Function: resume-visitor-counter

  4. Click "Save"

  5. Click "OK" to permit API Gateway to invoke Lambda

4.5 Enable CORS

  1. Select /visitor-count resource

  2. Click "Actions" → "Enable CORS"

  3. Access-Control-Allow-Origin: *

  4. Access-Control-Allow-Headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token

  5. Access-Control-Allow-Methods: Select GET

  6. Click "Enable CORS and replace existing CORS headers"

4.6 Deploy API

  1. Click "Actions" → "Deploy API"

  2. Deployment stage: New Stage

  3. Stage name: prod

  4. Click "Deploy"

4.7 Get API URL


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

  1. Go to the Lambda console

  2. Test function with sample event

  3. Verify DynamoDB count increases

6.2 Test API Gateway

  1. Use the API Gateway test feature

  2. Or test directly with curl:

curl https://your-api-id.execute-api.region.amazonaws.com/prod/visitor-count

6.3 Test Frontend Integration

  1. Open your resume website

  2. Check browser developer tools for any errors

  3. 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:

  1. Test thoroughly: Try different browsers and devices

  2. Add error handling: Improve user experience with better error messages

  3. Consider analytics: Track more detailed visitor information

  4. Security hardening: Implement rate limiting and input validation

  5. 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.

0
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.