AWS SDK for Rubyでインスタンスのイメージ(AMI)を登録する
未だにEC2インスタンスのバックアップというかスナップショットからのリストアのベストプラクティスというのがわかりません。VMwareでのスナップショットと同じ感覚で操作したいのですが。。
EBSボリュームのスナップショットから復元する場合には、以下のような手順になると思います。
単一ボリュームであればそれほど問題ないのですが、複数のEBSボリュームをアタッチしている場合に手順が煩雑です。この処理を行うスクリプトやツールを作成すればよいのかもしれません。
また、別の方法として、インスタンスごとイメージ(AMI)を作成して登録しAMIを世代管理すればよいのではと思いスクリプトを書いてみた、、のですが、どうもうまく動かないので放置状態になってました。せっかくなのでここにあげておきます。
AMIから新しいインスタンスを立ち上げた場合には、インスタンスIDが変わってしまうので、別の処理でインスタンスIDに依存した部分があったりすると、それはそれで面倒です。そもそも、うまく説明できないのですがインスタンスの一個に依存するような利用・運用がEC2の特性にそぐわないのではないかという気もします。
# -*- coding: utf-8 -*- require 'rubygems' require 'yaml' require 'aws-sdk' require 'date' ID_TAG="backup" unless ARGV.size == 2 puts "Usage: #{$0} <target_instance> <count>" exit 1 end instance_id = ARGV[0] count = ARGV[1].to_i unless count > 0 puts "Count must be greater than 0 !" exit 1 end puts "Create image of #{instance_id} with #{count} generations." config = YAML.load(File.read("config.yml")) AWS.config(config) ec2 = AWS::EC2.new instance = ec2.instances[instance_id] unless instance.exists? puts "No such instance: #{instance_id}" exit 1 end # Create new image image_name = "#{instance.id}-#{DateTime.now.strftime("%Y%m%d%H%M%S")}" image_desc = "Backup image(#{instance.tags['Name']}) at #{DateTime.now}" new_image = instance.create_image(image_name, {:description => image_desc, :no_reboot => true}) # Add tag for indentifying backuped images new_image.tags << ID_TAG # wait for complete puts "waiting for new image: #{new_image.name}" begin sleep 1 new_image = ec2.images[new_image.id] end until new_image.state != :pending if new_image.state == :failure puts "create image failed: #{new_image.state_reason}" exit 1 end # Remove old images ec2.images.with_owner(:self). filter("name", "*#{instance.id}*"). filter("state", "available"). tagged(ID_TAG). sort_by{|i| i.name}.reverse_each. # sort descending by datetime each_with_index {|i, idx| if idx >= count puts "#{i.name} -> deregister" i.deregister else puts "#{i.name} -> hold" end }