Reputation: 2765
Let's say I have an AMI with an attached EBS Volume.
I also have a snapshot.
I want to "restore" the EBS Volume to the snapshot.
What's the best process to do this?
Upvotes: 9
Views: 12728
Reputation: 1847
I have touched up the script provided by @algal to use the aws cli and polling instead of sleep. It will also look for the latest snapshot of the given volume.
#!/bin/bash
set -e
# IN PARAMS
RECOVERY_INSTANCE_ID=
SNAPSHOT_VOLUME_ID=
echo "Gathering information about the instance"
BLOCK_DEVICE_MAPPING=`aws ec2 describe-instance-attribute --instance-id ${RECOVERY_INSTANCE_ID} --attribute blockDeviceMapping`
DEVICE_NAME=`echo ${BLOCK_DEVICE_MAPPING} | jq '.BlockDeviceMappings[0].DeviceName' | tr -d '"'`
OLD_VOLUME_ID=`echo ${BLOCK_DEVICE_MAPPING} | jq '.BlockDeviceMappings[0].Ebs.VolumeId' | tr -d '"'`
AVAILABILITY_ZONE=`aws ec2 describe-instances --filters "Name=instance-id,Values='${RECOVERY_INSTANCE_ID}'" | jq '.Reservations[0].Instances[0].Placement.AvailabilityZone' | tr -d '"'`
LATEST_SNAPSHOT_ID=`aws ec2 describe-snapshots --filter "Name=volume-id,Values='${SNAPSHOT_VOLUME_ID}'" | jq '.[]|max_by(.StartTime)|.SnapshotId' | tr -d '"'`
echo "Found instance ${RECOVERY_INSTANCE_ID} in ${AVAILABILITY_ZONE} has volume ${OLD_VOLUME_ID} on device ${DEVICE_NAME}"
echo "Creating new volume from snapshot ${LATEST_SNAPSHOT_ID}"
NEW_VOLUME_ID=`aws ec2 create-volume --region eu-west-1 --availability-zone ${AVAILABILITY_ZONE} --snapshot-id ${LATEST_SNAPSHOT_ID} | jq '.VolumeId' | tr -d '"'`
echo "Created new volume ${NEW_VOLUME_ID}"
aws ec2 wait volume-available --volume-ids $NEW_VOLUME_ID
echo "Stopping the instance"
aws ec2 stop-instances --instance-ids $RECOVERY_INSTANCE_ID
aws ec2 wait instance-stopped --instance-ids $RECOVERY_INSTANCE_ID
echo "Detaching current volume"
aws ec2 detach-volume --volume-id $OLD_VOLUME_ID --instance-id $RECOVERY_INSTANCE_ID
aws ec2 wait volume-available --volume-ids $OLD_VOLUME_ID
echo "Attaching new volume"
aws ec2 attach-volume --volume-id $NEW_VOLUME_ID --instance-id $RECOVERY_INSTANCE_ID --device $DEVICE_NAME
aws ec2 wait volume-in-use --volume-ids $NEW_VOLUME_ID
echo "Starting the instance"
aws ec2 start-instances --instance-ids $RECOVERY_INSTANCE_ID
If you'd like to stay up to date with this script or contribute:
https://github.com/karimtabet/ebs_snapshot_recovery
Upvotes: 2
Reputation: 361
To replace a volume attached to an instance with a new volume created from a snapshot:
Upvotes: 1
Reputation: 28094
If you have a running EC2 instance, and you want to restore it to the state captured in an earlier snapshot, then you need to stop the instance, detach its current volume, create a new volume from the snapshot, attach the new volume to your instance, and restart your instance. Furthermore, there are a couple subtleties around specifying the availability zone of the new volume, and the device name when detaching/re-attaching the volume.
The logic might easier to see if you do it from the command line, instead of from the AWS web UI.
The following bash script is not fit for production use, since it lacks any error-checking and it just uses sleep
instead of polling to ensure AWS commands have completed. But it does perform all these steps successfully:
#!/bin/bash
set -e
# IN PARAMS
INSTANCE_ID=<YOUR_INSTANCE_ID_HERE>
SNAPSHOT_ID=<YOUR_SNAPSHOT_ID_HERE>
# OUT PARAMS
VOLUME_ID=
# begin execution
echo "Gathering information about the instance"
DEVICE_NAME=`ec2-describe-instance-attribute ${INSTANCE_ID} --block-device-mapping | awk '{print $2}'`
OLD_VOLUME_ID=`ec2-describe-instance-attribute ${INSTANCE_ID} --block-device-mapping | awk '{print $3}'`
echo "Found instance ${INSTANCE_ID} has volume ${OLD_VOLUME_ID} on device ${DEVICE_NAME}"
echo "Creating new volume from snapshot"
AVAILABILITY_ZONE=`ec2-describe-availability-zones --filter state=available | head -n 1 | awk '{print $2}'`
VOLUME_ID=`ec2-create-volume --availability-zone ${AVAILABILITY_ZONE} --snapshot ${SNAPSHOT_ID} | awk '{print $2}'`
echo "Created new volume: ${VOLUME_ID}"
sleep 20
echo "Stopping the instance"
ec2-stop-instances $INSTANCE_ID
sleep 20
echo "Detaching current volume"
ec2-detach-volume $OLD_VOLUME_ID --instance $INSTANCE_ID --device $DEVICE_NAME
sleep 20
echo "Attaching new volume"
ec2-attach-volume $VOLUME_ID --instance $INSTANCE_ID --device $DEVICE_NAME
sleep 20
echo "Starting the instance"
ec2-start-instances $INSTANCE_ID
Upvotes: 7
Reputation: 1
Make a volume from the snapshot to mount the volume on an existing EC2 machine and copy files from it.
Check the EC2 machine.
Create a volume.
Attach the volume.
Upvotes: 0
Reputation: 3800
I don't know of a way that you can 'restore' an attached volume, but the way i would do it is to create a volume from the snapshot, then detach the original and attach the new one.
Upvotes: 7