LoginSignup
4
5

More than 5 years have passed since last update.

EBS snapshot automation

Last updated at Posted at 2016-07-05

0. はじめに

EC2がなにかと増えてきて、EBSのスナップショットの容量、個数が増えてきて、Human Errorが出る前に自動化しときたいなーと思っていた所、こちらの記事(http://qiita.com/MasaoDX/items/39624823fff337d08e6f) を参考にさせていただきました。

AWSCLIで
1.バックアップターゲットEBSの検索
2.Snapshot作成
3.保持期間,VolumeID,device name等の情報をsnapshotに付加
4.消してもOKなsnapshotを検索して削除
5.snapshotをとったvolumeをAWSSNSで通知

0. System Requirement

1. IAM Roleの準備

Snapshotを作ったり消したりするためだけのIAM Roleを設定します。権限を最低限に抑えるのがお作法だと聞いております。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CreateDeleteSnapshot",
            "Effect": "Allow",
            "Action": [
                "ec2:Describe*",
                "ec2:CreateSnapshot",
                "ec2:DeleteSnapshot",
                "ec2:CreateImage",
                "ec2:CreateTags",
                "ec2:DescribeImages",
                "ec2:DeregisterImage"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

2. AWS CLI実行用のInstance準備

2.1 Amazon Linuxの起動 with IAM Role

2.2 jq install

sudo yum install jq

3. EBS側の準備

3.1 Tag付け

  • バックアップのターゲットになるEBSにtagをつけます。このタグで検索してバックアップを実行します。
Key   = backup_target
Value = true

4. 実行するシェルスクリプト

4.1 変数定義

DATE_CURRENT=`date +%Y-%m-%d`
TIME_CURRENT=`date +%Y%m%d%H%M%S`
PURGE_AFTER_DAYS=0
PURGE_AFTER=`date -d +${PURGE_AFTER_DAYS}days -u +%Y-%m-%d`
BACKUP_KEY='backup_target'
AWS_REGION='us-west-2'
SNS_REGION='us-west-2'
SNS_TOPIC_NAME='MySNSTopic'
SNS_TOPIC_ARN=`aws --region ${SNS_REGION} sns list-topics | jq -r .Topics[].TopicArn | grep ${SNS_TOPIC_NAME}`
ERROR_VOL='./error_vol.txt'
SUCCESS_VOL='./succes_vol.txt'

4.2 Snapshotの作成

# 1-1. listing-up backup target volume-id
VOLUMES=`aws --region ${AWS_REGION} ec2 describe-volumes --filters Name=tag:${BACKUP_KEY},Values=true | jq -r '.Volumes[].Attachments[] | .VolumeId'`

for VOLUME in ${VOLUMES}; do
  BACKUP=`aws --region ${AWS_REGION} ec2 describe-tags --filters "Name=resource-type,Values=volume" "Name=resource-id,Values=${VOLUME}" "Name=key,Values=${BACKUP_KEY}" | jq -r .Tags[].Value`
  INSTANCE_ID=`aws --region ${AWS_REGION} ec2 describe-volumes --filters Name=volume-id,Values=${VOLUME} | jq -r '.Volumes[].Attachments[] | .InstanceId'`
  Device_Name=`aws --region ${AWS_REGION} ec2 describe-volumes --filters Name=volume-id,Values=${VOLUME} | jq -r '.Volumes[].Attachments[] | .Device'`
  INSTANCE_NAME=`aws --region ${AWS_REGION} ec2 describe-tags --filters Name=resource-id,Values=${INSTANCE_ID} Name=key,Values=Name | jq -r .Tags[].Value`

  # 1-2.verify backup target volume with tag
  if [ "${BACKUP}" == "true" ]; then
    # 1-3.create snapshot
    SNAPSHOT_ID=`aws --region ${AWS_REGION} ec2 create-snapshot --volume-id ${VOLUME} --description "${INSTANCE_NAME} ${INSTANCE_ID} ${Device_Name} ${VOLUME} ${TIME_CURRENT}" | jq -r '.SnapshotId'`
      if [ -z "${SNAPSHOT_ID}" ]; then
        echo ${VOLUME} >> "${ERROR_VOL}"
      else
        echo ${VOLUME} >> "${SUCCESS_VOL}"
      fi
    # 1-4.adding tag for searching
    aws --region ${AWS_REGION} ec2 create-tags --resources ${SNAPSHOT_ID} --tags Key=PurgeAllow,Value=true Key=PurgeAfter,Value=${PURGE_AFTER} Key=PurgeTarget,Value=${BACKUP_KEY} Key=Name,Value="${INSTANCE_NAME} ${INSTANCE_ID} ${Device_Name} ${VOLUME} ${TIME_CURRENT}"
  fi
done

4.3 Snapshotの削除

# 2-1.find delete target snapshot volume with tag
SNAPSHOT_PURGE_ALLOWED=`aws --region ${AWS_REGION} ec2 describe-tags --filters "Name=resource-type,Values=snapshot" "Name=key,Values=PurgeAllow" | jq -r .Tags[].ResourceId`

# 2-2. verify the delete target volumes with 2 tags
for SNAPSHOT_ID in ${SNAPSHOT_PURGE_ALLOWED}; do
  PURGE_AFTER_DATE=`aws --region ${AWS_REGION} ec2 describe-tags --filters "Name=resource-type,Values=snapshot" "Name=resource-id,Values=${SNAPSHOT_ID}" "Name=key,Values=PurgeAfter" | jq -r .Tags[].Value`
  PURGE_TARGET_CHECK=`aws --region ${AWS_REGION} ec2 describe-tags --filters "Name=resource-type,Values=snapshot" "Name=resource-id,Values=${SNAPSHOT_ID}" "Name=key,Values=PurgeTarget" | jq -r .Tags[].Value`

  if [ "${PURGE_TARGET_CHECK}" == "${BACKUP_KEY}" ]; then

    if [ -n ${PURGE_AFTER_DATE} ]; then
      DATE_CURRENT_EPOCH=`date -d ${DATE_CURRENT} +%s`
      PURGE_AFTER_DATE_EPOCH=`date -d ${PURGE_AFTER_DATE} +%s`

      if [[ ${PURGE_AFTER_DATE_EPOCH} < ${DATE_CURRENT_EPOCH} ]]; then
        # 2-2.judge the target and delete the snapshots
        aws --region ${AWS_REGION} ec2 delete-snapshot --snapshot-id ${SNAPSHOT_ID}
      fi
    fi
  fi
done

4.3 SNSで結果報告

#3-1. send notification mail
if [ -e "${ERROR_VOL}" ]; then
# create message header
cat << EOF >> ${ERROR_VOL}

There are EBS volumes failed to take snapshots on above volumes, please contact to AWS admin

EOF
  date >> ${ERROR_VOL}
  aws --region ${SNS_REGION} sns publish --topic-arn ${SNS_TOPIC_ARN} --message file://tokyo_error_vol.txt --subject "[ERROR] EBS Backup"
rm -f ${ERROR_VOL}

elif [ -e "${SUCCESS_VOL}" ]; then
# create message header
cat << EOF >> ${SUCCESS_VOL}

Taking EBS snapshot was succesfully completed on above volumes. Have a nice day!

EOF
  date >> ${SUCCESS_VOL}
  aws --region ${SNS_REGION} sns publish --topic-arn ${SNS_TOPIC_ARN} --message file://tokyo_succes_vol.txt --subject "[SUCCESS] EBS Backup"
  rm -f ${SUCCESS_VOL}

else
  aws --region ${SNS_REGION} sns publish --topic-arn ${SNS_TOPIC_ARN} --message "There are no target EBS Volumes" --subject "[WARN] EBS Backup"
  rm -f ${SUCCESS_VOL}
fi

5. cronで定期実行

書いたシェルスクリプトをcronで定期実行してあげる。例えばこんな感じに。

00 01 * * 0 ~/backup.sh >> /var/log/cron.log

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5