Maintenance

Ongoing maintenance tasks for keeping your Serverless CMS healthy, secure, and cost-effective.

Backup Procedures

DynamoDB Backups

DynamoDB supports point-in-time recovery and on-demand backups.

Enable Point-in-Time Recovery

aws dynamodb update-continuous-backups \
  --table-name serverless-cms-content-store \
  --point-in-time-recovery-specification PointInTimeRecoveryEnabled=true \
  --region eu-west-2 \
  --profile cms-deploy

This enables continuous backups for the last 35 days.

Create On-Demand Backup

aws dynamodb create-backup \
  --table-name serverless-cms-content-store \
  --backup-name cms-backup-$(date +%Y%m%d-%H%M%S) \
  --region eu-west-2 \
  --profile cms-deploy

List Backups

aws dynamodb list-backups \
  --table-name serverless-cms-content-store \
  --region eu-west-2 \
  --profile cms-deploy

Restore from Backup

aws dynamodb restore-table-from-backup \
  --target-table-name serverless-cms-content-store-restored \
  --backup-arn arn:aws:dynamodb:eu-west-2:123456789012:table/serverless-cms-content-store/backup/01234567890123-abcdef12 \
  --region eu-west-2 \
  --profile cms-deploy

S3 Backups

Enable Versioning

# Enable versioning on Component Store
aws s3api put-bucket-versioning \
  --bucket serverless-cms-component-store \
  --versioning-configuration Status=Enabled \
  --profile cms-deploy

# Enable versioning on Publish Store
aws s3api put-bucket-versioning \
  --bucket serverless-cms-publish-store \
  --versioning-configuration Status=Enabled \
  --profile cms-deploy

Cross-Region Replication (Optional)

For disaster recovery, set up cross-region replication:

  1. Create destination bucket in another region
  2. Enable versioning on both buckets
  3. Create replication rule in S3 console
  4. Configure IAM role for replication

Export S3 Data

# Sync bucket to local directory
aws s3 sync s3://serverless-cms-component-store ./backups/components/ \
  --profile cms-deploy

# Create compressed archive
tar -czf cms-backup-$(date +%Y%m%d).tar.gz ./backups/

Automated Backup Script

Create a backup script to run daily:

#!/bin/bash
# backup-cms.sh

DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="./backups/$DATE"

# Create backup directory
mkdir -p "$BACKUP_DIR"

# Backup DynamoDB
aws dynamodb create-backup \
  --table-name serverless-cms-content-store \
  --backup-name "cms-backup-$DATE" \
  --region eu-west-2 \
  --profile cms-deploy

# Sync S3 buckets
aws s3 sync s3://serverless-cms-component-store "$BACKUP_DIR/components/" \
  --profile cms-deploy

aws s3 sync s3://serverless-cms-publish-store "$BACKUP_DIR/publish/" \
  --profile cms-deploy

# Compress backup
tar -czf "cms-backup-$DATE.tar.gz" "$BACKUP_DIR"

# Upload to backup bucket (optional)
aws s3 cp "cms-backup-$DATE.tar.gz" s3://my-backup-bucket/ \
  --profile cms-deploy

echo "Backup completed: cms-backup-$DATE.tar.gz"

Schedule with cron:

# Run daily at 2 AM
0 2 * * * /path/to/backup-cms.sh

Update Procedures

Update Lambda Functions

To deploy code updates:

# Pull latest code
git pull origin main

# Rebuild project
mvn clean package

# Preview changes
mvn serverless:plan

# Deploy updates
mvn serverless:deploy

Update Node.js Dependencies

# Update Admin UI dependencies
cd src/main/admin-ui
npm update
npm audit fix

# Update Lambda function dependencies
cd ../../functions/cms-functions
npm update
npm audit fix

# Rebuild and redeploy
cd ../..
mvn clean package
mvn serverless:deploy

Update Admin UI

To update only the Admin UI without redeploying Lambda functions:

# Build Admin UI
cd src/main/admin-ui
npm run build

# Upload to S3
aws s3 sync dist/ s3://serverless-cms-admin-tool/ \
  --delete \
  --profile cms-deploy

# Invalidate CloudFront cache
aws cloudfront create-invalidation \
  --distribution-id E1234567890ABC \
  --paths "/*" \
  --profile cms-deploy

Database Schema Updates

DynamoDB is schemaless, but if you need to migrate data:

  1. Create backup before migration
  2. Write migration script using AWS SDK
  3. Test on development environment first
  4. Run migration during low-traffic period
  5. Verify data integrity after migration

Monitoring and Logging

CloudWatch Dashboards

Create a custom dashboard for monitoring:

  1. Go to CloudWatch → Dashboards
  2. Create dashboard: "Serverless CMS"
  3. Add widgets for:
    • Lambda invocations
    • Lambda errors
    • Lambda duration
    • API Gateway requests
    • API Gateway 4xx/5xx errors
    • DynamoDB read/write capacity
    • S3 bucket size
    • CloudFront requests

CloudWatch Alarms

Set up alarms for critical metrics:

Lambda Error Rate Alarm

aws cloudwatch put-metric-alarm \
  --alarm-name cms-lambda-errors \
  --alarm-description "Alert when Lambda error rate exceeds 5%" \
  --metric-name Errors \
  --namespace AWS/Lambda \
  --statistic Sum \
  --period 300 \
  --threshold 5 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2 \
  --region eu-west-2 \
  --profile cms-deploy

API Gateway 5xx Errors

