EC2インスタンスのバックアップを日次で取得したいと思います。
今ならLambdaなどを使うことが多いと思いますが、今回は稼働しているインスタンス自身でスナップショットを取得する方法についてです。
aws cliのインストール
APIを利用する為、対象サーバにAWS CLIをインストールします。
参考:CentOSにAWS CLIをインストールする
IAM Roleの作成
IAMには、最低限の下記のRoleを設定します。
対象サーバ自身からのみスナップショットを取得できるようにElasticIPで制限をかけています。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1427276485000", "Effect": "Allow", "Action": [ "ec2:CreateSnapshot", "ec2:DeleteSnapshot", "ec2:DescribeSnapshots", "ec2:DescribeInstances", "ec2:CreateTags" ], "Condition": { "IpAddress": { "aws:SourceIp": [ "<instance_elastic_ip>/32" ] } }, "Resource": [ "*" ] } ] }
IAM Roleが使えない場合
IAM Roleを設定していないインスタンス等、IAM Roleを追加できない場合は、同様のポリシーを持ったIAM Userを作成して、AWS CLIの設定にキー情報を設定します。
スナップショット取得スクリプトの設置
下記にて紹介されているAMIMOTOで利用されているスクリプトを流用させて頂こうと思います。
このスクリプトは、世代管理ができるので便利です。
Snapshot を自動で作成するには?
しかし、このスクリプトはスナップショットのName
タグが設定されません。
個人的に、Name
タグにインスタンス名_日付
のような形で設定したいので、スクリプトを少し修正します。
具体的にはcreate_snapshot()
の処理に下記を追加します。
SNAPSHOT_ID=`grep SnapshotId ${LOG_FILE} |cut -d"\"" -f4` SNAPSHOT_DATE=`date +%Y%m%d` HOSTNAME=`hostname` aws ec2 create-tags --resources ${SNAPSHOT_ID} --tags Key=Name,Value=${HOSTNAME}_${SNAPSHOT_DATE}
スクリプトの修正
差分は以下の通りです。
--- create-snapshot.sh_20160229134807 2016-02-29 12:37:48.334968041 +0900 +++ create-snapshot.sh 2016-02-29 14:46:02.926520887 +0900 @@ -54,6 +55,13 @@ logger -f ${LOG_FILE} exit 1 fi + ### Custom Add + SNAPSHOT_ID=`grep SnapshotId ${LOG_FILE} |cut -d"\"" -f4` + SNAPSHOT_DATE=`date +%Y%m%d` + HOSTNAME=`hostname` + aws ec2 create-tags --resources ${SNAPSHOT_ID} --tags Key=Name,Value=${HOSTNAME}_${SNAPSHOT_DATE} + print_msg "Create snapshot End" }
実際のスクリプトは以下の通りです。
#!/bin/sh SHELLDIR=`dirname ${0}` SHELLDIR=`cd ${SHELLDIR}; pwd` SHELLNAME=`basename $0` LOG_DIR="/var/log" LOG_SAVE_PERIOD=5 LOG_FILE="${LOG_DIR}/${SHELLNAME}.log" AZ=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone` LN=`echo $((${#AZ} - 1))` REGION=`echo ${AZ} | cut -c 1-${LN}` SNAPSHOTS_PERIOD=3 AWS="/usr/bin/aws --region ${REGION}" INSTANCE_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id` rotate_log() { (( cnt=${LOG_SAVE_PERIOD} )) while (( cnt > 0 )) do logfile1=${LOG_FILE}.$cnt (( cnt=cnt-1 )) logfile2=${LOG_FILE}.$cnt if [ -f $logfile2 ]; then mv $logfile2 $logfile1 fi done if [ -f $LOG_FILE ]; then mv ${LOG_FILE} ${LOG_FILE}.1 fi touch $LOG_FILE } print_msg() { echo "`date '+%Y/%m/%d %H:%M:%S'` $1" | tee -a ${LOG_FILE} } create_snapshot() { print_msg "Create snapshot Start" VOL_ID=`${AWS} ec2 describe-instances --instance-ids ${INSTANCE_ID} --output text | grep EBS | awk '{print $5}'` if [ -z ${VOL_ID} ] ; then echo ${VOL_ID} print_msg "ERR:ec2-describe-instances" logger -f ${LOG_FILE} exit 1 fi print_msg "ec2-describe-instances Success : ${VOL_ID}" ${AWS} ec2 create-snapshot --volume-id ${VOL_ID} --description "Created by SYSTEMBK(${INSTANCE_ID}) from ${VOL_ID}" >> ${LOG_FILE} 2>&1 if [ $? != 0 ] ; then print_msg "ERR:${SHELLDIR}/${SHELLNAME} ec2-create-snapshot" logger -f ${LOG_FILE} exit 1 fi ### Custom Add SNAPSHOT_ID=`grep SnapshotId ${LOG_FILE} |cut -d"\"" -f4` SNAPSHOT_DATE=`date +%Y%m%d` HOSTNAME=`hostname` aws ec2 create-tags --resources ${SNAPSHOT_ID} --tags Key=Name,Value=${HOSTNAME}_${SNAPSHOT_DATE} print_msg "Create snapshot End" } delete_old_snapshot() { print_msg "Delete old snapshot Start" SNAPSHOTS=`${AWS} ec2 describe-snapshots --output text | grep ${VOL_ID} | grep "Created by SYSTEMBK" | wc -l` while [ ${SNAPSHOTS} -gt ${SNAPSHOTS_PERIOD} ] do ${AWS} ec2 delete-snapshot --snapshot-id `${AWS} ec2 describe-snapshots --output text | grep ${VOL_ID} | grep "Created by SYSTEMBK" | sort -k 11,11 | awk 'NR==1 {print $10}'` >> ${LOG_FILE} 2>&1 if [ $? != 0 ] ; then print_msg "ERR:${SHELLDIR}/${SHELLNAME} ec2-delete-snapshot" logger -f ${LOG_FILE} exit 1 fi SNAPSHOTS=`${AWS} ec2 describe-snapshots | grep ${VOL_ID} | grep "Created by SYSTEMBK" | wc -l` done print_msg "Delete old snapshot End" } rotate_log print_msg "INF:$SHELLDIR/${SHELLNAME} START" create_snapshot delete_old_snapshot print_msg "INF:$SHELLDIR/${SHELLNAME} END" exit 0
尚、今回は個人的な利用なので、20行目で世代数を3世代にしています。
設置できたら実行権限を付けておきます。
$ chmod +x create-snapshot.sh
cronへの設定
毎晩2時にスナップショットを取る場合は以下のように設定します。
0 2 * * * /your_script_path/create-snapshot.sh | logger -i -t DailySnapshot
このスクリプトは標準出力に処理途中の内容が出力される為、実行される度にcronの設定によりroot宛にメールが送られてしまいます。
これを止めたかったので、上記のような設定にしています。
以上です。
関連記事:
- dstatをインストールしないで使う
プロセス毎のI/Oを表示してくれたりするdstatという素晴らしいモニタリングツールがあります。 イ… - CentOSにAWS CLIをインストールする
AWS CLIのインストール方法についてです。 よく忘れてしまうので、手順として記載しておこうと思い… - CloudWatchのカスタムメトリクスでCentOSのメモリ使用率を監視する
今更感がありますが、備忘録として書いています。 では早速、下記の公式マニュアルにある「Red Hat…


