Recently, I was on a project that required daily backups of an Amazon Web Services server. The Windows 2012 server stored critical company data that had to be available at all times. My team decided to accomplish the backup task by creating snapshots of the volume that was associated with the server on a daily basis. Since it was a repetitive action, I automated this process with the help of the task scheduler in Windows Server and the following batch script:
set AWS_HOME=C:\Users\Administrator\Desktop set AWS_VOLUME_ID=vol-11111111 :: Create snapshot for the specified volume CMD /C aws ec2 create-snapshot --volume-id %AWS_VOLUME_ID% --description "Daily Snap" :: Find old snapshots for this volume aws ec2 describe-snapshots --filters Name=volume-id,Values="%AWS_VOLUME_ID%" Name=status,Values="completed" | find /I "SnapshotId" > %AWS_HOME%\MyFile.txt :: Loop over old snapshots, skip the first 10, delete the rest for /F "tokens=2 skip=10" %%line in (%AWS_HOME%\MyFile.txt) do call :DeleteSnapshot %%line goto End :DeleteSnapshot set snapId=%1 aws ec2 delete-snapshot --snapshot-id %snapId% goto :eof :End
This batch script creates a snapshot with the specified volume, then saves all the snapshot ids that match criteria specified in the “aws ec2 describe-snapshots” command to a text file and deletes the snapshots that are older than ten days. To start the job, the “aws ec2 create-snapshot” command will create a snapshot for the volume id that is specified along with the desired description. Then, the “aws ec2 describe-instances…” command lists all the snapshots which have the status “completed” and are associated with the specified volume id. The “find /l “SnapshotId” part of the command extracts the line that has the text “SnapshotId” from the output. The last part of the command, “> %AWS_HOME%\MyFile.txt” is used to write the lines which contain the snapshot ids to a text file. Finally, the for-loop is used to iterate through the lines and extract snapshot ids from the text file in order to be used as an argument for the command: “aws ec2 delete-snapshot –snapshot-id %snapId%”. The for-loop is set up to look at the second column in the text file as the second field contains the snapshot id. This is done with the “tokens” value. A business decision was made to only keep the previous ten snapshots. Therefore, my script utilizes the “skip” option to overlook the top ten lines in the text file as those are the latest snapshots ids. The “DeleteSnapshot” method removes the last character which is a ‘,’ that is written to the text file during the execution of the “aws ec2 describe-snapshots” command. The “set snapId=%1” statement sets the snapID variable equal to the value contained in the second column for each of the lines in MyFile.txt file. This statement gets rid of the comma as it only reads in the second field which is the snapshot id. After the ‘,’ is removed, the snapshot id is used as a parameter for the “aws ec2 delete-snapshot…” command in order to delete any snapshot that matches the filter criteria.
This script in combination with the capabilities of the task scheduler in Windows Server proved to be a great solution for the daily backups. In the task scheduler, I was able to schedule a job to run this batch file daily at a specified time. Snapshots make great choices for backups because they are incremental. In other words, only the blocks on the device that have changed since the last snapshot are stored in the new snapshot. For this very reason, snapshots are made very quickly. Even though snapshots are saved incrementally, the snapshot deletion process is designed so that you need to retain only the most recent snapshot in order to restore the volume. Due to this setup, if there is ever an issue with the server, we can restore from the snapshot easily and proceed with daily operations.