Serverless Cloud Resume & Visitor API
Executive Summary
The Cloud Resume Challenge is a full-stack, cloud-native engineering project demonstrating real-world cloud deployment standards. Rather than relying on static site hosting providers, the entire website infrastructure—from DNS routing and SSL/TLS certificate validation to edge content distribution and database microservices—is fully provisioned as code using Terraform.
The frontend is hosted in an encrypted Amazon S3 bucket blocked from direct public access and distributed globally via Amazon CloudFront. A serverless Python AWS Lambda microservice interacts with Amazon DynamoDB using atomic updates to calculate, persist, and serve real-time visitor metrics back to the client interface.
Architecture & Workflow Decisions
- Edge Delivery & Security (CloudFront & S3 OAC): Static assets are secured inside an Amazon S3 bucket with strict public access blocks. Origin Access Control (OAC) policies guarantee that requests can only originate from CloudFront edge distributions.
- Domain & TLS Management (Route 53 & ACM): Custom domain routing (`samuelojo.tech`) is configured via AWS Route 53, with automated SSL/TLS certificate creation and DNS validation using AWS Certificate Manager.
- Serverless Visitor Counter API (Lambda & DynamoDB): Inbound visitors trigger an asynchronous JavaScript `fetch()` call to an AWS Lambda URL endpoint. The Lambda function uses Python's `boto3` library to execute an atomic `ADD` operation on DynamoDB, eliminating race conditions.
- Infrastructure as Code (Terraform Backend): All AWS infrastructure is defined declaratively. State file integrity and concurrent execution locks are managed remotely via an S3 backend bucket and a DynamoDB locking table.
- Continuous Integration / Continuous Deployment (GitHub Actions): Automated pipelines validate, lint, and deploy both frontend static assets and backend IaC code on every Git push using keyless AWS OIDC authentication.
Infrastructure & Code Highlights
Atomic Visitor Counter (`lambda_function.py`)
Uses Python `boto3` to perform an atomic counter increment directly in DynamoDB, ensuring thread-safe visitor counts even during high concurrent traffic spikes.
import json
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('cloud-resume-stats')
def lambda_handler(event, context):
# Atomic update prevents race conditions across concurrent visitors
response = table.update_item(
Key={'id': 'visitor_count'},
UpdateExpression='ADD views :inc',
ExpressionAttributeValues={':inc': 1},
ReturnValues='UPDATED_NEW'
)
views = response['Attributes']['views']
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Origin': 'https://samuelojo.tech',
'Access-Control-Allow-Methods': 'GET, OPTIONS'
},
'body': json.dumps({'count': int(views)})
}
CloudFront Origin Access Control Policy (`main.tf`)
Restricts direct public access to S3, ensuring content is exclusively served via CloudFront edge locations with SigV4 request signing.
# Enforce CloudFront OAC over legacy OAI
resource "aws_cloudfront_origin_access_control" "oac" {
name = "resume-s3-oac"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
# Bucket Policy allowing read access exclusively to CloudFront
resource "aws_s3_bucket_policy" "site_bucket_policy" {
bucket = aws_s3_bucket.resume_bucket.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Sid = "AllowCloudFrontServicePrincipal"
Effect = "Allow"
Principal = { Service = "cloudfront.amazonaws.com" }
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.resume_bucket.arn}/*"
Condition = {
StringEquals = {
"AWS:SourceArn" = aws_cloudfront_distribution.cdn.arn
}
}
}]
})
}
Key Technical Challenges Resolved
State Locking & Remote Backend
Configured a remote Terraform state backend using Amazon S3 for state storage and Amazon DynamoDB for state locking, preventing state corruption during concurrent pipeline triggers.
CORS & Lambda Function URLs
Resolved cross-origin resource sharing (CORS) header mismatches between client-side JavaScript calls and the Lambda endpoint by configuring strict origin validation headers on the function response payload.
Zero-Downtime Cache Invalidation
Implemented automated CloudFront cache invalidation steps (`aws cloudfront create-invalidation`) inside GitHub Actions, ensuring site updates reflect instantly globally without long TTL delay times.