Automate Linux EC2 Backups: MySQL Dumps to AWS S3 with CLI & IAM
A Bash script and a least-privilege IAM role that dump your databases and upload them to an S3 bucket on a schedule.
Common Symptoms and Quick Fixes
| Symptom | Likely Cause | Quick Fix |
|---|---|---|
| AccessDenied from S3 | IAM role lacks PutObject | Attach a policy limited to the backup bucket |
| Cron job does nothing | Missing PATH or credentials | Use full paths and an instance role |
| Backup grows forever | No retention | Add an S3 lifecycle rule |
Method 1: Least-Privilege IAM Policy
Attach this to the EC2 instance role. Replace the bucket name with yours.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::my-backups", "arn:aws:s3:::my-backups/*"]
}]
}
Method 2: Backup Script and Cron
Save as /usr/local/bin/db-backup.sh, make it executable with chmod +x, and schedule it with crontab -e.
#!/bin/bash
set -euo pipefail
D=$(date +%F)
mysqldump --single-transaction --all-databases | gzip > /tmp/db-$D.sql.gz
/usr/local/bin/aws s3 cp /tmp/db-$D.sql.gz s3://my-backups/mysql/
rm /tmp/db-$D.sql.gz
# crontab -e
0 2 * * * /usr/local/bin/db-backup.sh >> /var/log/db-backup.log 2>&1
Pro Tip for AdministratorsStore MySQL credentials in ~/.my.cnf with chmod 600 instead of putting a password in the script.
Method 3: Expire Old Backups
In the S3 console open the bucket > Management > Create lifecycle rule and expire objects under mysql/ after 30 to 90 days.
Frequently Asked Questions (FAQ)
Q: Should I keep old backups forever?
No. Use an S3 lifecycle rule to expire or archive objects after 30 to 90 days.
Q: How do I test a restore?
Download one file and run gunzip -c file.sql.gz | mysql on a test server regularly.