Created
June 15, 2017 09:20
-
-
Save yoonwaiyan/2b549d563dbdddb0f3963a23cab947bc to your computer and use it in GitHub Desktop.
Restore an instance volume with existing snapshot.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# modified/rewrite from http://gist.github.com/cNeha/4eddaa1aabe112b72976e06cb2dbfa54 | |
require 'aws-sdk' | |
class SnapshotRestorer | |
PROVIDER_REGION = "<region>" | |
SNAPSHOT_ID = '<snapshot_id>' | |
attr_reader :ec2, :target_instance_id, :dry_run_mode | |
def initialize(args = {}) | |
@ec2 = get_ec2 | |
@target_instance_id = args.fetch(:instance_id) | |
@dry_run_mode = args.fetch(:dry_run_mode, true) | |
end | |
def perform | |
# Checking the status of target instance. Stop the instance if it is running. | |
instance = ec2.instance(target_instance_id) | |
@zone_name = instance.placement.availability_zone | |
puts "Instance ID is #{instance.id} and Instance state is #{instance.state.name} and Availability zone is #{@zone_name}" | |
unless instance.state.name.casecmp("stopped") == 0 | |
instance.stop({ | |
dry_run: dry_run_mode, | |
force: false | |
}) | |
puts "Waiting for instance to stop..." | |
wait_instance_stop | |
puts "finished sleeping." | |
end | |
# Detaching volumes | |
instance.volumes.each do |volume| | |
volume_id = volume.id | |
puts "detaching volume #{volume_id}" | |
detach_result = instance.detach_volume({ | |
volume_id: volume_id, | |
dry_run: dry_run_mode, | |
force: false | |
}) | |
@device_name = detach_result.device | |
puts "device_name: #{@device_name}" | |
wait_volume_available(volume_id) | |
puts "Volume #{volume_id} has been detached from Instance #{target_instance_id} with device name: #{@device_name}" | |
volume.delete(dry_run: dry_run_mode) | |
puts "Volume has been deleted successfully" | |
end | |
return nil if @device_name.nil? | |
# Create volume with snapshot | |
puts "Restoring the Snapshot" | |
vol = ec2.create_volume({ | |
dry_run: false, | |
snapshot_id: SNAPSHOT_ID, | |
availability_zone: @zone_name | |
}) | |
wait_volume_available(vol.id) | |
puts "New Volume is #{vol.id} and its state is #{vol.state}" | |
attach_vol = instance.attach_volume({ | |
dry_run: false, | |
volume_id: vol.id, | |
device: @device_name | |
}) | |
puts "Volume #{attach_vol.volume_id} has been attached to instance #{target_instance_id} with state #{attach_vol.state}" | |
# Restart the instance after restoring snapshot | |
puts "Restarting instance..." | |
restart_result = instance.start(dry_run: dry_run_mode) | |
puts "Finish restarting instance. Instances:" | |
p restart_result | |
wait_instance_run | |
instance = ec2.instance(target_instance_id) | |
return instance.public_ip_address | |
rescue Exception => e | |
Rollbar.error(e) | |
return nil | |
end | |
private | |
def get_ec2 | |
client = Aws::EC2::Client.new({ | |
:region => "<region>", | |
:access_key_id => "<access_key_id>", | |
:secret_access_key => "<secret_access_key>" | |
}) | |
Aws::EC2::Resource.new(client: client) | |
end | |
def wait_instance_run | |
instance = ec2.instance(target_instance_id) | |
puts "instance state: #{instance.state.name}" | |
if instance.state.name == "running" | |
return instance | |
else | |
sleep 1 | |
wait_instance_run | |
end | |
end | |
def wait_instance_stop | |
instance = ec2.instance(target_instance_id) | |
puts "instance state: #{instance.state.name}" | |
if instance.state.name == "stopped" | |
return instance | |
else | |
sleep 1 | |
wait_instance_stop | |
end | |
end | |
def wait_volume_available(volume_id) | |
volume = ec2.volume(volume_id) | |
puts "volume state: #{volume.state}" | |
if volume.state == "available" | |
return volume | |
else | |
sleep 1 | |
wait_volume_available(volume_id) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment