Created
July 17, 2023 11:18
-
-
Save DelusionalOptimist/e2d66c53fb02d3569345a2d3dbfbd196 to your computer and use it in GitHub Desktop.
Deallocate your DigitalOcean droplets by creating snapshots
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
#!/bin/env bash | |
# MOTIVATION: | |
# I setup a dev env in a DigitalOcean droplet once. | |
# However I was annoyed by the fact that there | |
# is no way to deallocate (like in Azure) the VM | |
# and save credits when not in use. | |
# Thus, I implemented this script to create snapshots, which | |
# are cheaper then droplets. | |
# NOTE: THIS HAS ONLY BEEN TESTED WITH A SINGLE INSTANCE. | |
# USE IT AT YOUR OWN RISK. | |
main() { | |
CONFIG=$HOME/.config/doctl/snapdrop.config | |
if [[ -f "$CONFIG" ]]; then | |
echo "Using config $CONFIG..." | |
else | |
echo "Prompting for default values..." | |
set_defaults | |
fi | |
# DEFAULT VALUES ARE SOURCED FROM $CONFIG | |
source $CONFIG | |
local DROPLET_ID=$DEFAULT_DROPLET_ID | |
local DROPLET_NAME=$DEFAULT_DROPLET_NAME | |
local SSH_KEY=$DEFAULT_SSH_KEY | |
local SNAPSHOT=$DEFAULT_SNAPSHOT_NAME | |
local DROPLET_SIZE=$DEFAULT_DROPLET_SIZE | |
parse_cli_args "$@" | |
if [[ $CREATE == "true" && $DELETE == "false" ]] | |
then | |
create_droplet $DROPLET_ID $SNAPSHOT $SSH_KEY $DROPLET_NAME $DROPLET_SIZE | |
exit 1 | |
elif [[ $CREATE == "false" && $DELETE == "true" ]] | |
then | |
deallocate_droplet $DROPLET_ID $SNAPSHOT | |
fi | |
} | |
set_defaults() { | |
echo "Enter default droplet name" | |
read DEFAULT_DROPLET_NAME | |
DEFAULT_DROPLET_ID=$(doctl compute droplet get $DEFAULT_DROPLET_NAME -o json | jq '.[] | ."id"') | |
echo "Enter default ssh key" | |
read DEFAULT_SSH_KEY | |
echo "Enter default snapshot name" | |
read DEFAULT_SNAPSHOT_NAME | |
echo "DEFAULT_DROPLET_NAME=$DEFAULT_DROPLET_NAME" >> $CONFIG | |
echo "DEFAULT_DROPLET_ID=$DEFAULT_DROPLET_ID" >> $CONFIG | |
echo "DEFAULT_SSH_KEY=$DEFAULT_SSH_KEY" >> $CONFIG | |
echo "DEFAULT_SNAPSHOT_NAME=$DEFAULT_SNAPSHOT_NAME" >> $CONFIG | |
} | |
# restores a droplet from a given snapshot | |
create_droplet() { | |
echo "Getting snapshot id..." | |
SNAPSHOT_ID=$(doctl compute snapshot list -o json | jq '.[] | select(.resource_id=='\"$1\"') | select(.name=='\"$2\"') | ."id"' | tr -d '"') | |
echo "Creating droplet..." | |
doctl compute droplet create --image $SNAPSHOT_ID --size $5 --ssh-keys $3 --region blr1 --wait $4 | |
DROPLET_ID_NEW=$(doctl compute droplet get $4 -o json | jq '.[] | ."id"') | |
sed -i 's/DEFAULT_DROPLET_ID=.*/DEFAULT_DROPLET_ID='$DROPLET_ID_NEW'/g' $CONFIG | |
echo "Deleting snapshot..." | |
doctl compute snapshot delete --force $SNAPSHOT_ID | |
} | |
# powers off, creates a snapshot and deletes a droplet | |
deallocate_droplet() { | |
echo "Powering off..." | |
doctl compute droplet-action power-off $1 --wait | |
echo "Taking a snapshot..." | |
doctl compute droplet-action snapshot $1 --snapshot-name $2 --wait | |
echo "Saved snapshot with ID: $(doctl compute droplet snapshots $1 -o json | jq '.[] | select(.name=="'$2'") | ."id"')" | |
echo "Deleting droplet..." | |
doctl compute droplet delete --force $1 | |
} | |
parse_cli_args() { | |
while : | |
do | |
case "${1:-}" in | |
restore) | |
CREATE=true | |
DELETE=false | |
shift | |
;; | |
deallocate) | |
DELETE=true | |
CREATE=false | |
shift | |
;; | |
--droplet) | |
if [[ -n "${2:-}" ]]; then | |
DROPLET_NAME=$2 | |
DROPLET_ID=$(doctl compute droplet get $DROPLET_NAME -o json | jq '.[] | ."id"') | |
shift | |
else | |
echo "ERROR: '--droplet' cannot be empty." >&2 | |
exit 1 | |
fi | |
;; | |
--snapshot) | |
if [[ -n "${2:-}" ]]; then | |
SNAPSHOT=$2 | |
shift | |
else | |
echo "ERROR: '--droplet-name' cannot be empty." >&2 | |
exit 1 | |
fi | |
;; | |
help|--help|-h) | |
printf "\nsnapdrop: A CLI for deallocating and restoring Digital Ocean Droplets (VMs)\n" | |
printf "COMMANDS:\n" | |
printf "deallocate:\t\tdeallocates given droplet\n" | |
printf "restore:\t\trestores droplet with the given snapshot\n" | |
printf "\nFLAGS:\n--droplet:\t\tname of the droplet to be referenced\n--snapshot:\t\tname of the snapshot to be referenced\n" | |
exit 0 | |
;; | |
set-defaults) | |
rm -rf $CONFIG | |
set_defaults | |
exit 0 | |
;; | |
*) | |
break | |
;; | |
esac | |
shift | |
done | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment