diff --git a/README.md b/README.md index 2c4d395a6..c43f550b6 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ Example | Description | [Static Website](aws-ts-static-website) | Serve a static website using S3, CloudFront, Route53, and Certificate Manager. [Step Functions](aws-ts-stepfunctions) | Use Step Functions with a Lambda function. [Thumbnailer](aws-ts-thumbnailer) | Create a video thumbnail extractor using serverless functions and containers. +[Toolbox](aws-ts-toolbox) | A demo app that shows how to easily deploy web apps to AWS using Lambda, S3, and CloudFront, powered by components from Pulumi-AWS-Toolbox. [Twitter](aws-ts-twitter-athena) | Query Twitter every 2 minutes, store the results in S3, and set up an Athena table and query. [URL Shortener](aws-ts-url-shortener-cache-http) | Create a serverless URL shortener that uses high-level components. [Voting App](aws-ts-voting-app) | Create a simple voting app using Redis and Python Flask. diff --git a/aws-ts-toolbox/README.md b/aws-ts-toolbox/README.md new file mode 100644 index 000000000..338a906c8 --- /dev/null +++ b/aws-ts-toolbox/README.md @@ -0,0 +1,83 @@ +# Notebook Example App Built with Pulumi AWS Toolbox + +Notebook is an open-source, serverless pastebin alternative that demonstrates how to deploy a modern web app to AWS using Pulumi and the pulumi-aws-toolbox library—all with about 100 lines of infrastructure code. + +## Overview + +Notebook leverages a fully serverless architecture to keep AWS costs nearly $0. It integrates several AWS services and modern web frameworks to provide a scalable, low-maintenance application: + +- **Frontend:** Built with SvelteKit and styled with Tailwind CSS. +- **Backend:** With AWS Lambda for handling user data. +- **Static Assets:** Hosted on Amazon S3. +- **Content Delivery:** Using Amazon CloudFront. + +A live demo is available at [https://notebook.datalisk.com](https://notebook.datalisk.com). + + +## How it works + +### Backend +A serverless backend is defined using the SimpleNodeLambda component. + +```typescript +const backendLambda = new pat.lambda.SimpleNodeLambda(`${resourcePrefix}-backend`, { + codeDir: `${__dirname}/../backend`, + roleInlinePolicies: [{ + name: "S3", + policy: { + Version: "2012-10-17", + Statement: [{ + Effect: "Allow", + Action: ["s3:PutObject"], + Resource: [pulumi.interpolate`${contentBucket.arn}/content/*`], + }], + }, + }], + environmentVariables: { + CONTENT_BUCKET: contentBucket.bucket, + }, +}); +``` + +### Static Website + +The CloudFront distribution serves as the entry point for the website. The StaticWebsite component creates a necessary resources for API routes, content delivery, path rewrites, and static frontend assets: + +```typescript +const website = new pat.website.StaticWebsite(`${resourcePrefix}-website`, { + acmCertificateArn_usEast1: config.require("acmCertificateArn_usEast1"), + hostedZoneId: config.require("hostedZoneId"), + subDomain: resourcePrefix, + routes: [{ + // API calls routed to the backend Lambda function + type: RouteType.Lambda, + pathPattern: '/api/*', + functionUrl: backendFunctionUrl, + }, { + // Direct download for notebook files stored in S3 + type: RouteType.S3, + pathPattern: '/content/*', + s3Folder: { bucket: contentBucket, path: '' }, + originCachePolicyId: aws.cloudfront.getCachePolicyOutput({ name: "Managed-CachingDisabled" }) + .apply(policy => policy.id!!), + }, { + // Rewrite requests to serve the Notebook UI (e.g., /n/abc123 → /n/0.html) + type: RouteType.S3, + pathPattern: "/n/*", + s3Folder: frontendArtifact, + viewerRequestFunctionArn: new pat.website.ViewerRequestFunction(`${resourcePrefix}-notebook-rewrite`) + .rewritePathElement(1, "0.html") + .create().arn + }, { + // Serve static frontend assets + type: RouteType.S3, + pathPattern: "/", + s3Folder: frontendArtifact, + }], +}); +``` + + +## Deployment + +See the full code and documentation at [https://github.com/datalisk/pulumi-aws-toolbox/tree/main/examples/notebook-app](https://github.com/datalisk/pulumi-aws-toolbox/tree/main/examples/notebook-app).