0
1

AWS EC2 のスナップショットからインスタンスのボリュームを復元する

Posted at

はじめに

AWS EC2 のスナップショットからインスタンスのボリューム (volume) を復元して起動させるまでの手順の覚書です。

これは、インスタンスのボリューム (volume) が1つのみのものなのでご注意ください。

昔のラックに収められていたサーバの HDD を差し替えをした人なら、なんとなく感覚がわかるんじゃないか(笑
と思います。

このスクリプトを実行するときは事前に、「インスタンスID」と「スナップショットID」を取得しておく必要があるのでご注意ください。

簡単な手順は以下になります。

  1. インスタンスを停止
  2. インスタンスに割り当たっている root デバイス名を取得
  3. 上記の root デバイス名のボリューム (volume) IDを取得
  4. インスタンスの root デバイスをデタッチ
  5. スナップショットからボリューム (volume) を復元
  6. 復元したボリューム (volume) の ID を取得
  7. インスタンスの root デバイスにボリューム (volume) をアタッチ
  8. インスタンスを開始

実際の実行

インスタンスの停止

まずは、復元するインスタンスを停止します。

aws ec2 stop-instances --instance-ids=<<<インスタンスID>>>

インスタンスに割り当たっている root デバイス名を取得

インスタンスに割り当たっている root デバイス名を取得します
※) 物理的な HDD と思えばいいかと

aws ec2 describe-instances \
    --instance-ids=<<<インスタンスID>>> \
    --query "Reservations[].Instances[].RootDeviceName"   --output text

おそらく以下のような値が返ってくるかと思います(違う可能性もあります)

/dev/sda1

インスタンスのボリュームID を取得

root デバイスに割りあっているボリューム (volume) ID を取得します。
※) まぁ、HDD でいくとパーティションみたいなもんです。ここでは 1HDD = 1ボリューム(volume) にして簡単にしています。

`aws ec2 describe-instances \
    --instance-id <<<インスタンスID>>>\
    --query "Reservations[].Instances[].BlockDeviceMappings[?DeviceName==\<<<上記で出力された root デバイス名 (/dev/sda1 とか)>>>\`].Ebs.VolumeId"   --output text`

おそらく、以下のような値が返ってくるかと思います(xxxx は半角英数字)

vol-xxxxxxxxxxxxxxxxx

インスタンスの root デバイスをデタッチ

上記で出力されたボリューム (volume) をデタッチします。 ここでは root デバイスになります
※) デバイスを umount するって言ったらわかりやすいですかね。 root デバイスを umount するので、実行したらインスタンスは 2 度と起動できませんw (マウントすれば、動作するけど)

aws ec2 detach-volume \
    --instance-id <<<インスタンスID>>>\
    --volume-id <<<上記で取得したインスタンスのボリューム (volume) ID>>>

スナップショットからボリューム (volume) を復元

スナップショットからボリュームを復元します。

availability-zone は、(この文章を読んでいるのは)日本だと思うので ap-northeast-1 ではないでしょうか
リージョンが合わないと復帰できないので、合わせるようにしてください。

まぁ、だいたいは ap-northeast-1a でしょうが。。。

aws ec2 create-volume \
    --availability-zone ap-northeast-1a <<<ここはリージョンをあわせてください>>>
    --snapshot-id <<<スナップショットID>>>
    --tag-specifications "ResourceType=volume,Tags=[{Key=Name,Value=<<<ボリュームの名前をつけるので適当な文字列(あとでこの名前で復帰するボリュームを検索します)>>>]"

復元したボリューム (volume) の ID を取得

上記で復元したボリューム (volume) の ID を取得します。
取得する際、ボリューム (volume) につけた名前で検索をします。

aws ec2 describe-volumes \
    --filters Name=tag:Name,Values=<<<ボリュームの名前>>> \
    --query "Volumes[].VolumeId" \
    --output text

おそらく、以下のような値が返ってくるかと思います(xxxx は半角英数字)
これが、復元したボリューム(のID) です。

vol-xxxxxxxxxxxxxxxxx

復元したボリューム (volume) をインスタンスにアタッチ

※) サーバに HDD をはめ込んでデバイスをマウントするわけですw

aws ec2 attach-volume \
    --device <<<root デバイス名>>>
    --instance-id <<<インスタンスID>>> \\
    --volume-id <<<復元したボリューム (volume) のID>>>

インスタンスの起動

最後にインスタンスを起動します

aws ec2 start-instances --instance-ids=<<<インスタンスID>>>

不要なボリュームを削除

もし、復元するときにデタッチしたボリュームが不要な場合は削除しちゃいましょう
※) どんどんボリュームが増えて、見た目上わけわからんくなるので。。。

aws ec2 delete-volume --volume-id <<<デタッチしたボリューム ID>>>

まとめ

上記を bash スクリプトにすると以下のようになります。
スクリプト内なので「`」をエスケープしないといけないとかあるので「\」が若干増えているとことがありますw

#!/bin/bash
DATE=`date "+%Y%m%d%H%M%S"`

INSTANCE_ID=i-xxxxxxxxxxxxxxxxx
SNAP_SHOT_ID=snap-xxxxxxxxxxxxxxxx

# インスタンスを停止
aws ec2 stop-instances --instance-ids=${INSTANCE_ID}

# インスタンスが停止するまで待機
aws ec2 wait instance-stopped --instance-ids=${INSTANCE_ID}

# root デバイス名取得
INSTANCE_ROOT_DEV=`aws ec2 describe-instances \
    --instance-ids=${INSTANCE_ID} \
    --query "Reservations[].Instances[].RootDeviceName" \
    --output text`

# root デバイスの volume 名を取得
ROOT_DEV_VOLUME=`aws ec2 describe-instances \
    --instance-id ${INSTANCE_ID} \
    --query "Reservations[].Instances[].BlockDeviceMappings[?DeviceName==\\\`${INSTANCE_ROOT_DEV}\\\`].Ebs.VolumeId"   \
    --output text`


# root デバイスの volume をデタッチ
aws ec2 detach-volume --instance-id ${INSTANCE_ID} --volume-id ${ROOT_DEV_VOLUME}

# スナップショットから volume 復元
RESTORE_VOLUME_TAG_VALUE="instance_restore_${DATE}"
aws ec2 create-volume \
    --availability-zone ap-northeast-1a \
    --snapshot-id ${SNAP_SHOT_ID} \
    --tag-specifications "ResourceType=volume,Tags=[{Key=Name,Value=$RESTORE_VOLUME_TAG_VALUE}}]"


# volume 復元まで待機
aws ec2 wait volume-available \
    --filters Name=tag:Name,Values=${RESTORE_VOLUME_TAG_VALUE}

# root デバイスに vlolume をアタッチ
aws ec2 attach-volume --device ${INSTANCE_ROOT_DEV} --instance-id ${INSTANCE_ID} --volume-id ${RESTORE_VOLUME_ID}


# インスタンスを開始
aws ec2 start-instances --instance-ids=${INSTANCE_ID}

# 不要な volume を削除
aws ec2 delete-volume --volume-id ${ROOT_DEV_VOLUME}

おわりに

インテリジェンスにスナップショットやインスタンスの ID を取得して実行する方法ではないので、事前にある程度、情報をまとめておく必要がありますので、若干めんどくさいです。

そのめんどくさいのは、今後改善していきたいとは思ってます。

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