MongoDB Backup Failure Email Alerts with Amazon SES
Catch silent MongoDB backup failures before they cost you data. Wire Amazon SES into your Ubuntu cron script for instant emails when dumps or S3 uploads fail.
In the previous post I set up the automated MongoDB → S3 backup I've been running on production Ubuntu boxes. But backups without monitoring are dangerous: if a backup quietly fails and nobody notices, the whole data-protection strategy fails silently with it. I learned this the hard way when a rotated IAM key broke S3 uploads for three days before I noticed — the cron ran, the log said "Starting backup", and no email ever arrived because there was no email path yet.
This guide bolts Amazon Simple Email Service (SES) onto that backup script so you get an instant email whenever a backup breaks.
Architecture
MongoDB
↓
mongodump
↓
Upload to S3
↓
If failure occurs → Send email alert via Amazon SESStep 1: Set up Amazon SES
- Log in to the AWS Console
- Open Amazon Simple Email Service (SES)
- Go to Verified identities
- Click Create identity
- Choose Email Address
- Enter the sender email (e.g.
alerts@yourdomain.com) - Click Create
- Verify the email from your inbox
Important: If SES is in Sandbox mode you must also verify the recipient email. For production, request Production Access inside SES.
Step 2: Add SES permission to the IAM user
Go to IAM → Users → select your backup IAM user → Attach policy and attach:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ses:SendEmail", "ses:SendRawEmail"],
"Resource": "*"
}
]
}This lets the server send emails through SES.
Step 3: Test SES from the Ubuntu server
aws ses send-email \
--from alerts@yourdomain.com \
--destination ToAddresses=your@email.com \
--message "Subject={Data=SES Test Email},Body={Text={Data=Amazon SES is working successfully}}" \
--region ap-south-1If configured correctly, you should receive the test email. If you see an error, check:
- Verified email identities
- IAM permissions
- The correct AWS region
Step 4: Update the MongoDB backup script
Edit the script from the previous post:
nano ~/mongo-backup.shReplace its contents with:
#!/bin/bash
# Same `snap run aws-cli.aws` approach as the previous post — see there for the cron/PATH rationale.
MONGO_URI="mongodb://localhost:27017/mydatabase"
BACKUP_DIR="$HOME/bkp"
DATE=$(date +"%Y-%m-%d_%H-%M-%S")
S3_BUCKET="s3://your-bucket-name"
BACKUP_NAME="backup-$DATE.gz"
RETENTION_DAYS=7
SES_FROM="alerts@yourdomain.com"
SES_TO="your@email.com"
AWS_REGION="ap-south-1"
LOG_FILE="$HOME/mongo-backup.log"
send_failure_email() {
snap run aws-cli.aws ses send-email \
--from "$SES_FROM" \
--destination ToAddresses="$SES_TO" \
--message "Subject={Data=Mongo Backup FAILED},Body={Text={Data=Backup failed on $(hostname) at $DATE. Check logs at $LOG_FILE}}" \
--region "$AWS_REGION"
}
mkdir -p "$BACKUP_DIR"
echo "Starting backup: $DATE" >> "$LOG_FILE"
# Run mongodump
mongodump --uri="$MONGO_URI" \
--archive="$BACKUP_DIR/$BACKUP_NAME" --gzip >> "$LOG_FILE" 2>&1
if [ $? -ne 0 ]; then
echo "Mongo dump failed" >> "$LOG_FILE"
send_failure_email
exit 1
fi
# Upload to S3
snap run aws-cli.aws s3 cp "$BACKUP_DIR/$BACKUP_NAME" "$S3_BUCKET/" >> "$LOG_FILE" 2>&1
if [ $? -ne 0 ]; then
echo "S3 upload failed" >> "$LOG_FILE"
send_failure_email
exit 1
fi
# Cleanup old local backups
find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -delete
echo "Backup completed successfully: $BACKUP_NAME" >> "$LOG_FILE"Step 5: Make the script executable
chmod +x ~/mongo-backup.shHow it works
- If
mongodumpfails → email is sent - If S3 upload fails → email is sent
- If everything succeeds → no email is sent
You only hear from the script when something is wrong, which is exactly what you want from monitoring.
Production best practices
- Use an IAM role instead of access keys if running on EC2
- Restrict SES permissions to specific verified identities
- Add an S3 lifecycle rule for automatic cleanup
- Periodically test the restore process — a backup you've never restored is not a backup
- Review backup logs weekly
FAQ
Why SES and not SNS or a Slack webhook?
SES is the cheapest option (~$0.10 per 1,000 emails) and doesn't need a topic subscription like SNS. For a solo dev inbox that fires a few times a year, this is fine. If your team already lives in Slack, swap the send_failure_email function for a curl to an incoming webhook — same pattern, different transport.
Why doesn't the script use set -e?
Because I want to catch the failure, log it, and email — not exit silently. set -e would short-circuit before send_failure_email runs. Explicit $? checks after each command give me that control.
What if SES itself is down when I try to send the alert?
Rare, but possible. The email attempt writes to the log either way, so a grep -i fail ~/mongo-backup.log on your weekly review catches anything the email path missed. For paranoia, tail the log into a second channel (Papertrail, Loki, CloudWatch Logs).
How do I stop getting spammed if the backup fails every night?
Add a "sent today" flag: touch ~/.mongo-backup-alert-sent inside send_failure_email and short-circuit the function if the flag file is less than 24 h old. Delete the flag on the next successful run.
Can I use Gmail SMTP instead of SES? You can, but Gmail throttles hard on scripted senders and revokes app passwords aggressively. SES with a verified domain is more reliable for unattended alerting.
Final result
You now have:
- Automated MongoDB backup
- Cloud storage in S3
- Automatic failure detection
- Email alert system
- Production-ready monitoring
What's next
Backups and alerts get you two-thirds of the way. The part everyone skips: actually restoring. In the next post I restore one of these archives from S3 into a scratch database, verify it, and set up a quarterly restore drill — because a backup you've never restored is not a backup.