@@ -29,6 +29,40 @@ hugo --minify --gc
2929Deploy Command:
3030hugo && aws s3 sync public/ s3://bryanchasko.com --profile websites-bryanchasko
3131
32+ ## 🏗️ Architecture Diagrams
33+
34+ ### Website Architecture
35+
36+ ``` mermaid
37+ architecture-beta
38+ service user(logos:aws-route53)[User Browser]
39+ service dns(logos:aws-route53)[Route 53 DNS]
40+ service cdn(logos:aws-cloudfront)[CloudFront CDN]
41+ service functions(logos:aws-lambda)[CloudFront Functions]
42+ service bucket(logos:aws-s3)[S3 Bucket]
43+
44+ user:R -- L:dns
45+ dns:R -- L:cdn
46+ cdn:B -- T:functions
47+ functions:B -- T:bucket
48+ ```
49+
50+ ### CI/CD Pipeline
51+
52+ ``` mermaid
53+ architecture-beta
54+ service github(logos:github-actions)[GitHub]
55+ service runner(logos:github-actions)[GitHub Actions]
56+ service cli(logos:aws-cli)[AWS CLI]
57+ service s3(logos:aws-s3)[S3 Deploy]
58+ service cdn_invalidate(logos:aws-cloudfront)[CloudFront Invalidate]
59+
60+ github:R -- L:runner
61+ runner:B -- T:cli
62+ cli:B -- T:s3
63+ s3:R -- L:cdn_invalidate
64+ ```
65+
3266## 🚀 How to Replicate This Stack for Your Own Site
3367
3468This project is designed to be reproducible for any Hugo site wanting WebGL visual effects with professional testing.
@@ -51,6 +85,8 @@ This project is designed to be reproducible for any Hugo site wanting WebGL visu
5185| Baseline Storage | AWS S3 | Visual regression screenshots |
5286| CI/CD | GitHub Actions | Automated test pipeline |
5387| CSS Architecture | CSS Custom Properties | 3-palette theming system |
88+ | CDN | AWS CloudFront | Global content delivery |
89+ | Edge Logic | CloudFront Functions | URL rewriting & redirects |
5490
5591### Quick Start for New Project
5692
@@ -277,6 +313,87 @@ aws iam create-access-key --user-name github-actions-webgl-tests \
277313# Copy the AccessKeyId and SecretAccessKey into GitHub Secrets
278314```
279315
316+ ### CloudFront Functions for Edge Logic
317+
318+ This site uses ** CloudFront Functions** to handle URL rewriting and redirects at the edge (viewer-request stage):
319+
320+ ** Current Function: ` bryanchasko-com-url-rewrite ` **
321+ - Redirects ` /help ` → ` /services ` (case-insensitive)
322+ - Rewrites URLs for SPA routing (e.g., ` /blog ` → ` /blog/index.html ` )
323+ - Executes at CloudFront edge locations (~ 1ms latency)
324+ - Cost: ~ $0.60/month (vs $0.50 per 1M requests for Lambda@Edge)
325+
326+ ** Why CloudFront Functions?**
327+ - ✅ No cold starts (unlike Lambda@Edge)
328+ - ✅ Handles redirects without S3 objects
329+ - ✅ Case-insensitive URL matching
330+ - ✅ Cheaper and faster than Lambda@Edge
331+
332+ ** To Update the Function:**
333+ ``` bash
334+ # Edit function code
335+ cat > /tmp/function.js << 'EOF '
336+ function handler(event) {
337+ var request = event.request;
338+ var uri = request.uri.toLowerCase();
339+
340+ // Add your redirects here
341+ if (uri === '/help' || uri === '/help/') {
342+ return {
343+ statusCode: 301,
344+ statusDescription: 'Moved Permanently',
345+ headers: { 'location': { value: '/services' } }
346+ };
347+ }
348+
349+ // URL rewriting for SPA routing
350+ if (!uri.includes('.') && !uri.endsWith('/')) {
351+ request.uri = uri + '/index.html';
352+ }
353+ else if (uri.endsWith('/') && !uri.endsWith('/index.html')) {
354+ request.uri = uri + 'index.html';
355+ }
356+
357+ return request;
358+ }
359+ EOF
360+
361+ # Get current DEVELOPMENT version ETag
362+ DEV_ETAG=$( aws cloudfront get-function \
363+ --name bryanchasko-com-url-rewrite \
364+ --stage DEVELOPMENT \
365+ --profile websites-bryanchasko \
366+ /tmp/dev-function.js 2>&1 | jq -r ' .ETag' )
367+
368+ # Update DEVELOPMENT version
369+ aws cloudfront update-function \
370+ --name bryanchasko-com-url-rewrite \
371+ --function-code fileb:///tmp/function.js \
372+ --function-config Comment=" URL rewriting and redirects" ,Runtime=cloudfront-js-1.0 \
373+ --if-match " $DEV_ETAG " \
374+ --profile websites-bryanchasko
375+
376+ # Get new ETag and publish to LIVE
377+ NEW_ETAG=$( aws cloudfront get-function \
378+ --name bryanchasko-com-url-rewrite \
379+ --stage DEVELOPMENT \
380+ --profile websites-bryanchasko \
381+ /tmp/dev-function-updated.js 2>&1 | jq -r ' .ETag' )
382+
383+ aws cloudfront publish-function \
384+ --name bryanchasko-com-url-rewrite \
385+ --if-match " $NEW_ETAG " \
386+ --profile websites-bryanchasko
387+
388+ # Invalidate cache to apply changes
389+ aws cloudfront create-invalidation \
390+ --distribution-id E2E9BSL5RVN6DI \
391+ --paths " /*" \
392+ --profile websites-bryanchasko
393+ ```
394+
395+ See [ AWS_ARCHITECTURE.md] ( docs/deployment/AWS_ARCHITECTURE.md#6-cloudfront-functions ) for complete CloudFront Functions documentation.
396+
280397### Common Pitfalls
281398
282399❌ ** Browser cache serving old WebGL code**
0 commit comments