Skip to content

A modern serverless three-tier web application built on AWS demonstrating cloud-native architecture best practices. Features React SPA frontend hosted on S3 & served via CloudFront), serverless REST API layer (Lambda/API Gateway), and DynamoDB database with automated deployment via AWS SAM.

License

Notifications You must be signed in to change notification settings

Heeyaichen/aws-three-tier-architecture

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

44 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

AWS Three-Tier Serverless Application

A modern, serverless three-tier-architecture web application built on AWS, demonstrating best practices for cloud-native architecture using React, AWS Lambda, API Gateway, DynamoDB, S3, and CloudFront.

Image

πŸ“‹ Table of Contents

πŸ—οΈ Architecture Overview

This application implements a three-tier serverless architecture on AWS:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Presentation   β”‚    β”‚   Application    β”‚    β”‚      Data       β”‚
β”‚      Tier       β”‚    β”‚      Tier        β”‚    β”‚      Tier       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   React SPA     β”‚    β”‚   AWS Lambda     β”‚    β”‚   DynamoDB      β”‚
β”‚   S3 Bucket     │◄──►│   API Gateway    │◄──►│   NoSQL DB      β”‚
β”‚   CloudFront    β”‚    β”‚   Python 3.13    β”‚    β”‚   Pay-per-use   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Features

  • βœ… Serverless: No server management required
  • βœ… Scalable: Auto-scaling based on demand
  • βœ… Cost-effective: Pay only for what you use
  • βœ… Secure: IAM-based access control
  • βœ… Fast: Global CDN distribution
  • βœ… Modern: React SPA with responsive design

πŸ“ Project Structure

aws-three-tier-architecture/
β”œβ”€β”€ frontend/                    # Presentation Tier (React SPA)
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/         # React components
β”‚   β”‚   β”‚   β”œβ”€β”€ TodoForm.jsx   # Todo creation/editing form
β”‚   β”‚   β”‚   β”œβ”€β”€ TodoItem.jsx   # Individual todo item
β”‚   β”‚   β”‚   └── TodoList.jsx   # Todo list container
β”‚   β”‚   β”œβ”€β”€ App.jsx            # Main application component
β”‚   β”‚   └── main.jsx           # Application entry point
β”‚   β”œβ”€β”€ package.json           # Dependencies and scripts
β”‚   └── vite.config.js         # Vite build configuration
β”œβ”€β”€ sam-app/                    # Application & Data Tiers (SAM)
β”‚   β”œβ”€β”€ todo_function/         # Lambda function code
β”‚   β”‚   β”œβ”€β”€ app.py            # Main Lambda handler
β”‚   β”‚   └── requirements.txt  # Python dependencies
β”‚   β”œβ”€β”€ events/               # Test events for local development
β”‚   β”œβ”€β”€ tests/                # Unit and integration tests
β”‚   └── template.yaml         # SAM/CloudFormation template
β”œβ”€β”€ deploy.sh                  # Automated deployment script
└── delete.sh                 # Cleanup script

πŸ”§ Prerequisites

Required Tools & Technologies

  1. AWS CLI - Configure AWS credentials

    aws configure
  2. AWS SAM CLI - Deploy serverless applications

    # macOS
    brew install aws-sam-cli

    For Windows/Linux:

  3. Node.js & npm - Frontend development

    node --version  # v18+ recommended
    npm --version
  4. Python 3.13 - Lambda runtime

    python3 --version

AWS Account Requirements

  • Active AWS account with appropriate permissions
  • IAM user with programmatic access
  • Sufficient service limits for:
    • Lambda functions
    • API Gateway APIs
    • DynamoDB tables
    • S3 buckets
    • CloudFront distributions

πŸš€ Getting Started

Quick Deployment

  1. Clone the repository

    git clone <repository-url>
    cd aws-three-tier-architecture
  2. Make deployment script executable

    chmod +x deploy.sh
  3. Deploy the application

    ./deploy.sh
  4. Access your application

    • The script will output the CloudFront URL
    • Open the URL in your browser

Manual Deployment

If you prefer manual deployment:

  1. Deploy SAM application

    cd sam-app
    sam build
    sam deploy --guided
  2. Build and deploy frontend

    cd ../frontend
    npm install
    npm run build
    
    # Upload to S3 (replace with your bucket name)
    aws s3 sync dist/ s3://your-bucket-name --delete

πŸ›οΈ Architecture Deep Dive

Presentation Tier

  • Technology: React 18 with Vite
  • Hosting: Amazon S3 static website hosting
  • CDN: Amazon CloudFront for global distribution
  • Features:
    • Single Page Application (SPA)
    • Responsive design
    • Environment-based API configuration

Application Tier

  • Compute: AWS Lambda (Python 3.13)
  • API: Amazon API Gateway (REST API)
  • Features:
    • Serverless compute
    • Auto-scaling
    • CORS enabled
    • RESTful API design

Data Tier

  • Database: Amazon DynamoDB
  • Configuration:
    • Pay-per-request billing
    • Single table design
    • Partition key: id (String)

πŸ” IAM Roles & Permissions

Lambda Execution Role

The SAM template automatically creates an IAM role for the Lambda function with these policies:

1. DynamoDBCrudPolicy

Policies: 
  - DynamoDBCrudPolicy:
      TableName: !Ref DynamoDBTable

Purpose: Grants Lambda function permissions to perform CRUD operations on the DynamoDB table.

AWS Managed Policy: Provides these permissions:

  • dynamodb:GetItem - Read individual items
  • dynamodb:PutItem - Create new items
  • dynamodb:UpdateItem - Modify existing items
  • dynamodb:DeleteItem - Remove items
  • dynamodb:Scan - Read all items
  • dynamodb:Query - Query items with conditions

Documentation: DynamoDB IAM Policies

2. AWSLambdaBasicExecutionRole

Policies:
  - AWSLambdaBasicExecutionRole

Purpose: Provides basic Lambda execution permissions.

AWS Managed Policy: Includes:

  • logs:CreateLogGroup - Create CloudWatch log groups
  • logs:CreateLogStream - Create log streams
  • logs:PutLogEvents - Write logs to CloudWatch

Documentation: Lambda Execution Role

CloudFront Origin Access Control (OAC)

S3 Bucket Policy

CloudFrontS3AccessBucketPolicy:
  Type: AWS::S3::BucketPolicy
  Properties:
    PolicyDocument:
      Statement:
        - Effect: Allow
          Principal: 
            Service: cloudfront.amazonaws.com
          Action: s3:GetObject
          Resource: !Sub "arn:aws:s3:::${FrontendBucket}/*"
          Condition:
            StringEquals:
              AWS:SourceArn: !Sub "arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}"

Purpose: Allows CloudFront to access S3 bucket objects while keeping the bucket private.

Security Benefits:

  • S3 bucket remains private (no public access)
  • Only CloudFront can access bucket contents
  • Prevents direct S3 access bypassing CloudFront

Documentation: CloudFront OAC

πŸ”„ Service Interactions

Complete Request Flow

1. User Interaction β†’ CloudFront

User Browser β†’ CloudFront Distribution
  • User accesses application via CloudFront URL
  • CloudFront serves cached content when possible
  • Routes requests based on path patterns

2. Static Content Delivery

CloudFront β†’ S3 Bucket (via OAC)

Configuration in template.yaml:

Origins:
  - Id: S3Origin
    DomainName: !GetAtt FrontendBucket.RegionalDomainName
    OriginAccessControlId: !GetAtt OriginAccessControl.Id
  • React SPA files served from S3
  • OAC ensures secure access
  • Cached globally for performance

3. API Request Routing

CloudFront β†’ API Gateway β†’ Lambda β†’ DynamoDB

CloudFront Cache Behavior:

CacheBehaviors:
- PathPattern: "/api/*"
  TargetOriginId: ApiOrigin
  MinTTL: 0
  DefaultTTL: 0
  MaxTTL: 0  # No caching for API calls

API Gateway Integration:

Origins:
  - Id: ApiOrigin
    DomainName: !Sub "${TodoAPI}.execute-api.${AWS::Region}.amazonaws.com"
    OriginPath: "/prod"

4. Lambda Function Routing

Event Configuration in template.yaml:

Events:
  GetTodos:
    Type: Api
    Properties:
      RestApiId: !Ref TodoAPI
      Path: /api/todos
      Method: get

Lambda Handler Logic:

def lambda_handler(event, context):
    method = event.get('httpMethod')
    path_parameters = event.get('pathParameters') or {}
    todo_id = path_parameters.get('id')
    
    if method == 'GET' and not todo_id:
        return get_todos()
    elif method == 'POST' and not todo_id:
        return create_todo(body)
    # ... other routes

5. DynamoDB Operations

Table Configuration:

DynamoDBTable:
  Type: AWS::DynamoDB::Table
  Properties:
    TableName: todos
    AttributeDefinitions:
      - AttributeName: id 
        AttributeType: S
    KeySchema:
      - AttributeName: id
        KeyType: HASH
    BillingMode: PAY_PER_REQUEST

Lambda DynamoDB Access:

# Initialize DynamoDB resource
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("todos")

# CRUD operations
def get_todos():
    result = table.scan()
    return response(200, result["Items"])

def create_todo(data):
    todo = {
        "id": str(uuid.uuid4()),
        "text": data["text"],
        "completed": False,
        "createdAt": now_iso_ms(),
    }
    table.put_item(Item=todo)
    return response(201, todo)

Environment Variables & Configuration

SAM Template Global Variables:

Globals:
  Function:
    Environment:
      Variables:
        BUCKET_NAME: !Ref BucketName
        TABLE_NAME: !Ref DynamoDBTable

React Environment Configuration:

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || "/api";

🌐 CORS Configuration

Cross-Origin Resource Sharing (CORS) is critical for this architecture since the React frontend (served from CloudFront) needs to make API calls to API Gateway. This application implements CORS at multiple levels:

1. API Gateway CORS Configuration

Template Configuration:

TodoAPI:
  Type: AWS::Serverless::Api
  Properties:
    StageName: prod
    Cors:
      AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"
      AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
      AllowOrigin: "'*'"

Purpose: Enables API Gateway to handle preflight OPTIONS requests and set appropriate CORS headers.

Key Settings:

  • AllowMethods: Permits all HTTP methods used by the application
  • AllowHeaders: Allows standard headers plus AWS-specific headers
  • AllowOrigin: Set to '*' for development (restrict in production)

Documentation: API Gateway CORS

2. Lambda Function CORS Headers

Response Headers in app.py:

def response(status_code, body):
    return {
        "statusCode": status_code,
        "headers": {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
            "Access-Control-Allow-Headers": "Content-Type"
        },
        "body": json.dumps(body, default=str)
    }

Purpose: Ensures every Lambda response includes CORS headers for browser compatibility.

3. CloudFront CORS Header Forwarding

CloudFront Configuration:

CacheBehaviors:
- PathPattern: "/api/*"
  ForwardedValues:
    Headers:
      - Authorization
      - Content-Type

Purpose: Ensures CloudFront forwards necessary headers to API Gateway for CORS processing.

4. Common CORS Issues & Solutions

Issue: "CORS policy: No 'Access-Control-Allow-Origin' header"

Solution: Verify both API Gateway and Lambda function return CORS headers

Issue: "CORS policy: Request header 'content-type' is not allowed"

Solution: Add Content-Type to AllowHeaders in API Gateway configuration

Issue: Preflight requests failing

Solution: Ensure API Gateway handles OPTIONS method correctly and returns appropriate CORS headers

Environment Variables & Configuration

SAM Template Global Variables:

Globals:
  Function:
    Environment:
      Variables:
        BUCKET_NAME: !Ref BucketName
        TABLE_NAME: !Ref DynamoDBTable

React Environment Configuration:

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || "/api";

πŸ“¦ Deployment

Automated Deployment Script

The deploy.sh script automates the entire deployment process:

Key Features:

  • Builds and deploys SAM application
  • Extracts CloudFormation outputs
  • Configures React environment variables
  • Uploads built frontend to S3
  • Provides final application URL

Manual Deployment Steps

  1. Deploy Backend Infrastructure

    cd sam-app
    sam build
    sam deploy --guided
  2. Configure Frontend Environment

    cd ../frontend
    echo "VITE_API_BASE_URL=https://your-cloudfront-url/api" > .env.production
  3. Build and Deploy Frontend

    npm install
    npm run build
    aws s3 sync dist/ s3://your-bucket-name --delete

🧹 Cleanup

Automated Cleanup Script

The delete.sh script safely removes all AWS resources:

Key Features:

  • Deletes CloudFormation stack
  • Removes S3 bucket and its contents
  • Ensures no orphaned resources remain

Important: S3 buckets must be empty before CloudFormation can delete them.

Manual Cleanup

  1. Empty S3 Bucket

    aws s3 rm s3://your-bucket-name --recursive
  2. Delete SAM Stack

    cd sam-app
    sam delete

πŸ“š API Documentation

Base URL

https://your-cloudfront-url/api

Endpoints

GET /todos

Retrieve all todos

curl https://your-cloudfront-url/api/todos

Response:

[
  {
    "id": "uuid",
    "text": "Sample todo",
    "completed": false,
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
]

POST /todos

Create a new todo

curl -X POST https://your-cloudfront-url/api/todos \
  -H "Content-Type: application/json" \
  -d '{"text": "New todo item"}'

PUT /todos/{id}

Update an existing todo

curl -X PUT https://your-cloudfront-url/api/todos/uuid \
  -H "Content-Type: application/json" \
  -d '{"text": "Updated text", "completed": true}'

DELETE /todos/{id}

Delete a todo

curl -X DELETE https://your-cloudfront-url/api/todos/uuid

πŸ”§ Troubleshooting

Common Issues

1. CORS Errors

Symptom: Browser console shows CORS errors Solution: Verify API Gateway CORS configuration in template.yaml

2. 403 Forbidden on S3

Symptom: CloudFront returns 403 for static files Solution: Check S3 bucket policy and OAC configuration

3. Lambda Function Errors

Symptom: 500 errors from API Solution: Check CloudWatch logs for Lambda function

4. DynamoDB Access Denied

Symptom: Lambda cannot access DynamoDB Solution: Verify IAM role has DynamoDBCrudPolicy

Debugging Commands

# Check SAM deployment status
sam list stack-outputs

# View Lambda logs
sam logs -n TodoFunction --stack-name your-stack-name

# Test Lambda function locally
sam local start-api

# Validate SAM template
sam validate

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“– Additional Resources

AWS Documentation

Best Practices


Built using AWS Serverless Technologies

πŸš€ Future Enhancements

This section outlines potential improvements and enhancements that could be implemented to further strengthen the application's security, scalability, reliability, and performance.

πŸ”’ Security Enhancements

Authentication & Authorization

  • AWS Cognito Integration: Implement user authentication and authorization
  • JWT Token Validation: Add token-based authentication for API endpoints
  • API Key Management: Implement API keys for rate limiting and access control
  • Role-Based Access Control (RBAC): Define granular permissions for different user roles

Enhanced IAM Security

  • Least Privilege Principle: Further restrict IAM policies to minimum required permissions
  • Cross-Account Roles: Implement cross-account access for multi-environment deployments
  • Resource-Based Policies: Add more granular resource-level permissions
  • IAM Policy Conditions: Implement time-based and IP-based access restrictions

CORS Security Hardening

  • Domain-Specific CORS: Replace wildcard (*) with specific domain origins in production
  • Credential-Aware CORS: Implement Access-Control-Allow-Credentials for authenticated requests
  • Header Validation: Restrict allowed headers to only necessary ones
  • Method Restrictions: Limit HTTP methods based on endpoint requirements

Data Protection

  • DynamoDB Encryption: Enable encryption at rest and in transit
  • S3 Bucket Encryption: Implement server-side encryption for static assets
  • Secrets Management: Use AWS Secrets Manager for sensitive configuration
  • Input Validation: Add comprehensive input sanitization and validation

⚑ Performance Optimizations

Caching Strategy

  • DynamoDB DAX: Implement DynamoDB Accelerator for microsecond latency
  • API Gateway Caching: Enable response caching for read-heavy operations
  • CloudFront Edge Caching: Optimize cache behaviors and TTL settings
  • Lambda Provisioned Concurrency: Reduce cold start latency for critical functions

Database Optimization

  • DynamoDB Global Secondary Indexes (GSI): Add indexes for efficient querying
  • Batch Operations: Implement batch read/write operations for bulk data
  • Connection Pooling: Optimize database connections in Lambda functions
  • Query Optimization: Replace scan operations with more efficient query patterns

πŸ“ˆ Scalability Improvements

Auto-Scaling Configuration

  • DynamoDB Auto Scaling: Configure automatic capacity scaling based on demand
  • Lambda Concurrency Limits: Set appropriate reserved and provisioned concurrency
  • API Gateway Throttling: Implement rate limiting and burst capacity management
  • CloudFront Geographic Restrictions: Optimize content delivery based on user location

Multi-Region Architecture

  • Cross-Region Replication: Implement DynamoDB Global Tables for disaster recovery
  • Multi-Region CloudFront: Deploy edge locations closer to global users
  • Route 53 Health Checks: Add DNS failover and health monitoring
  • Regional Lambda Deployments: Deploy functions in multiple regions for redundancy

πŸ›‘οΈ Reliability & Monitoring

Error Handling & Resilience

  • Circuit Breaker Pattern: Implement failure isolation and recovery mechanisms
  • Retry Logic: Add exponential backoff for transient failures
  • Dead Letter Queues: Implement DLQ for failed Lambda invocations
  • Graceful Degradation: Design fallback mechanisms for service failures

Observability & Monitoring

  • AWS X-Ray Tracing: Implement distributed tracing for request flow analysis
  • Custom CloudWatch Metrics: Add business-specific metrics and dashboards
  • Log Aggregation: Centralize logs using CloudWatch Logs Insights
  • Alerting Strategy: Set up proactive alerts for system health and performance

Backup & Disaster Recovery

  • Automated Backups: Implement point-in-time recovery for DynamoDB
  • Cross-Region Backup: Store backups in multiple regions
  • Infrastructure as Code Versioning: Version control for SAM templates
  • Recovery Testing: Regular disaster recovery drills and testing

πŸ”§ Development & Operations

CI/CD Pipeline Enhancements

  • Multi-Stage Deployments: Implement dev/staging/prod pipeline
  • Automated Testing: Add unit, integration, and end-to-end tests
  • Security Scanning: Integrate SAST/DAST tools in deployment pipeline
  • Blue-Green Deployments: Implement zero-downtime deployment strategies

Infrastructure Improvements

  • Environment Separation: Separate AWS accounts for different environments
  • Resource Tagging Strategy: Implement comprehensive tagging for cost allocation
  • Cost Optimization: Regular cost analysis and resource right-sizing
  • Compliance Monitoring: Implement AWS Config for compliance tracking

API Enhancements

  • API Versioning: Implement versioning strategy for backward compatibility
  • Request/Response Validation: Add JSON schema validation
  • Rate Limiting: Implement per-user and per-endpoint rate limiting
  • API Documentation: Auto-generate OpenAPI/Swagger documentation

πŸ“‹ Implementation Priority

Phase 1 (High Priority)

  1. Domain-specific CORS configuration
  2. Input validation and sanitization
  3. CloudWatch monitoring and alerting
  4. Automated backup strategy

Phase 2 (Medium Priority)

  1. AWS Cognito authentication
  2. DynamoDB performance optimization
  3. Multi-environment CI/CD pipeline
  4. Enhanced error handling

Phase 3 (Long-term)

  1. Multi-region deployment
  2. Advanced analytics implementation
  3. Real-time features
  4. Mobile application development

These enhancements should be prioritized based on business requirements, user feedback, and system performance metrics. Each improvement should be implemented incrementally with proper testing and monitoring.

About

A modern serverless three-tier web application built on AWS demonstrating cloud-native architecture best practices. Features React SPA frontend hosted on S3 & served via CloudFront), serverless REST API layer (Lambda/API Gateway), and DynamoDB database with automated deployment via AWS SAM.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published