スナップショットを自動で作成するには?

網元AMIでは AWS の様々なサービスをコマンドラインから利用することができるツール AWS CLI がインストールされています。このツールと cron を使用することにより、サーバイメージのバックアップ (スナップショット) を定期的に自動作成することができます。

ここでは、AWS CLI を利用するための IAM ユーザの作成から、稼働しているインスタンスに関連付けられているボリュームのスナップショットを作成するシェルスクリプトを紹介します。

 

 

IAM ユーザの作成

AWS の提供する各種 API を使用するためには Access Key と Secret Access Key が必要になります。

これらは AWS Identity and Access Management (IAM) というサービスを使用して取得することが可能です。

ここでは、AWS の IAM管理画面 で、スナップショット作成に必要な権限を持ったユーザを作成して Access Key を取得するまでを説明します。

 

カスタムポリシーの作成

 IAM には、デフォルトで様々なポリシーが用意されています。しかし、スナップショットを作成するだけの権限を持ったポリシーは用意されていないのでカスタムポリシーを作成しましょう。

 まず IAM のポリシー管理画面 を表示します。

 

スクリーンショット 2015-03-04 19.31.19

次に [Create Policy] ボタンをクリックします。

スクリーンショット 2015-03-04 19.31.41

Step1 では、[Create Your Own Policy] を選択します。

 

[Create Your Own Policy] を選択すると Step2 が飛ばされ Step3 へ移ります。
ここでは、以下のように入力して [Create Policy] をクリックしてください。

 

Policy Name

ポリシー名を設定します。

AmazonEC2CreateSnapshots

Description

ポリシーの説明を入力してください。スナップショット用のポリシーなので、スナップショット作成用 等、分かりやすい説明を入力してください。

Policy Document

ここには json 形式でポリシーを設定します。

以下のように入力することで ec2 関係の値の読み取りと、Snapshot の作成・削除のみを許可できます。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:Describe*",
        "ec2:CreateSnapshot",
        "ec2:DeleteSnapshot"
      ],
      "Resource": "*"
    }
  ]
}

 

グループの作成

 次に先ほど作成したポリシーが適用されたグループを作成します。ユーザに直接ポリシーを設定することもできますが、ユーザが増えてくると管理が煩雑になるため、グループにポリシーを設定して、ユーザは使用したいポリシーを持ったグループに所属させる方が、後々の管理が楽になるでしょう。

 

スクリーンショット 2015-03-04 19.32.45

IAM のグループ管理画面 を表示し、[Create New Group] ボタンをクリックします。

 

Step1 では、グループ名を設定します。[Group Name] 欄に create_snapshot などのわかりやすい名前を入力して [Next Step] ボタンをクリックします。

 

Step2 では、このグループに適用するポリシーを選択します。先ほど作成したポリシー AmazonEC2CreateSnapshots を選択して **Next Step** ボタンをクリックします。

 

Step3 では、Step1, Step2 で設定した内容を確認します。問題なければ [Create Group] ボタンをクリックしてグループを作成してください。間違いが見つかった場合は [Previous] ボタンをクリックすれば Step2 に戻ることができます。

 

 

ユーザの作成

最後に実際に AWS CLI を利用するユーザを作成して Access Key と Secret Access Key を取得します。

 

スクリーンショット 2015-03-04 19.33.45

IAM のユーザー管理画面 を表示し、Create New Users ボタンをクリックします。

 

Step1 では、作成するユーザの名前を設定します。[Enter User Names] 欄にユーザ名を入力して [Create] をクリックしてください。最大で5人まで同時に作成することができます。

 

ユーザの作成が成功すると、ユーザ名, Access KeySecret Access Key が記載された csv ファイルをダウンロードできます。[Download Credentials] ボタンをクリックすると credentials.csv という CSV ファイルをダウンロードできます。こちらの内容は以下のようにユーザごとに1行になっていて、ユーザ名, Access KeySecret Access Key の順にカンマ区切りで書かれたテキストファイルになります。

"user_name",AXXXXXXXXXXXXXXXXXXX,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

 

スクリーンショット 2015-03-04 19.34.41

最後に作成したユーザを一覧から選択して詳細を表示させ [Add User to Groups] ボタンをクリックして、さきほど作成した create_snapshot グループにこのユーザが所属するように設定してください。

グループを作成しなかった場合は [Attach Policy] ボタンをクリックして、最初に作成したポリシー AmazonEC2CreateSnapshots を付与しても良いです。

 

ここまでの作業で、Snapshot 作成権限を持った IAM ユーザの Access Key と Secret Access Key が用意できました。

次はインスタンスに ssh 接続してスナップショットを作成するシェルスクリプトを設定しましょう。

 

AWS CLI の設定とスナップショットを作成するシェルスクリプトの実行

 

AWS CLI の設定

 

網元AMI のインスタンスに ssh 接続して、以下のコマンドを実行してください。Access Key, Secret Access Key, Default region などを聞かれるので適切に入力します。tokyo リージョンを使用するのであれば Default region name には ap-northeast-1 を入力してください。

$ aws configure
AWS Access Key ID [None]: 
AWS Secret Access Key [None]: 
Default region name [None]: 
Default output format [None]: 

ここで入力した値が保存される設定ファイルは ~/.aws/ ディレクトリ内に作成される configcredentials になります。

 

スナップショットを作成するシェルスクリプトの実行

 

次に AWS CLI を使用して、自インスタンスに接続されている volume のスナップショットを作成するシェルスクリプトを作成します。

こちらを利用してください。

https://gist.github.com/wokamoto/1c53fd9d9ce54c446489

#!/bin/sh
SHELLDIR=`dirname ${0}`
SHELLDIR=`cd ${SHELLDIR}; pwd`
SHELLNAME=`basename $0`

LOG_DIR="/var/log"
LOG_SAVE_PERIOD=14
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=2

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
    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
	

 

6行目は実行時ログを保存するディレクトリです。
実行するユーザが書き込めるディレクトリに適宜変更してください。

10行目は自インスタンスが稼働しているリージョンの名です。

11行目はスナップショットを保存しておく世代です。
この例では2が設定されていますので、3世代前のスナップショットは、このスクリプトを実行すると自動的に削除されます。

 

このスクリプトをインスタンスにダウンロードして実行する手順は以下のとおりです。

$ wget https://gist.githubusercontent.com/wokamoto/1c53fd9d9ce54c446489/raw/create-snapshot.sh
--2015-03-04 19:37:58--  https://gist.githubusercontent.com/wokamoto/1c53fd9d9ce54c446489/raw/e08459f978ee979fcec3ca3d9d77210dae92bc4c/create-snapshot.sh
gist.githubusercontent.com (gist.githubusercontent.com) をDNSに問いあわせています... 103.245.222.133
gist.githubusercontent.com (gist.githubusercontent.com)|103.245.222.133|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 2383 (2.3K) [text/plain]
`create-snapshot.sh' に保存中

create-snapshot.sh                  100%[====================================================================>]   2.33K  --.-KB/s 時間 0s     

2015-03-04 19:37:58 (140 MB/s) - `create-snapshot.sh' へ保存完了 [2383/2383]

$ chmod +x create-snapshot.sh 

※ このまま、実行すると /var/log に書き込み権限がないためエラーが発生します。6行目を実行するユーザが書き込めるディレクトリに変更してから、スクリプトを実行してください。

 

このスクリプトを cron に登録しておくと、定期的にスナップショットを作成することが可能です。

cron への登録方法については、以下の参考URLを参考にしてください。

他にご質問がございましたら、リクエストを送信してください

0 コメント

ログインしてコメントを残してください。
Powered by Zendesk