Skip to content

Instantly share code, notes, and snippets.

@unluckynelson
Last active July 15, 2023 12:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save unluckynelson/e6fc32c5d4146f99b3b7dfe0655969c6 to your computer and use it in GitHub Desktop.
Save unluckynelson/e6fc32c5d4146f99b3b7dfe0655969c6 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
set -e
# Function to delete an RDS instance.
#
# Arguments
# - $1: The identifier of the RDS instance to be deleted.
#
delete_instance() {
local instance_id=$1
local status=$(aws rds delete-db-instance --skip-final-snapshot --db-instance-identifier $instance_id 2>&1)
if echo $status | grep -q "DBInstanceNotFound"; then
echo "Instance $instance_id not found."
else
local state=$(echo $status | jq -r '.DBInstance.DBInstanceStatus')
echo "Deleting $instance_id..."
fi
wait_for_db_delete_status $instance_id
}
# Function to get the latest snapshot of an RDS instance
#
# Arguments:
# - $1: The identifier of the RDS instance to be deleted.
#
# Returns:
# - latest_snapshot: the identifier of the latest snapshot
# - "No snapshots found for this instance." if no snapshots were found
get_latest_snapshot() {
local instance_id=$1
local snapshots
local latest_snapshot
snapshots=$(aws rds describe-db-snapshots --query 'DBSnapshots[?DBInstanceIdentifier==`'$instance_id'`].{SnapshotCreateTime:SnapshotCreateTime,DBSnapshotIdentifier:DBSnapshotIdentifier}' --output json)
if echo "$snapshots" | jq '. | length' | grep -q 0
then
echo "No snapshots found for this instance."
else
latest_snapshot=$(echo "$snapshots" | jq -r 'sort_by(.SnapshotCreateTime | split(".")[0] | strptime("%Y-%m-%dT%H:%M:%S") | mktime) | .[-1] | .DBSnapshotIdentifier')
echo $latest_snapshot
fi
}
# Function to restore an RDS instance from a snapshot.
#
# Arguments
# - $1: The identifier of the snapshot to be restored.
# - $2: The identifier of the RDS instance to be restored.
#
restore_db_from_snapshot() {
local snapshot_id=$1
local instance_name=$2
error=$(aws rds restore-db-instance-from-db-snapshot --db-snapshot-identifier $snapshot_id --db-instance-identifier $instance_name --no-auto-minor-version-upgrade 2>&1 > /dev/null)
if [ -n "$error" ]; then
echo "An error occurred: $error"
else
echo "The command completed successfully."
fi
wait_for_db_status $instance_name
}
# Function to wait for an RDS instance to be available.
#
# Arguments
# - $1: The identifier of the RDS instance to wait for.
#
wait_for_db_status() {
local instance_name=$1
local status=""
while [ "$status" != "available" ]; do
status=$(aws rds describe-db-instances --db-instance-identifier $instance_name | jq -r '.DBInstances[].DBInstanceStatus')
if [ "$status" != "available" ]; then
echo "Current status: $status. Waiting for availability..."
sleep 5
fi
done
echo "Instance $instance_name is now $status"
}
# Function to wait for an RDS instance to be deleted.
#
# Arguments
# - $1: The identifier of the RDS instance to wait for.
#
wait_for_db_delete_status() {
local instance_name=$1
local status=""
while [ "$status" != "" ]; do
status=$(aws rds describe-db-instances --db-instance-identifier $instance_name | jq -r '.DBInstances[].DBInstanceStatus')
if [ "$status" != "" ]; then
echo "Current status: $status. Waiting for removal..."
sleep 5
fi
done
echo "Instance $instance_name is now removed"
}
# Function to reset the master password of an RDS instance.
#
# Arguments
# - $1: The identifier of the RDS instance to be reset.
# - $2: The new password for the master user.
#
reset_master_password() {
local instance_name="$1"
local new_password="$2"
echo "Resetting master password for $instance_name..."
error=$(aws rds modify-db-instance \
--db-instance-identifier "$instance_name" \
--master-user-password "$new_password" \
--apply-immediately 2>&1 > /dev/null)
if [ -n "$error" ]; then
echo "An error occurred: $error"
else
echo "The command completed successfully."
echo "Waiting for instance to be available..."
sleep 30
wait_for_db_status $instance_name
fi
}
# Function to get the endpoint of an RDS instance.
#
# Arguments
# - $1: The identifier of the RDS instance to get the endpoint for.
#
# Returns:
# - endpoint: the endpoint of the RDS instance
get_db_instance_endpoint () {
local db_instance_identifier=$1
local endpoint=$(aws rds describe-db-instances --query "DBInstances[?DBInstanceIdentifier=='$db_instance_identifier'].Endpoint.Address" --output text)
echo "$endpoint"
}
staging="staging-instance"
production="production-instance"
latest_snapshot=$(get_latest_snapshot $production)
staging_password="hunter2"
echo "Cloning prod database to staging..."
echo "Deleting staging instance"
delete_instance $staging
echo "Latest snapshot: $latest_snapshot"
restore_db_from_snapshot $latest_snapshot $staging
reset_master_password $staging $staging_password
staging_endpoint=$(get_db_instance_endpoint $staging)
echo "New Staging endpoint: $staging_endpoint"
# TODO - update env files with new endpoint
echo "All done."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment