Automate Vultr Snapshots Using Bash

Vultr is a VPS (Virtual Private Server) hosting platform that uses KVM (Kernel-based Virtual Machine) Disclosure: Link contains a referral. Logging into their website over and over again to make a snapshot is tedious. Let’s automate this process using Bash, and systemd timers.
Vultr offers an excellent
API (application program interface)
that lets you programmatically orchestrate a web based hypervisor dashboard, right down to account payments. We will use this API
to automatically create snapshots.
Vultr’s
Other low level methods for snapshotting exist. This is merely a nice convenience.
are free, but pricing may be subject to
Vultr shows this disclaimer below the snapshot dashboard.
As of writing, Vultr appears to support up to 11
free snapshots out of the box, so we will create a script with this in mind.

First let’s set up the variables that our script will use.
#!/bin/sh -eu
Key='YourAPIKEY'
SnapshotLimit=11
SnapshotCount=$(curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep -o SNAPSHOTID | wc -l)
Fields=$(curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep -o '"' | wc -l)
LastSnapshotField=$((Fields - 24))
LastSnapshotID=$(curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep '"' | cut -d '"' -f $LastSnapshotField)
We are using command substitutions with curl
. Let’s add our API
key and set the snapshot limit to 11
. The API
will respond in json
. We can install
jq
but I’ll use the tools that are available to process the output.
We will get the current number of snapshots using grep
and wc
.
SnapshotCount=$(curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep -o SNAPSHOTID | wc -l)
Then use the same technique to get the number of fields in the json
output delimited by "
.
Fields=$(curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep -o '"' | wc -l)
Since we have an upper snapshot limit of 11
, we also need to know the ID
of the oldest snapshot. This will allow us to destroy that snapshot when we reach Vultr’s limit automatically.
I already know that the oldest snapshot ID
is always 24
fields away from the end of the delimited json
output.
LastSnapshotField=$((Fields - 24))
We finish up by using grep
and cut
to extract the oldest snapshot ID
.
LastSnapshotID=$(curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep '"' | cut -d '"' -f $LastSnapshotField)
Execute a simple if
statement to destroy that snapshot when necessary. Nothing fancy.
if [ "$SnapshotCount" -eq "$SnapshotLimit" ]
then
curl -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/destroy --data "SNAPSHOTID=$LastSnapshotID";
fi
curl -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/create --data 'SUBID=YourSUBID';
Our full script now looks like this;
#!/bin/sh -eu
Key='YourAPIKEY'
SnapshotLimit=11
SnapshotCount=$(curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep -o SNAPSHOTID | wc -l)
Fields=$(curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep -o '"' | wc -l)
LastSnapshotField=$((Fields - 24))
LastSnapshotID=$(curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep '"' | cut -d '"' -f $LastSnapshotField)
if [ "$SnapshotCount" -eq "$SnapshotLimit" ]
then
curl -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/destroy --data "SNAPSHOTID=$LastSnapshotID";
fi
curl -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/create --data 'SUBID=YourSUBID';
Let’s drop this into a systemd
service at /etc/systemd/system/vultr-snapshot.service
.
[Unit]
Description=Create Vultr Snapshot
[Service]
Type=oneshot
ExecStart=/usr/local/bin/vultr-snapshot
Then run it using a timer at /etc/systemd/system/vultr-snapshot.timer
. This timer runs the script at 5:30 AM
every morning.
[Unit]
Description=Create Vultr Snapshot
[Timer]
OnCalendar=*-*-* 05:30:00
RandomizedDelaySec=60
[Install]
WantedBy=timers.target
That’s it. This is a quick way of supplementing your normal backups with automatic Vultr snapshots.
Updated 21 September 2020