Skip to content

t-maypat/aws-serverless-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Serverless Web Application on AWS

A production-ready, serverless web app that serves a frontend site from S3/CloudFront and uses an AWS Lambda function with DynamoDB to track page views.

Features

  • Frontend hosted on Amazon S3 (optionally via CloudFront).
  • Serverless backend using AWS Lambda with a Function URL (or API Gateway).
  • DynamoDB table stores and increments a single counter for page views.
  • Zero servers to manage, fast global delivery with CloudFront, and pay-per-use compute.

Architecture

architecture

Tech Stack

  • Front end: HTML, CSS, JavaScript (vanilla)
  • Backend: AWS Lambda (Python)
  • Data: Amazon DynamoDB
  • Hosting/CDN: Amazon S3, Amazon CloudFront

Project Structure

index.html        # Static page UI (form + counter)
style.css         # Styles
script.js         # Front-end logic and backend call
lambda-function.py# Lambda handler that increments the counter in DynamoDB
README.md         # This file

How It Works

  • The browser loads the static site from S3 (optionally via CloudFront).
  • script.js calls the Lambda Function URL to fetch/increment the view count.
  • The Lambda function reads item id = "0" from DynamoDB, increments views, writes it back, and returns the count as JSON.

Setup and Deployment

Prerequisites:

  • AWS account with permissions for S3, CloudFront (optional), Lambda, and DynamoDB
  • AWS CLI configured (aws configure)
  • Python 3.9+ for packaging the Lambda (if needed)

1) Create the DynamoDB table

  • Table name: serverless-web-application-on-aws
  • Partition key: id (String)
  • Create a seed item with id = "0" and views = 0.

Using AWS CLI (replace region as needed):

aws dynamodb create-table --table-name serverless-web-application-on-aws --attribute-definitions AttributeName=id,AttributeType=S --key-schema AttributeName=id,KeyType=HASH --billing-mode PAY_PER_REQUEST --region us-east-1

aws dynamodb put-item --table-name serverless-web-application-on-aws --item {"id":{"S":"0"},"views":{"N":"0"}} --region us-east-1

2) Deploy the Lambda function

This repo’s lambda-function.py uses the table name serverless-web-application-on-aws. You can keep that name or change the code to read a TABLE_NAME env var.

Steps (console) — simplest path:

  • Create a Lambda function (Python 3.10 or similar).
  • Add basic execution role with permissions to read/write the DynamoDB table.
  • Create a Function URL (Auth = NONE) and enable CORS (e.g., allow your S3/CloudFront origin).
  • Upload the code from lambda-function.py.

Or package with CLI:

copy lambda-function.py function\lambda-function.py
cd function
tar -a -c -f function.zip lambda-function.py
cd ..
rem Create function (first time)
aws lambda create-function --function-name view-counter --runtime python3.10 --role arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_WITH_DDB_ACCESS> --handler lambda-function.lambda_handler --zip-file fileb://function/function.zip --region us-east-1

rem Or update code (subsequent deployments)
aws lambda update-function-code --function-name view-counter --zip-file fileb://function/function.zip --region us-east-1

rem Create Function URL (one time)
aws lambda create-function-url-config --function-name view-counter --auth-type NONE --cors AllowOrigins='["*"]',AllowMethods='["GET"]' --region us-east-1

rem Get Function URL
aws lambda get-function-url-config --function-name view-counter --region us-east-1

Copy the Function URL you get and update the front end (next step).

3) Configure the front end

Edit script.js and set your Function URL:

const counter = document.querySelector(".counter-number");
async function updateCounter() {
	let response = await fetch("https://YOUR_FUNCTION_ID.lambda-url.YOUR-REGION.on.aws/");
	let data = await response.json();
	counter.innerHTML = `Views: ${data}`;
}
updateCounter();

4) Host the static site on S3

aws s3 mb s3://<your-unique-bucket-name> --region us-east-1
aws s3 website s3://<your-unique-bucket-name>/ --index-document index.html --error-document index.html
aws s3 cp index.html s3://<your-unique-bucket-name>/ --acl public-read
aws s3 cp style.css s3://<your-unique-bucket-name>/ --acl public-read
aws s3 cp script.js s3://<your-unique-bucket-name>/ --acl public-read

Make sure the bucket policy or S3 Public Access settings allow static website hosting (or use CloudFront, recommended for production).

5) Optional: Add CloudFront

  • Create a CloudFront distribution with the S3 website endpoint as origin.
  • Set a default behavior to allow GET/HEAD.
  • Add your custom domain + SSL via ACM for a polished public URL.

Local Development

You can open index.html directly or use a local server for CORS-friendly testing:

python -m http.server 8000

Note: The counter still calls the deployed Lambda URL.

Security and Cost Notes

  • IAM least privilege: Lambda role should allow only the specific DynamoDB table access.
  • CORS: Restrict Function URL CORS to your S3/CloudFront origin in production.
  • API protection: Consider placing Lambda behind API Gateway with a WAF and authentication for public endpoints.
  • Costs: Uses pay-per-request services; typical demo usage is cents/month, but always monitor with AWS Budgets.

What I Built and Why

I designed this as a minimal, production-minded serverless pattern: static hosting + a small compute function + managed NoSQL. It’s fast to deploy, easy to scale, and showcases cloud-native fundamentals.

License

MIT

About

A serverless web app that serves a frontend site from S3/CloudFront and uses an AWS Lambda function with DynamoDB to track page views.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors