Deploy with AWS CDK
In this tutorial, you’ll deploy the complete Serverless Inbox system to AWS using Infrastructure-as-Code with CDK.
Time required: ~30 minutes
Difficulty: Medium
Prerequisites: AWS account, Node.js 18+, AWS CLI v2
Last tested: March 2026
What You’ll Do
Section titled “What You’ll Do”By the end of this tutorial:
- ✅ Clone the CDK repository
- ✅ Configure your AWS credentials
- ✅ Deploy all infrastructure with one command
- ✅ Verify the deployment succeeded
- ✅ Access your admin dashboard
Prerequisites Checklist
Section titled “Prerequisites Checklist”Before starting, verify you have:
- AWS Account with admin permissions (or IAM user with broad permissions)
- Node.js 18+ installed
Terminal window node --version # Should output v18.0.0 or higher - AWS CLI v2 installed and configured
Terminal window aws --version # Should output aws-cli/2.x.x or higheraws sts get-caller-identity # Should show your AWS account - Git installed
Terminal window git --version # Should output git version 2.x.x or higher - AWS credentials configured with default region
Terminal window cat ~/.aws/config # Should show default region and profile - ~1 hour of time for deployment and initial setup
Step 1: Clone the CDK Repository
Section titled “Step 1: Clone the CDK Repository”First, get the source code:
git clone https://github.com/serverless-inbox/cdk.gitcd cdkExpected output:
Cloning into 'cdk'...remote: Enumerating objects: 1234, done.remote: Counting objects: 100% (1234/1234), done....cd cdk # Now inside the repositoryVerify you’re in the correct directory:
ls -laExpected output:
drwxr-xr-x lib/drwxr-xr-x src/-rw-r--r-- package.json-rw-r--r-- tsconfig.json-rw-r--r-- cdk.json-rw-r--r-- README.mdStep 2: Install Node Dependencies
Section titled “Step 2: Install Node Dependencies”Install CDK and project dependencies:
npm installExpected output:
added 450 packages in 45sThis may take a few minutes depending on internet speed.
Step 3: Configure Deployment Settings
Section titled “Step 3: Configure Deployment Settings”The CDK configuration is in cdk.json. Open and review the defaults:
cat cdk.jsonDefault configuration:
{ "app": "npx ts-node src/main.ts", "context": { "region": "us-east-1", "environment": "dev", "enableXRayTracing": false, "emailDomain": "your-domain.com" }}Optional: Customize Your Deployment
Section titled “Optional: Customize Your Deployment”If you want to change settings, edit cdk.json:
# Edit with your preferred editornano cdk.jsonCommon customizations:
region- Change to your preferred AWS region (default: us-east-1)environment- Set to “dev”, “staging”, or “prod” (affects naming, logging)emailDomain- Your domain (used for SES configuration, change later if needed)
Tip: For first deployment, stick with defaults. You can customize later.
Step 4: Bootstrap CDK (First-Time Only)
Section titled “Step 4: Bootstrap CDK (First-Time Only)”If this is your first CDK deployment in this AWS account, bootstrap it:
npm run cdk bootstrapExpected output:
✓ Environment aws://ACCOUNT_ID/us-east-1 bootstrapped.Note: You only need to do this once per AWS account per region. Future deployments skip this step.
Step 5: Review the Infrastructure Deployment Plan
Section titled “Step 5: Review the Infrastructure Deployment Plan”Before deploying, see what will be created:
npm run cdk diffExpected output:
Stack MailboxStack[+] Resource AWS::Lambda::Function EmailIngestFunction[+] Resource AWS::DynamoDB::Table EmailTable[+] Resource AWS::SQS::Queue IndexingQueue[+] Resource AWS::S3::Bucket SearchIndexBucket... (many more resources)
Summary: 45 resources to createReview this output to ensure everything looks correct. See System Architecture if you’re unsure what these resources are for.
Step 6: Deploy!
Section titled “Step 6: Deploy!”Now deploy the infrastructure:
npm run cdk deployWhat happens:
- Compiles your CDK code
- Uploads deployment package to S3
- Creates CloudFormation stack
- Deploys all resources
- Waits for completion (5-10 minutes)
Expected output:
MailboxStack: creating CloudFormation changeset...[████████░░] (15/45) MailboxStack: created
Do you wish to deploy these changes (y/n)? y
MailboxStack: deploying... [████████████████████] (45/45)✓ MailboxStack
Outputs:MailboxStack.AdminDashboardUrl = https://d123abc.cloudfront.net/adminMailboxStack.JmapApiUrl = https://api-xyz.execute-api.us-east-1.amazonaws.comMailboxStack.WebmailUrl = https://d456def.cloudfront.net/webmail
Stack ARN:arn:aws:cloudformation:us-east-1:ACCOUNT_ID:stack/MailboxStack/UUIDKeep these URLs handy! You’ll need them in the next steps.
Step 7: Verify the Deployment
Section titled “Step 7: Verify the Deployment”Confirm everything deployed successfully:
npm run cdk outputExpected output:
{ "AdminDashboardUrl": "https://d123abc.cloudfront.net/admin", "JmapApiUrl": "https://api-xyz.execute-api.us-east-1.amazonaws.com", "WebmailUrl": "https://d456def.cloudfront.net/webmail"}Health Check
Section titled “Health Check”Test that the API is responding:
curl https://api-xyz.execute-api.us-east-1.amazonaws.com/.well-known/jmapExpected output:
{ "capabilities": { "urn:ietf:params:jmap:core": {} }, "apiUrl": "https://api-xyz.execute-api.us-east-1.amazonaws.com/jmap", "eventSourceUrl": "https://api-xyz.execute-api.us-east-1.amazonaws.com/events"}If you get a response, your API is working.
Step 8: Access the Admin Dashboard
Section titled “Step 8: Access the Admin Dashboard”Open the Admin Dashboard URL in your browser:
https://d123abc.cloudfront.net/adminYou should see:
- Login page (Serverless Inbox branding)
- Ability to log in with initial admin credentials (see notes below)
Note: Initial admin credentials are output during deployment. Check the CloudFormation stack outputs in AWS Console for credentials.
Troubleshooting: Common Issues
Section titled “Troubleshooting: Common Issues”Issue: “npm: command not found”
Section titled “Issue: “npm: command not found””Solution: Node.js not installed or not in PATH
node --version # Should return v18.0.0+# If not, download from nodejs.orgIssue: “AWS credentials not found”
Section titled “Issue: “AWS credentials not found””Solution: Configure AWS CLI
aws configure # Enter access key, secret, region, output format# Then try againIssue: “This application requires a newer version of AWS CDK”
Section titled “Issue: “This application requires a newer version of AWS CDK””Solution: Update CDK
npm install -g aws-cdknpm install # Reinstall dependenciesIssue: “Insufficient IAM permissions”
Section titled “Issue: “Insufficient IAM permissions””Solution: Your AWS user needs permissions for Lambda, DynamoDB, SQS, S3, etc.
# Contact your AWS administrator to grant permissions# Or use AWS account root credentials for first deploymentIssue: “Stack already exists”
Section titled “Issue: “Stack already exists””Solution: Previous deployment with same name exists
# Option 1: Deploy with different environment name# Edit cdk.json, change "environment": "dev" to "dev2", redeploy
# Option 2: Delete previous stack and redeployaws cloudformation delete-stack --stack-name MailboxStack-devIssue: “Timeout - deployment still not complete after 20 minutes”
Section titled “Issue: “Timeout - deployment still not complete after 20 minutes””Solution: Check CloudFormation events in AWS Console
aws cloudformation describe-stack-events \ --stack-name MailboxStackLook for failed resources and errors.
What Was Deployed?
Section titled “What Was Deployed?”Your deployment created:
| Component | AWS Service | Purpose |
|---|---|---|
| Email Ingest | Lambda | Receives emails from SES |
| JMAP API | Lambda + API Gateway | Email protocol API |
| Admin API | Lambda + API Gateway | User management |
| WebSocket | API Gateway + Lambda | Real-time notifications |
| Email Storage | DynamoDB | Email database |
| Search Index | EBS Volume | Tantivy full-text search |
| Admin Dashboard | CloudFront + S3 | Admin web interface |
| Webmail | CloudFront + S3 | End-user web interface |
See System Architecture for detailed explanation of each component.
Next Steps
Section titled “Next Steps”Now that Serverless Inbox is deployed:
-
- Verify deployment and configure your account
- Create admin user
- Takes ~10 minutes
-
- Verify your domain with AWS SES
- Enable sending/receiving emails
- Takes ~15 minutes
-
- Invite colleagues
- Grant permissions
- Takes ~10 minutes
-
- Send/receive test emails
- Explore features
- Takes ~5 minutes
Cleanup (When You’re Done With This Test)
Section titled “Cleanup (When You’re Done With This Test)”To delete the deployment and stop incurring costs:
npm run cdk destroyYou’ll be asked:
Are you sure you want to delete: MailboxStack (y/n)? yThis removes all AWS resources created. Costs will stop.
Warning: This deletes all data in DynamoDB. Only do this for test deployments.
Need Help?
Section titled “Need Help?”- Deployment failed? Check Troubleshooting Deployments
- Costs higher than expected? See Cost Optimization
- Can’t access admin dashboard? Check Admin Dashboard Troubleshooting
- Still stuck? Open an issue: GitHub Issues
Congratulations! You’ve successfully deployed Serverless Inbox.
Next: Complete Initial Setup
Last updated: March 2026