AWS: EC2インスタンスをスナップショットから復元するスクリプト
スナップショットのリストアに伴う一連の操作をスクリプト化。
デバイスが EBS 1個だけの場合にのみ対応。
- 対象のインスタンスID、スナップショットIDを引数に指定するので事前に確認
こちらを参照
mog project: AWS: More Listings of EC2 Information
コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | #!/usr/bin/env python # -*- coding: utf-8 -*- import sys import subprocess import time try : import json except ImportError: print ( 'You need python 2.6 or later to run this script.' ) sys.exit( 1 ) def usage(): print ( 'Usage: %s <instance-id> <snapshot-id>' % sys.argv[ 0 ]) sys.exit( 2 ) def run_command( * args): output = subprocess.check_output([ 'aws' , 'ec2' ] + list (args)) return json.loads(output) def get_volume_id(instance): assert ( len (instance[ 'BlockDeviceMappings' ]) = = 1 ) return instance[ 'BlockDeviceMappings' ][ 0 ][ 'Ebs' ][ 'VolumeId' ] def get_zone(instance): return instance[ 'Placement' ][ 'AvailabilityZone' ] def get_device(instance): assert ( len (instance[ 'BlockDeviceMappings' ]) = = 1 ) return instance[ 'BlockDeviceMappings' ][ 0 ][ 'DeviceName' ] def is_running(instance): return instance[ 'State' ][ 'Code' ] = = 16 def is_stopped(instance): return instance[ 'State' ][ 'Code' ] = = 80 def get_instance(instance_id): j = run_command( 'describe-instances' , '--instance-ids' , instance_id) return j[ 'Reservations' ][ 0 ][ 'Instances' ][ 0 ] def start_instance(instance_id): sys.stdout.write( 'Starting instance: %s ...' % instance_id) run_command( 'start-instances' , '--instance-ids' , instance_id) for i in range ( 20 ): sys.stdout.write( '.' ) time.sleep( 10 ) if is_running(get_instance(instance_id)): break else : raise (RunTimeError( 'Timed out for waiting.' )) print ( 'OK' ) def stop_instance(instance_id): sys.stdout.write( 'Stopping instance: %s ...' % instance_id) run_command( 'stop-instances' , '--instance-ids' , instance_id) for i in range ( 20 ): sys.stdout.write( '.' ) time.sleep( 10 ) if is_stopped(get_instance(instance_id)): break else : raise (RunTimeError( 'Timed out for waiting.' )) print ( 'OK' ) def detach_volume(volume_id): sys.stdout.write( 'Detaching volume: %s ...' % volume_id) run_command( 'detach-volume' , '--volume-id' , volume_id) print ( 'OK' ) def create_volume(zone, snapshot): sys.stdout.write( 'Creating volume from snapshot: %s ...' % snapshot) j = run_command( 'create-volume' , '--availability-zone' , zone, '--snapshot-id' , snapshot) print ( 'OK' ) return j[ 'VolumeId' ] def attach_volume(volume_id, instance_id, device): sys.stdout.write( 'Attaching volume: %s ...' % volume_id) run_command( 'attach-volume' , '--volume-id' , volume_id, '--instance-id' , instance_id, '--device' , device) print ( 'OK' ) def delete_volume(volume_id): sys.stdout.write( 'Deleting volume: %s ...' % volume_id) run_command( 'delete-volume' , '--volume-id' , volume_id) print ( 'OK' ) if __name__ = = '__main__' : if len (sys.argv) ! = 3 : usage() instance_id = sys.argv[ 1 ] snapshot = sys.argv[ 2 ] sys.stdout.write( 'Checking instance: %s ...' % instance_id) ins = get_instance(instance_id) old_vol = get_volume_id(ins) print ( 'OK' ) stop_instance(instance_id) detach_volume(old_vol) new_vol = create_volume(get_zone(ins), snapshot) attach_volume(new_vol, instance_id, get_device(ins)) start_instance(instance_id) delete_volume(old_vol) |
実行例
$ ./aws_restore.py i-xxxxxxxx snap-XXXXXXXX Checking instance: i-xxxxxxxx ...OK Stopping instance: i-xxxxxxxx .......OK Detaching volume: vol-yyyyyyyy ...OK Creating volume from snapshot: snap-XXXXXXXX ...OK Attaching volume: vol-zzzzzzzz ...OK Starting instance: i-xxxxxxxx .....OK Deleting volume: vol-yyyyyyyy ...OK |
0 件のコメント:
コメントを投稿