A sample AWS CDK project demonstrating production-ready serverless infrastructure for Single Page Applications (SPA). This repository showcases reusable CDK constructs and best practices for deploying modern web applications on AWS.
This project provides a complete serverless architecture for SPAs with authentication, API backend, and secure content delivery. It demonstrates:
- Custom CDK construct development and testing
- Multi-region deployment patterns
- Security best practices (WAF, Cognito, API Gateway resource policies)
- Real-world integration with a React frontend
- Comprehensive testing with CDK assertions
- Frontend Delivery: S3 + CloudFront CDN with optional custom domains
- Authentication: AWS Cognito User Pool with JWT-based authorization
- API Backend: API Gateway (REST) + Lambda functions
- Database: DynamoDB with on-demand billing
- Security: WAF protection, ACM certificates, Secrets Manager
- DNS Management: Route53 integration with alternative domain names
- Cross-Region Support: Lambda@Edge, secret replication, and SSM parameter sharing
- Demo Application: React 19 + Vite + Tailwind CSS with authentication flow
βββββββββββββββββββ
β Cognito β
β User Pool β
β (JWT issuer) β
ββββββββββ¬βββββββββ
β JWT verification
ββββββββ βββββββββββββββ βββββββββββββββ΄βββββββββββββ
β User βββββΆβ CloudFront βββββΆβ API Gateway (REST) β
ββββββββ β β β - Resource policy β
β /api/* ββββββΌββββΆβ - Cognito Authorizer β
β β βββββββββββββββ¬βββββββββββββ
β /* ββββββββββΌββββ β
βββββββββββββββ β βΌ
β βββββββββββββββββββ
β β Lambda β
β β (Node.js) β
β ββββββββββ¬βββββββββ
β β
βΌ βΌ
βββββββββββββββ βββββββββββββββ
β S3 Bucket β β DynamoDB β
βββββββββββββββ βββββββββββββββ
This sample deploys two CDK stacks:
| Stack | Region | Description |
|---|---|---|
ServerlessSpaSecurityStack |
us-east-1 | WAF, ACM certificate, Secrets, SSM parameters |
ServerlessSpaMainStack |
ap-northeast-1 | Main application (DynamoDB, Cognito, API, S3) |
The security stack must be deployed in us-east-1 because CloudFront requires WAF WebACLs and ACM certificates in that region.
- Node.js 18.x or later
- AWS CLI configured with appropriate credentials
- AWS account with permissions to create:
- CloudFormation stacks
- S3 buckets, CloudFront distributions
- API Gateway, Lambda functions
- DynamoDB tables, Cognito User Pools
- WAF WebACLs, ACM certificates
- Route53 hosted zone (for custom domains)
- Clone the repository:
git clone <repository-url>
cd serverless-spa-construct-test- Install dependencies:
npm install- Configure environment variables (copy from example):
cp .env.example .env- Edit
.envwith your configuration:
DOMAIN_NAME=www.example.com
ZONE_NAME=example.com
HOSTED_ZONE_ID=Z1234567890ABC
ALTERNATIVE_DOMAIN_NAMES=example.com,alt.example.com
SSM_PREFIX=/serverless-spa/security/
WAF_RATE_LIMIT=2000npx cdk deploy --allCDK automatically resolves dependencies and deploys ServerlessSpaSecurityStack first.
# 1. Deploy security stack (us-east-1)
npx cdk deploy ServerlessSpaSecurityStack
# 2. Deploy main application stack
npx cdk deploy ServerlessSpaMainStackAfter deployment completes, CDK outputs will include:
- CloudFront distribution URL
- Cognito User Pool ID
- API Gateway endpoint
- Custom domain URL (if configured)
npx cdk synthnpx cdk diffnpx cdk destroy --allNote: Some resources may fail to delete if they contain data (S3 buckets, DynamoDB tables). Manual cleanup may be required.
βββ bin/
β βββ serverless-spa-construct-test.ts # CDK app entry point
βββ lib/
β βββ constructs/ # Custom CDK constructs
β β βββ serverless-spa.ts # High-level API
β β βββ serverless-spa-security-construct.ts # Security construct
β β βββ frontend-construct.ts # Low-level: S3 + CloudFront
β β βββ auth-construct.ts # Low-level: Cognito
β β βββ api-construct.ts # Low-level: API Gateway + Lambda
β β βββ database-construct.ts # Low-level: DynamoDB
β β βββ certificate-construct.ts # ACM certificate
β β βββ lambda-edge-construct.ts # Lambda@Edge functions
β β βββ waf-construct.ts # AWS WAFv2
β β βββ secret-construct.ts # Secrets Manager
β β βββ ssm-construct.ts # SSM Parameter Store
β βββ lambda/ # Lambda function handlers
β β βββ custom-header-authorizer.ts # Custom header authorization
β β βββ edge-origin-request.ts # Edge origin request handler
β β βββ rotation-handler.ts # Secret rotation handler
β βββ serverless-spa-main-stack.ts # Main stack definition
β βββ serverless-spa-security-stack.ts # Security stack definition
β βββ index.ts # Public exports
βββ lambda/
β βββ handler.ts # Sample Lambda handler
βββ spa/ # Frontend SPA (Vite + React)
β βββ src/
β β βββ pages/ # Page components
β β β βββ LoginPage.tsx
β β β βββ HomePage.tsx
β β βββ App.tsx # Main application component
β β βββ AuthContext.tsx # Authentication context
β β βββ auth.ts # Cognito authentication logic
β β βββ ProtectedRoute.tsx # Route guard component
β β βββ config.ts # Configuration
β β βββ main.tsx # Application entry point
β βββ index.html
β βββ vite.config.ts
βββ test/ # Test suite
βββ constructs/ # Construct unit tests
β βββ serverless-spa.test.ts
β βββ database-construct.test.ts
β βββ frontend-construct.test.ts
β βββ ...
βββ serverless-spa-main-stack.test.ts
| Command | Description |
|---|---|
npm run build |
Compile TypeScript |
npm run watch |
Watch mode for development |
npm test |
Run Jest tests |
npm run lint |
Run ESLint checks |
npm run lint:fix |
Auto-fix ESLint issues |
npm run format |
Format code with Prettier |
npm run format:check |
Check code formatting |
npx cdk synth |
Synthesize CloudFormation templates |
npx cdk diff |
Compare deployed stack with local state |
npx cdk deploy |
Deploy stacks to AWS |
npx cdk destroy |
Remove stacks from AWS |
Run the test suite:
npm testTests use Jest with CDK assertions to validate CloudFormation template generation. Test coverage includes:
- Construct property validation
- Default configuration testing
- Custom configuration overrides
- Output properties verification
- Cross-region resource integration
This project uses:
- TypeScript 5.9 with strict mode
- ESLint with CDK-specific rules
- Prettier for code formatting
- Jest for unit testing
ServerlessSpaConstruct - Complete SPA setup with factory methods:
// Minimal setup with CloudFront default domain
ServerlessSpaConstruct.minimal(scope, id, props)
// Custom domain from SecurityStack certificate
ServerlessSpaConstruct.withCustomDomain(scope, id, props)
// WAF protection without custom domain
ServerlessSpaConstruct.withWaf(scope, id, props)
// Full-featured production setup
ServerlessSpaConstruct.withCustomDomainAndWaf(scope, id, props)ServerlessSpaSecurityConstruct - Security resources in us-east-1:
// Custom header only
ServerlessSpaSecurityConstruct.minimal(scope, id, props)
// WAF protection
ServerlessSpaSecurityConstruct.withWaf(scope, id, props)
// Custom domain certificate
ServerlessSpaSecurityConstruct.withCertificate(scope, id, props)
// Full security suite
ServerlessSpaSecurityConstruct.withWafAndCertificate(scope, id, props)Fine-grained control with individual constructs:
DatabaseConstruct- DynamoDB tableAuthConstruct- Cognito User PoolApiConstruct- API Gateway + LambdaFrontendConstruct- S3 + CloudFrontCertificateConstruct- ACM certificateWafConstruct- WAF WebACLSecretConstruct- Secrets ManagerLambdaEdgeConstruct- Lambda@Edge functionsSsmConstruct- SSM Parameter Store
- WAF rate limiting protects against DDoS attacks
- API Gateway resource policy restricts access to CloudFront only
- Cognito handles authentication with JWT tokens
- Secrets Manager provides encrypted secret storage with rotation
- Lambda@Edge injects custom headers for origin validation
- Cross-region secret replication for high availability
Create a .env file with the following configuration:
| Variable | Description | Required | Default |
|---|---|---|---|
DOMAIN_NAME |
Primary CloudFront domain | No | - |
ZONE_NAME |
Route53 hosted zone name | No | - |
HOSTED_ZONE_ID |
Route53 hosted zone ID | No | - |
ALTERNATIVE_DOMAIN_NAMES |
Additional domain aliases | No | - |
SSM_PREFIX |
SSM parameter prefix | No | /serverless-spa/security/ |
WAF_RATE_LIMIT |
WAF rate limit (per 5 minutes) | No | 2000 |
This is a sample repository for demonstration purposes. Contributions are welcome for:
- Bug fixes
- Documentation improvements
- Additional test coverage
- New construct features
Please ensure all tests pass before submitting pull requests:
npm test
npm run lint
npm run format:checkMIT
This project demonstrates AWS CDK best practices and modern serverless architecture patterns. It is intended as a reference implementation for building production-ready SPAs on AWS.