-
Notifications
You must be signed in to change notification settings - Fork 0
/
restore_db_from_snapshot.sh
executable file
·131 lines (115 loc) · 4.43 KB
/
restore_db_from_snapshot.sh
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
127
128
129
130
131
#!/bin/bash
: ${AWS_ACCESS_KEY_ID:?"Need to set AWS_ACCESS_KEY_ID"}
: ${AWS_SECRET_ACCESS_KEY:?"Need to set AWS_SECRET_ACCESS_KEY"}
: ${REGION:?"Need to set REGION"}
: ${SOURCE_REGION:-$REGION}
: ${SOURCE_INSTANCE:?"Need to set SOURCE_INSTANCE"}
: ${TARGET_INSTANCE:?"Need to set TARGET_INSTANCE"}
: ${MASTER_USER_PASSWORD:?"Need to set MASTER_USER_PASSWORD"}
: ${SECURITY_GROUP:?"Need to set SECURITY_GROUP"}
restore_db_from_snapshot() {
SNAPSHOT_INSTANCE=$SOURCE_INSTANCE"-snapshot"
TEMPORARY_INSTANCE=$TARGET_INSTANCE"-backup"
SNAPSHOT=`aws rds describe-db-snapshots \
--region $SOURCE_REGION \
--db-instance-identifier $SOURCE_INSTANCE \
--query 'DBSnapshots' | \
jq -r 'max_by(.SnapshotCreateTime).DBSnapshotIdentifier'`
if [[ $SNAPSHOT = null ]]; then
echo "Could not find latest snapshot of DB instance $SOURCE_INSTANCE"
exit
fi
echo "Snapshot: $SNAPSHOT"
DB_CLASS=`aws rds describe-db-instances \
--region $REGION \
--db-instance-identifier $TARGET_INSTANCE \
--query 'DBInstances[*].[DBInstanceClass]' \
--output text`
if [[ $DB_CLASS = null ]]; then
echo "Could not determine DB instance class of $TARGET_INSTANCE"
exit
fi
echo "DB instance class: $DB_CLASS"
if [[ $REGION != $SOURCE_REGION ]]; then
echo "Copying snapshot from $SOURCE_REGION to the target region $REGION"
SNAPSHOT_ARN=`aws rds describe-db-snapshots \
--region $SOURCE_REGION \
--db-instance-identifier $SOURCE_INSTANCE \
--query 'DBSnapshots' | \
jq -r 'max_by(.SnapshotCreateTime).DBSnapshotArn'`
echo "Source snapshot ARN: $SNAPSHOT_ARN"
SNAPSHOT=`echo $SNAPSHOT | sed 's/rds://g'`
echo "Target snapshot ID: $SNAPSHOT"
aws rds copy-db-snapshot \
--region $REGION \
--source-region $SOURCE_REGION \
--source-db-snapshot-identifier $SNAPSHOT_ARN \
--target-db-snapshot-identifier $SNAPSHOT
wait_available $SNAPSHOT snapshot
fi
echo "Restoring snapshot $SNAPSHOT -> $SNAPSHOT_INSTANCE"
aws rds restore-db-instance-from-db-snapshot \
--db-instance-class $DB_CLASS \
--db-instance-identifier $SNAPSHOT_INSTANCE \
--db-snapshot-identifier $SNAPSHOT \
--region $REGION
wait_available $SNAPSHOT_INSTANCE
echo "Renaming the original database $TARGET_INSTANCE -> $TEMPORARY_INSTANCE"
aws rds modify-db-instance \
--region $REGION \
--db-instance-identifier $TARGET_INSTANCE \
--new-db-instance-identifier $TEMPORARY_INSTANCE \
--apply-immediately
wait_available $TEMPORARY_INSTANCE
echo "Renaming the recovered database $SNAPSHOT_INSTANCE -> $TARGET_INSTANCE"
aws rds modify-db-instance \
--region $REGION \
--db-instance-identifier $SNAPSHOT_INSTANCE \
--new-db-instance-identifier $TARGET_INSTANCE \
--master-user-password $MASTER_USER_PASSWORD \
--vpc-security-group-ids $SECURITY_GROUP \
--apply-immediately
wait_available $TARGET_INSTANCE
echo "Removing the temporary instance $TEMPORARY_INSTANCE"
aws rds delete-db-instance \
--region $REGION \
--db-instance-identifier $TEMPORARY_INSTANCE \
--skip-final-snapshot
}
wait_available() {
ID=${1}
TYPE=${2:-db}
SLEEP_TIME=10
STATUS=none
while true; do
if [[ "$TYPE" = "snapshot" ]]; then
current_status=`aws rds describe-db-snapshots \
--query 'DBSnapshots[?DBSnapshotIdentifier==\`'${ID}'\`]'.Status \
--output text \
--region ${REGION}`
else
current_status=`aws rds describe-db-instances \
--query 'DBInstances[?DBInstanceIdentifier==\`'${ID}'\`]'.DBInstanceStatus \
--output text \
--region ${REGION}`
fi
if [[ "$current_status" = "$STATUS" ]]; then
echo -n "."
else
if [[ "$STATUS" != "none" ]]; then echo; fi
echo -n "Status ($TYPE $ID): ${current_status:-none}"
fi
if [[ "$current_status" = "available" ]]; then
echo
break
fi
STATUS=$current_status
sleep ${SLEEP_TIME}
done
}
restore_db_from_snapshot
if [ -f "/external/after_restore.sh" ]; then
sh /external/after_restore.sh
else
echo "/external/after_restore.sh not found"
fi