EC2自動バックアップスクリプト
RDSには自動バックアップ機能がありますが、EC2には無いので、
EC2(正確にはEBS)のバックアップスクリプトをbashで作ってみ
ました。
コードが少々汚い気がしますが・・・
前提
1. backupタグを作成済みであること。
2. /home/xxxx/.bash_profile に、AWSコマンド実行に必要な環境変数が
設定されていること。
http://xoxo-infra.hatenablog.com/entry/2013/02/08/013002
仕様
1. backupタグが、ON になっているインスタンスのみをバックアップ取得対象と
している。
2. スクリプトの第1引数に指定されたインスタンスのEBSバックアップ&AMI作成を
する。
3. 作成したAMI、Snapshotにタグを付与する。
4. スクリプトの第2引数に指定された世代分は残す。
5. 作成されるAMI名は、「インスタンス名_yyyymmdd-HHMMSS」
6. 作成されるスナップショット名は、「インスタンス名_デバイス名_yyyymmdd-HHMMSS」
7. cron実行にて定期的にバックアップを作成することを前提にしている。
一応、手動実行も可能。
スクリプト (make-ami.sh)
・make-ami.sh インスタンス名 保存世代数 で実行する。
(ex.) make-ami.sh web01 3
#!/bin/bash . /home/xxxx/.bash_profile NODENAME=$1 GENE=$2 DATE=`date +%Y%m%d-%H%M%S` SHELL_NAME=`basename ${0}` LOG=/pathto/logs/${SHELL_NAME}_${NODENAME}.log RETRY_MAXCNT=15 RETRY_WAIT_TIME=60 RETVAL=0 ARRAY_CNT=0 #set -x #-------------------------- # Output Messages #-------------------------- Output() { if [ ${RETVAL} -eq 0 ] ; then printf "[`date '+%Y%m%d %H:%M:%S'`] ${PROC} is Sucusess\n" elif [ ${RETVAL} -eq 1 ] ; then printf "[`date '+%Y%m%d %H:%M:%S'`] ${PROC} is Abnormal End\n" exit ${RETVAL} fi } >> ${LOG} #-------------------------- # Main #-------------------------- MakeAMI() { PROC=ArgumentCheck if [ -n "${NODENAME}" ] && [ -n "${GENE}" ] ; then RETVAL=0 else RETVAL=1 fi Output #PROC=ServerHealthCheck #if ping -c 5 ${NODENAME} > /dev/null 2>&1 ; then # RETVAL=0 #else # RETVAL=1 #fi #Output PROC=MakeAMI INSTANCE_ID=`ec2-describe-instances -F "tag:backup=ON" -F "tag:Name=${NODENAME}" | awk '$1 == "INSTANCE" {print $2}'` if ec2-create-image -n ${NODENAME}_${DATE} -d "${DATE}" --no-reboot ${INSTANCE_ID} ; then RETVAL=0 else RETVAL=1 fi Output PROC=CheckAMI AMI_ID=`ec2-describe-images | grep ${NODENAME}_${DATE} | awk '{print $2}'` for RETRY_CNT in `seq 1 1 ${RETRY_MAXCNT}` ; do if ec2-describe-images ${AMI_ID} | grep available ; then RETVAL=0 break else if [ ${RETRY_CNT} -eq ${RETRY_MAXCNT} ] ; then RETVAL=1 else sleep ${RETRY_WAIT_TIME} fi fi done Output PROC=CreateTag-AMI if ec2-create-tags ${AMI_ID} -t Name=${NODENAME}_${DATE} ; then RETVAL=0 else RETVAL=1 fi Output PROC=CreateTag-Snapshot SNAP_ARRAY=(`ec2-describe-images -F "tag:Name=${NODENAME}_${DATE}"| grep ^BLOCKDEVICEMAPPING | awk '{print $3"="$4}'`) ARRAY_MAXCNT=`expr ${#SNAP_ARRAY[@]} - 1` for ARRAY_CNT in `seq 0 1 ${ARRAY_MAXCNT}` ; do #DEVICE=`echo ${SNAP_ARRAY[${ARRAY_CNT}]/\/dev\//} | awk -F"=" '{print $1}'` #SNAP_ID=`echo ${SNAP_ARRAY[${ARRAY_CNT}]/\/dev\//} | awk -F"=" '{print $2}'` eval `echo ${SNAP_ARRAY[${ARRAY_CNT}]/\/dev\//} | awk -F"=" '{print "DEVICE="$1,"SNAP_ID="$2}'` if ec2-create-tags ${SNAP_ID} -t Name=ami_${NODENAME}_${DEVICE}_${DATE} ; then RETVAL=0 else RETVAL=1 fi if ec2-describe-snapshots ${SNAP_ID} | grep "Created by CreateImage" | grep completed ; then RETVAL=0 else RETVAL=1 fi Output done } >> ${LOG} 2>&1 #-------------------------- # Purge AMI&Snapshot #-------------------------- Purge() { PROC=PurgeAMIandSnapshot AMI_IDs=`ec2-describe-images | grep ^IMAGE | grep ${NODENAME} | sort -k3 | awk '{print $2}'` AMI_ID_CNT=`echo ${AMI_IDs} | wc -w` DELCNT=`expr ${AMI_ID_CNT} - ${GENE}` if [ ${DELCNT} -le 0 ] ; then RETVAL=0 else for DELID in ${AMI_IDs} ; do # Snapshot Info DELSNAP_IDs=`ec2-describe-images ${DELID} | grep ^BLOCKDEVICEMAPPING | awk '{print $4}'` # Purge AMI if ec2-deregister ${DELID} ; then # Purge Snapshot for DELSNAP_ID in ${DELSNAP_IDs} ; do if ec2-delete-snapshot ${DELSNAP_ID} ; then RETVAL=0 else RETVAL=1 fi done DELCNT=`expr ${DELCNT} - 1` if [ ${DELCNT} -eq 0 ] ; then RETVAL=0 break fi else RETVAL=1 break fi done fi Output PROC=AMIList AMI_IDs=`ec2-describe-images | grep ^IMAGE | grep ${NODENAME} | sort -k3 | awk '{print $2}'` if ec2-describe-images ${AMI_IDs} ; then RETVAL=0 else RETVAL=1 fi Output } >> ${LOG} 2>&1 #-------------------------- # Call Func #-------------------------- MakeAMI Purge exit 0
50GB程度のインスタンス(EBS)なら、数分で終わりますが、500GBとかだと
6時間くらい掛かりました。。。
大きいサイズのEBSバックアップを取る場合の良いソリューションは無いの
かしら。。
初回は仕方ないか。
https://forums.aws.amazon.com/thread.jspa?threadID=123356&tstart=0