Skip to content

Instantly share code, notes, and snippets.

@yoonwaiyan
Created June 15, 2017 09:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yoonwaiyan/2b549d563dbdddb0f3963a23cab947bc to your computer and use it in GitHub Desktop.
Save yoonwaiyan/2b549d563dbdddb0f3963a23cab947bc to your computer and use it in GitHub Desktop.
Restore an instance volume with existing snapshot.
# 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