aws cloudwatch put-metric-alarm \
  --alarm-name cms-api-5xx-errors \
  --alarm-description "Alert on API Gateway 5xx errors" \
  --metric-name 5XXError \
  --namespace AWS/ApiGateway \
  --statistic Sum \
  --period 300 \
  --threshold 10 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 1 \
  --region eu-west-2 \
  --profile cms-deploy

Log Retention

Configure log retention to control costs:

# Set retention to 30 days
aws logs put-retention-policy \
  --log-group-name /aws/lambda/serverless-cms-cms-functions-sites-create \
  --retention-in-days 30 \
  --region eu-west-2 \
  --profile cms-deploy

Log Insights Queries

Useful CloudWatch Insights queries:

Find Errors

fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 100

Slow Requests

fields @timestamp, @duration
| filter @duration > 1000
| sort @duration desc
| limit 50

Most Invoked Functions

stats count() by @log
| sort count desc

Performance Optimization

Lambda Optimization

Right-Size Memory

  1. Monitor Lambda memory usage in CloudWatch
  2. Adjust memory allocation in pom.xml
  3. Higher memory = faster CPU but higher cost
  4. Find optimal balance through testing

Reduce Cold Starts

  • Keep deployment packages small (< 10 MB)
  • Use Lambda layers for shared dependencies
  • Enable provisioned concurrency for critical functions (costs more)
  • Minimize initialization code outside handler

DynamoDB Optimization

Use Efficient Access Patterns

  • Query instead of Scan when possible
  • Use composite keys for efficient queries
  • Implement pagination for large result sets
  • Use BatchGetItem for multiple items

Monitor Capacity

# Check consumed capacity
aws dynamodb describe-table \
  --table-name serverless-cms-content-store \
  --region eu-west-2 \
  --profile cms-deploy

CloudFront Optimization

Cache Settings

  • Set appropriate TTL for static content (1 year)
  • Use cache invalidation sparingly (costs money)
  • Configure cache behaviors for different content types

Compression

  • Enable Gzip/Brotli compression in CloudFront
  • Reduces bandwidth and improves load times

Security Updates

Dependency Updates

Regularly update dependencies to patch security vulnerabilities:

# Check for vulnerabilities
npm audit

# Fix vulnerabilities automatically
npm audit fix

# For breaking changes, update manually
npm update package-name

IAM Policy Review

Periodically review IAM policies:

  1. Remove unused permissions
  2. Apply principle of least privilege
  3. Rotate access keys every 90 days
  4. Enable MFA for all users

Security Scanning

Use AWS security tools:

  • AWS Security Hub: Centralized security findings
  • AWS Inspector: Automated security assessments
  • AWS GuardDuty: Threat detection
  • AWS Config: Resource configuration compliance

SSL Certificate Renewal

ACM certificates auto-renew, but verify:

aws acm describe-certificate \
  --certificate-arn arn:aws:acm:us-east-1:123456789012:certificate/abc123... \
  --region us-east-1 \
  --profile cms-deploy

Check RenewalEligibility and Status fields.

Cost Optimization

Monitor Costs

Set up AWS Cost Explorer:

  1. Go to AWS Cost Management → Cost Explorer
  2. Enable Cost Explorer (free)
  3. Create cost reports by service
  4. Set up budget alerts

Optimize S3 Costs

Lifecycle Policies

# Move old backups to Glacier after 90 days
aws s3api put-bucket-lifecycle-configuration \
  --bucket my-backup-bucket \
  --lifecycle-configuration file://lifecycle.json \
  --profile cms-deploy

lifecycle.json:

{
  "Rules": [
    {
      "Id": "ArchiveOldBackups",
      "Status": "Enabled",
      "Transitions": [
        {
          "Days": 90,
          "StorageClass": "GLACIER"
        }
      ],
      "Expiration": {
        "Days": 365
      }
    }
  ]
}

Delete Unused Objects

# List old versions
aws s3api list-object-versions \
  --bucket serverless-cms-component-store \
  --profile cms-deploy

# Delete old versions (be careful!)
aws s3api delete-object \
  --bucket serverless-cms-component-store \
  --key path/to/object \
  --version-id version-id \
  --profile cms-deploy

Optimize Lambda Costs

  • Right-size memory allocation
  • Reduce execution time through optimization
  • Use Lambda layers to reduce package size
  • Consider reserved concurrency for predictable workloads

Optimize DynamoDB Costs

  • Use on-demand billing for unpredictable workloads
  • Use provisioned capacity for steady workloads (cheaper)
  • Enable auto-scaling for provisioned capacity
  • Archive old data to S3

CloudFront Cost Optimization

  • Use price class to limit edge locations (e.g., US/Europe only)
  • Optimize cache hit ratio to reduce origin requests
  • Compress content to reduce data transfer

Maintenance Checklist

Daily

  • Check CloudWatch dashboard for anomalies
  • Review error logs
  • Monitor costs in billing dashboard

Weekly

  • Review CloudWatch alarms
  • Check backup completion
  • Review security findings
  • Update npm dependencies

Monthly

  • Review and optimize costs
  • Update Lambda functions with latest code
  • Review IAM policies and permissions
  • Test disaster recovery procedures
  • Review CloudWatch metrics and adjust alarms

Quarterly

  • Rotate IAM access keys
  • Review and update security policies
  • Perform security audit
  • Review and optimize architecture
  • Update documentation
Maintenance Complete! Regular maintenance ensures your Serverless CMS remains secure, performant, and cost-effective.