Last active
July 7, 2017 06:14
-
-
Save pocari/a363d0d56589f6a571e478f09b513c1b to your computer and use it in GitHub Desktop.
Auroraのクラスタのスナップショットを既存のAurora環境に復元する
This file contains 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
require 'logger' | |
require 'aws-sdk' | |
LOGGER = Logger.new(STDOUT) | |
def current_timestamp | |
Time.new.strftime("%Y-%m-%d-%H-%M-%S") | |
end | |
# 最大一時間待つ | |
def wait_for(wait_time: 60, retry_max: 60) | |
i = 0 | |
loop { | |
result = yield | |
break result if result | |
i += 1 | |
break false if i >= retry_max | |
sleep wait_time | |
} | |
end | |
def get_instance_class(rds, identifier) | |
rds.describe_db_instances(db_instance_identifier: identifier).db_instances.first.db_instance_class | |
end | |
def main | |
src_db_cluster_identifier = "ams-api-alpha" | |
dest_db_cluster_identifier = "ams-api-stg" | |
rds = Aws::RDS::Client.new(region: 'ap-northeast-1') | |
LOGGER.info("find latest snapshot") | |
#対象クラスタの最新のスナップショット取得 | |
src_snapshot = rds.describe_db_cluster_snapshots(db_cluster_identifier: src_db_cluster_identifier).db_cluster_snapshots.first | |
if src_snapshot | |
# 置き換え対象のクラスタ取得 | |
dest_cluster = rds.describe_db_clusters(db_cluster_identifier: dest_db_cluster_identifier).db_clusters.first | |
vpc_security_groups = dest_cluster.vpc_security_groups | |
engine = dest_cluster.engine | |
instance_classes = {} | |
# 置き換え対象のクラスタ内のインスタンスをすべて削除 | |
dest_cluster.db_cluster_members.each do |member| | |
instance_classes[member.db_instance_identifier] = get_instance_class(rds, member.db_instance_identifier) | |
LOGGER.info("delete dest instances: #{member.db_instance_identifier}") | |
rds.delete_db_instance( | |
db_instance_identifier: member.db_instance_identifier | |
) | |
end | |
result = wait_for { | |
LOGGER.info("check instances ...") | |
cluster = rds.describe_db_clusters(db_cluster_identifier: dest_db_cluster_identifier).db_clusters.first | |
count = cluster.db_cluster_members.count | |
count == 0 | |
} | |
# かなり時間かかるので待ち足りない可能性もある | |
raise "インスタンスの削除に失敗しました" unless result | |
LOGGER.info("wait delete instances: end") | |
# 置き換え対象のクラスタを削除 | |
LOGGER.info("delete dest cluster") | |
rds.delete_db_cluster( | |
db_cluster_identifier: dest_db_cluster_identifier, | |
skip_final_snapshot: true | |
) | |
# 削除されるのを待つ | |
LOGGER.info("delete cluster: start") | |
result = wait_for { | |
begin | |
LOGGER.info("check delete cluster ...") | |
rds.describe_db_clusters(db_cluster_identifier: dest_db_cluster_identifier) | |
false | |
rescue Aws::RDS::Errors::DBClusterNotFoundFault | |
# 見つからない場合例外になるのでそれで削除確認 | |
true | |
end | |
} | |
raise "削除に失敗しました" unless result | |
LOGGER.info("delete cluster: end") | |
# スナップショットから復元 | |
rds.restore_db_cluster_from_snapshot( | |
db_cluster_identifier: dest_db_cluster_identifier, | |
engine: engine, | |
snapshot_identifier: src_snapshot.db_cluster_snapshot_identifier, | |
vpc_security_group_ids: vpc_security_groups.map(&:vpc_security_group_id), | |
db_subnet_group_name: dest_cluster.db_subnet_group | |
) | |
# 復元が完了するまで待つ | |
LOGGER.info("restore cluster: start") | |
result = wait_for { | |
begin | |
LOGGER.info("check restore cluster ...") | |
cluster = rds.describe_db_clusters(db_cluster_identifier: dest_db_cluster_identifier) | |
cluster.db_clusters.first.status == "available" | |
rescue Aws::RDS::Errors::DBClusterNotFoundFault | |
false | |
end | |
} | |
LOGGER.info("restore cluster: end") | |
# クラスタパラメータグループ変更 | |
rds.modify_db_cluster( | |
db_cluster_identifier: dest_db_cluster_identifier, | |
db_cluster_parameter_group_name: dest_cluster.db_cluster_parameter_group | |
) | |
# 復元後インスタンス起動 | |
LOGGER.info("start cluster members(instances): start") | |
dest_cluster.db_cluster_members.each do |member| | |
rds.create_db_instance( | |
db_instance_identifier: member.db_instance_identifier, | |
db_instance_class: instance_classes[member.db_instance_identifier], | |
engine: dest_cluster.engine, | |
db_cluster_identifier: dest_cluster.db_cluster_identifier | |
) | |
end | |
result = wait_for { | |
cluster = rds.describe_db_clusters(db_cluster_identifier: dest_db_cluster_identifier).db_clusters.first | |
count = cluster.db_cluster_members.count | |
puts count | |
count == dest_cluster.db_cluster_members.size | |
} | |
LOGGER.info("check cluster instances in aws console") | |
LOGGER.info("restore done!") | |
end | |
end | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment