Build and deploy a task manager on AWS using serverless cloud services.
TaskFlow — a task management app deployed on AWS. You'll start with a working app that can add and display tasks, then implement three new features:
- Delete tasks — remove tasks from DynamoDB
- Toggle complete — mark tasks as done with DynamoDB updates
- AI categorization — auto-categorize tasks using AWS Bedrock (Claude AI)
Along the way you'll discover how serverless cloud services work together: DynamoDB, Lambda, API Gateway, S3, and Bedrock.
You have access to AI coding tools (GitHub Copilot) to help you — use them as much or as little as you like.
Finished early? There are bonus features in the requirements too — task suggestions and a chat assistant powered by Bedrock.
Browser → S3 (static frontend)
→ API Gateway → Lambda → DynamoDB (task storage)
→ Bedrock (AI categorization)
- Open the workshop repository in your browser:
https://github.com/acp-io/cloudcraft-workshop - Click the Fork button in the top-right corner
- Select your personal GitHub account as the destination
- Wait for the fork to complete — you'll be redirected to your own copy
git clone https://github.com/<your-username>/cloudcraft-workshop.git
cd cloudcraft-workshopReplace <your-username> with your GitHub username.
Run the setup script to install all required tools (Node.js, Pulumi, GitHub CLI):
bash ./setup.sh
source ~/.bashrcVerify everything installed:
node --version # Should be v20+
pulumi version # Should show a version
gh --version # Should show a version
aws sts get-caller-identity # Should show your AWS accountThere are three separate packages to install — the frontend, the Lambda function, and the infrastructure:
npm install
cd src/lambda && npm install && cd ../..
cd infra && npm install && cd ..This section walks you through your first deployment to AWS using Pulumi.
cd src/lambda
npm run build
cd ../..This compiles the TypeScript Lambda handler into JavaScript that AWS can run.
npm run buildThis creates a static export of the Next.js app in the out/ directory.
cd infra
pulumi login --local
pulumi stack init dev
pulumi config set aws:region eu-central-2What this does:
pulumi login --local— stores infrastructure state on this machine (no account needed)pulumi stack init dev— creates an isolated deployment environment called "dev"pulumi config set aws:region eu-central-2— tells Pulumi to deploy to the Zurich AWS region
pulumi upPulumi will show you a preview of everything it's about to create:
- A DynamoDB table — your database
- A Lambda function — your API code
- An API Gateway — gives your Lambda a public URL
- An S3 bucket — hosts your frontend files
- IAM roles — permissions for Lambda to access DynamoDB and Bedrock
Review the preview and type yes to deploy.
pulumi stack output apiEndpoint
pulumi stack output siteUrlSave these — you'll need them.
The frontend needs to know where your API lives. Rebuild with the API URL from step 5:
cd ..
NEXT_PUBLIC_API_URL=<your-api-endpoint> npm run build
cd infra
pulumi up -yReplace <your-api-endpoint> with the apiEndpoint value from step 5 (e.g., https://abc123.execute-api.eu-central-2.amazonaws.com).
Open the site URL in your browser. Add a todo — it should appear in the list. That's your app running on AWS!
Read REQUIREMENTS.md for the three features you need to implement. Follow this process:
- Research — explore the codebase, understand the architecture
- Plan — map out what files and functions need to change
- Build — implement features one at a time, deploy and test each one
- Verify — confirm everything works end-to-end
After making changes, rebuild and redeploy:
# After Lambda changes:
cd src/lambda && npm run build && cd ../../infra && pulumi up -y
# After frontend changes (from project root):
NEXT_PUBLIC_API_URL=<your-api-endpoint> npm run build
cd infra && pulumi up -y- Look for
TODOcomments in the code — they mark exactly where changes are needed - Check the
solutionbranch to see the completed code:git show solution:src/lambda/handler.ts # See the finished Lambda git show solution:src/hooks/useTodos.ts # See the finished hook
cloudcraft-workshop/
├── src/
│ ├── app/ # Next.js pages (page.tsx, layout.tsx)
│ ├── components/ # React components (TodoApp, TodoItem, etc.)
│ ├── hooks/ # Custom hooks (useTodos)
│ ├── lambda/ # Lambda function (handler.ts)
│ └── types/ # TypeScript types (Todo)
├── infra/ # Pulumi infrastructure code (index.ts)
├── REQUIREMENTS.md # Feature specs for the workshop
└── README.md # You are here
Pulumi is an Infrastructure as Code (IaC) tool. You define cloud resources in TypeScript, and Pulumi creates, updates, and deletes them on AWS for you.
Key concepts:
- Stack — an isolated deployment environment (e.g.,
dev). Each student has their own stack. - State — Pulumi tracks what resources exist so it can update them incrementally.
pulumi up— preview and deploy changes to AWS.pulumi destroy— tear down all resources in the stack.
When you're done with the workshop, destroy your AWS resources:
cd infra
pulumi destroy # Tear down all AWS resources
pulumi stack rm dev # Remove the stack and its statepulumi destroy removes all AWS resources (DynamoDB table, Lambda, API Gateway, S3 bucket). You'll be shown a preview before confirming.
Want to run this workshop outside of the provided cloud environment? See the Self-Hosted Setup Guide for instructions on setting up your own AWS account and local tools.
| Technology | Role |
|---|---|
| Next.js 14 (static export) | Frontend framework |
| TypeScript | Type-safe code |
| Tailwind CSS | Styling (dark theme) |
| Pulumi | Infrastructure as Code |
| AWS DynamoDB | NoSQL database for tasks |
| AWS Lambda | Serverless API |
| AWS API Gateway | HTTP routing |
| AWS S3 | Static website hosting |
| AWS Bedrock | AI model invocation (Claude) |