Last active
December 1, 2017 22:02
-
-
Save eekfonky/8dd1c1123603f70ce623fbcc85450ae9 to your computer and use it in GitHub Desktop.
Create EC2 Snapshot in source region, copy to another region copy and remove after X days
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# error handling | |
error_handler() { | |
echo "Error occurred in script at line: ${1}" | |
echo "Line exited with status: ${2}" | |
} | |
trap 'error_handler ${LINENO} $?' ERR | |
set -o errexit | |
set -o errtrace | |
set -o nounset | |
## Variable Declartions ## | |
# get Instance Details | |
INSTANCE_ID=$(curl http://169.254.169.254/latest/meta-data/instance-id) | |
# get source region | |
SOURCE_REGION=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e 's/\([1-9]\).$/\1/g') | |
# get destination region | |
DESTINATION_REGION="eu-west-1" | |
# grab ALL volume IDs attached to this instance | |
# VOLUME_LIST=$(aws ec2 describe-volumes --region "$SOURCE_REGION" --filters Name=attachment.instance-id,Values="$INSTANCE_ID" --query Volumes[].VolumeId --output text) | |
# grab volumes with termination set to TRUE | |
# VOLUME_LIST=$(aws ec2 describe-volumes --region "$SOURCE_REGION" --filters Name=attachment.instance-id,Values="$INSTANCE_ID" Name=attachment.delete-on-termination,Values=true --query Volumes[].VolumeId --output text) | |
# grab volumes with termination set to FALSE | |
VOLUME_LIST=$(aws ec2 describe-volumes --region "$SOURCE_REGION" --filters Name=attachment.instance-id,Values="$INSTANCE_ID" Name=attachment.delete-on-termination,Values=false --query Volumes[].VolumeId --output text) | |
# DEST_VOLUME_LIST=$(aws ec2 describe-volumes --region "$DESTINATION_REGION" --filters Name=attachment.instance-id,Values="$INSTANCE_ID" Name=attachment.delete-on-termination,Values=false --query Volumes[].VolumeId --output text) | |
# set variables | |
TIMESTAMP=$(date +%F-%a) # year-month-date-day format | |
ORIG_SNAPSHOT="$TIMESTAMP-$VOLUME_LIST.json" | |
# 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) | |
# tags for snapshots | |
TAG_NAME="CreatedBy" | |
TAG_VALUE="AutomatedJenkinsBackup" | |
## Function Declarations ## | |
package_to_install () { | |
# enter the package you want installed in PKG_NAME below | |
PKG_NAME="jq" | |
if ! type $PKG_NAME > /dev/null 2>&1; then | |
# check Linux package manager (yum or apt) | |
declare -A osInfo; | |
osInfo[/etc/redhat-release]=yum | |
osInfo[/etc/arch-release]=pacman | |
osInfo[/etc/gentoo-release]=emerge | |
osInfo[/etc/SuSE-release]=zypp | |
osInfo[/etc/debian_version]=apt | |
osInfo[/etc/lsb-release]=apt | |
for f in "${!osInfo[@]}" | |
do | |
if [[ -f $f ]];then | |
sudo ${osInfo[$f]} install "$PKG_NAME" | |
fi | |
done | |
fi | |
} | |
# Function: create snapshot of attached EBS and get SnapShotId | |
create_source_snapshot () { | |
aws ec2 create-snapshot --region "$SOURCE_REGION" --volume-id "$VOLUME_LIST" --description "$TIMESTAMP Jenkins Docker home temporary snapshot" > "$ORIG_SNAPSHOT" | |
ORIG_ID=$(jq -r '.SnapshotId' "$ORIG_SNAPSHOT") | |
COPY_SNAPSHOT="$TIMESTAMP-$ORIG_ID.json" | |
# check snapshot status | |
ORIG_PROGRESS=$(aws --region "$SOURCE_REGION" ec2 describe-snapshots --snapshot-id "$ORIG_ID" | jq -r '.Snapshots[].Progress') | |
while [[ "$ORIG_PROGRESS" != "100%" ]]; do | |
sleep 20 | |
ORIG_PROGRESS=$(aws --region "$SOURCE_REGION" ec2 describe-snapshots --snapshot-id "$ORIG_ID" | jq -r '.Snapshots[].Progress') | |
done | |
} | |
# Function: copy snapshot to another region for fault tolerance | |
copy_source_snapshot () { | |
aws --region "$DESTINATION_REGION" ec2 copy-snapshot --source-region "$SOURCE_REGION" --source-snapshot-id "$ORIG_ID" --description "$TIMESTAMP Jenkins Docker home directories" > "$COPY_SNAPSHOT" | |
COPY_ID=$(jq -r '.SnapshotId' "$COPY_SNAPSHOT") | |
# check snapshot copy status | |
COPY_PROGRESS=$(aws --region "$DESTINATION_REGION" ec2 describe-snapshots --snapshot-id "$COPY_ID" | jq -r '.Snapshots[].Progress') | |
while [[ "$COPY_PROGRESS" != "100%" ]]; do | |
sleep 60 | |
COPY_PROGRESS=$(aws --region "$DESTINATION_REGION" ec2 describe-snapshots --snapshot-id "$COPY_ID" | jq -r '.Snapshots[].Progress') | |
done | |
# add tags to the resulting snapshot | |
aws ec2 create-tags --region "$DESTINATION_REGION" --resource "$COPY_ID" --tags Key=$TAG_NAME,Value=$TAG_VALUE | |
} | |
# Function: cleanup and delete snapshots older than $RETENTION_DAYS | |
cleanup () { | |
# remove source snapshot & json files | |
aws ec2 delete-snapshot --region "$SOURCE_REGION" --snapshot-id "$ORIG_ID" | |
rm -rf "$ORIG_SNAPSHOT" "$COPY_SNAPSHOT" | |
# remove snapshots in $DESTINATION_REGION older than $RETENTION_DAYS | |
SNAPSHOT_LIST=$(aws ec2 describe-snapshots --region "$DESTINATION_REGION" --filters Name=tag-key,Values="$TAG_NAME" Name=tag-value,Values="$TAG_VALUE" --query 'Snapshots[*].{ID:SnapshotId}' --output=text) | |
for SNAPSHOT in ${SNAPSHOT_LIST[@]}; do | |
# Check age of snapshot | |
SNAPSHOT_DATE=$(aws ec2 describe-snapshots --region "$DESTINATION_REGION" --snapshot-ids "$SNAPSHOT" --query 'Snapshots[].StartTime' --output=text | awk -F "T" '{printf "%s\n", $1}') | |
SNAPSHOT_DATE_IN_SECONDS=$(date "--date=$SNAPSHOT_DATE" +%s) | |
if (( $SNAPSHOT_DATE_IN_SECONDS <= $RETENTION_DATE_IN_SECONDS )); then | |
aws ec2 delete-snapshot --region "$DESTINATION_REGION" --snapshot-id "$SNAPSHOT" | |
fi | |
done | |
} | |
## SCRIPT COMMANDS ## | |
package_to_install | |
create_source_snapshot | |
copy_source_snapshot | |
cleanup |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment