This directory contains AWS Lambda functions that power the CodeBook e-commerce backend API.
aws-lambda/
├── functions/ # Individual Lambda functions (one per endpoint)
│ ├── products/ # Product management endpoints
│ ├── auth/ # Authentication endpoints
│ ├── orders/ # Order management endpoints
│ ├── admin/ # Admin-only endpoints
│ ├── payment/ # Payment processing (Stripe)
│ ├── email/ # Email service (Brevo)
│ ├── notifications/ # User notifications
│ ├── reviews/ # Product reviews
│ └── tickets/ # Support tickets
├── shared/ # Shared utilities used by all functions
│ ├── dynamodb.js # DynamoDB client setup
│ ├── response.js # HTTP response helpers
│ ├── auth.js # Authentication helpers
│ ├── products.js # Product helper functions
│ └── ... # Other shared utilities
├── template.yaml # AWS SAM template for deployment
├── deploy.sh # Deployment script
├── .env.secrets # Secrets file (NOT committed to Git)
└── package.json # Dependencies- AWS Account with IAM permissions configured
- AWS SAM CLI installed (
brew install aws-sam-cliorpip install aws-sam-cli) - Node.js 22.x (matches Lambda runtime)
- AWS credentials configured:
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_REGION=eu-north-1
- Install dependencies:
cd aws-lambda
npm install- Test locally with SAM:
sam local start-api- Test endpoint:
curl http://localhost:3000/productsUse the provided deployment script:
cd aws-lambda
./deploy.shThe script will:
- Load environment variables from
../.envor.env - Load secrets from
.env.secrets - Build the SAM application
- Deploy to AWS with all parameters
cd aws-lambda
sam buildThis packages your Lambda functions and dependencies.
sam deploy --guidedFirst-time deployment questions:
- Stack Name:
codebook-lambda(or any name you prefer) - AWS Region:
eu-north-1(must match your DynamoDB region) - Confirm changes:
Y - Allow SAM CLI IAM role creation:
Y(SAM will create roles for Lambda) - Disable rollback:
N(keep default) - Save arguments to configuration:
Y(saves for future deployments)
What SAM does:
- Creates HTTP API in API Gateway
- Creates all Lambda functions
- Sets up IAM roles with DynamoDB permissions
- Configures environment variables
- Returns the API endpoint URL
After deployment, SAM will output:
ApiUrl = https://xxxxxxxxxx.execute-api.eu-north-1.amazonaws.comSave this URL - you'll use it in your frontend as REACT_APP_LAMBDA_API_URL.
# Test products endpoint
curl https://YOUR_API_URL/products
# Test with search
curl "https://YOUR_API_URL/products?name_like=book"NEVER commit secrets (API keys, passwords, tokens) to GitHub!
Even if your repository is private, secrets can be exposed through:
- Accidental public commits
- Repository access changes
- GitHub security breaches
- Code sharing
This project uses AWS SAM Parameters to securely pass secrets during deployment without committing them to Git.
- Copy the example file:
cp .env.secrets.example .env.secrets- Add your actual secrets to
.env.secrets:
JWT_SECRET=your-jwt-secret-here
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
BREVO_API_KEY=xkeysib-...
BREVO_SENDER_EMAIL=your-email@gmail.com
BREVO_ADMIN_EMAIL=your-email@gmail.com
SHIPPO_API_KEY=shippo_test_...- Run deployment script (automatically loads secrets):
./deploy.shcd aws-lambda
sam deploy \
--parameter-overrides \
JwtSecret="your-jwt-secret-here" \
StripeSecretKey="sk_test_..." \
StripeWebhookSecret="whsec_..." \
BrevoApiKey="xkeysib-..." \
BrevoSenderEmail="your-email@gmail.com" \
BrevoAdminEmail="your-email@gmail.com" \
ShippoApiKey="shippo_test_..."Store secrets in AWS Systems Manager Parameter Store (FREE for standard parameters):
# Store secrets in Parameter Store
aws ssm put-parameter \
--name "/codebook/jwt-secret" \
--value "your-jwt-secret" \
--type "SecureString" \
--region eu-north-1
aws ssm put-parameter \
--name "/codebook/stripe-secret-key" \
--value "sk_test_..." \
--type "SecureString" \
--region eu-north-1Then update template.yaml to reference Parameter Store:
Environment:
Variables:
JWT_SECRET: !Sub "{{resolve:ssm:/codebook/jwt-secret}}"
STRIPE_SECRET_KEY: !Sub "{{resolve:ssm:/codebook/stripe-secret-key}}"- Go to AWS Lambda Console
- Select your function
- Go to "Configuration" → "Environment variables"
- Update the values
- Save
aws lambda update-function-configuration \
--function-name codebook-lambda-PaymentCreateIntentFunction-XXXXX \
--environment Variables="{STRIPE_SECRET_KEY=sk_test_...}" \
--region eu-north-1✅ Safe to commit:
template.yaml(uses parameters, no hardcoded secrets)deploy.sh(reads from .env files)samconfig.toml(only contains stack name and region).env.secrets.example(example structure without actual secrets)- Documentation files
❌ Never commit:
.env.secrets(already in .gitignore).env(already in .gitignore)- Any file with actual API keys, passwords, or tokens
- Lambda Environment Variables: FREE ✅
- AWS Systems Manager Parameter Store (Standard): FREE (10,000 parameters) ✅
- AWS Secrets Manager: Costs money (not recommended for this project)
- API Calls: 1 million requests/month FREE
- Data Transfer:
- First 1 GB/month outbound FREE
- After that: $0.09 per GB outbound
- API Calls: $1.00 per million requests
- Data Transfer: $0.09 per GB outbound
The $0.01 charge you might see is likely from:
- Data Transfer: ~111 MB outbound data (0.111 GB × $0.09 ≈ $0.01)
- This is normal for API responses with product data, images, etc.
- Go to AWS Billing Console → Budgets
- Click "Create budget"
- Choose "Cost budget"
- Set budget amount:
- Monthly budget: $5.00 (or your preferred limit)
- Alert threshold: 80% ($4.00) and 100% ($5.00)
- Configure alerts:
- Email: your email address
- Alert when: Actual > 80% of budgeted amount
- Alert when: Actual > 100% of budgeted amount
- Go to AWS Billing Console → Cost Anomaly Detection
- Click "Create monitor"
- Select "All services" or "API Gateway" specifically
- Set sensitivity: Medium or High
- Add email alerts with threshold: $0.10 AND 50% (recommended)
To limit API usage and prevent unexpected charges:
- Go to API Gateway Console → Your API → Usage Plans
- Create a usage plan:
- Throttle: 100 requests/second (adjust as needed)
- Quota: 1 million requests/month (free tier limit)
- Associate with API stages
- Go to CloudWatch → Metrics → API Gateway
- Monitor:
- Count: Number of API calls
- DataTransferOut: Outbound data transfer
- 4XXError: Client errors
- 5XXError: Server errors
- Enable Caching: Cache API responses to reduce Lambda invocations
- Compress Responses: Use gzip compression to reduce data transfer
- Optimize Payload Size: Minimize response data (only return needed fields)
- Use CDN: Serve static assets via CloudFront (cheaper than API Gateway)
- Monitor Regularly: Check AWS Cost Explorer weekly
- API Gateway Calls: $0.00 (within 1M limit)
- API Gateway Data Transfer: $0.00 - $0.50 (depends on usage)
- Lambda: $0.00 (within 1M requests, 400K GB-seconds)
- DynamoDB: $0.00 (within 25 GB storage, 25 RCU/WCU)
- S3: $0.00 (within 5 GB storage)
Total Expected: $0.00 - $1.00/month (within free tier)
- API Gateway: ~$1-5/month (depending on traffic)
- Lambda: ~$0.20/month (if within 1M requests)
- DynamoDB: ~$0.25/month (if within free tier limits)
- S3: $0.00 (if within 5 GB)
Total Expected: $1.50 - $6.00/month (after free tier)
- Budget Alert: $5/month total AWS spend
- API Gateway Alert: > 800K requests/month (80% of free tier)
- Data Transfer Alert: > 800 MB/month (80% of free tier)
- DynamoDB Alert: > 20 GB storage (80% of free tier)
- Cost Anomaly Detection: $0.10 AND 50% threshold
- Free Tier: Only applies for first 12 months after account creation
- Data Transfer: Always charged (even in free tier, after 1 GB/month)
- Regional: Charges vary by region (eu-north-1 is standard pricing)
- Monitor Regularly: Set up alerts to avoid surprises
- Make sure DynamoDB tables exist in eu-north-1 region
- Table names:
codebook-products,codebook-orders,codebook-users,codebook-activity-log,codebook-tickets,codebook-reviews
- Check IAM permissions for your AWS user
- Ensure Lambda execution role has DynamoDB permissions
- Verify API Gateway has proper CORS configuration
- Set
AWS_REGION=eu-north-1in environment or use--region eu-north-1 - Ensure all resources (DynamoDB, Lambda) are in the same region
- Ensure
.env.secretsfile exists inaws-lambda/directory - Check that secrets are properly formatted (no quotes, no spaces around
=) - Verify deployment script is loading secrets correctly
- Check Node.js version matches Lambda runtime (22.x)
- Ensure all dependencies are in
package.json - Try deleting
.aws-sam/folder and rebuilding
The template.yaml file may show linter warnings about !Ref and !Sub. These are false positives - these are valid CloudFormation intrinsic functions used in AWS SAM templates. The template will work correctly despite these warnings.
- Never commit secrets - Always use
.env.secrets(in.gitignore) - Use parameters - All secrets are passed as SAM parameters
- Rotate keys regularly - Update API keys periodically
- Monitor access - Check CloudWatch logs for suspicious activity
- Use IAM roles - Lambda functions use IAM roles, not access keys
- ✅ Project structure created
- ✅ All Lambda functions implemented
- ✅ Shared utilities (DynamoDB, Response helpers, Auth)
- ✅ Secure secrets management
- ✅ Deployment automation
- ✅ Cost monitoring setup