Automate Vultr Snapshots Using Bash

Vultr Snapshot Dashboard
Vultr Snapshot Dashboard

Vultr is a VPS (Virtual Private Server) hosting platform that uses KVM (Kernel-based Virtual Machine) Disclosure: Link contains a referral. It is rather tedious to log into their website over and over again to make a snapshot. 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 snapshots are currently free, but pricing may be subject to This disclaimer is shown below the Vultr Snapshot Dashboard. As of writing, Vultr appears to support up to 11 free snapshots out of the box, so we will implement a script with this is mind.

Vultr Snapshot Disclaimer
Vultr Snapshot Disclaimer

First let’s set up the variables that our script will use.

#!/bin/bash
Key="YourAPIKEY"
SnapshotLimit=11
SnapshotCount=$(/usr/bin/curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep -o SNAPSHOTID | wc -l)
Fields=$(/usr/bin/curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep -o '"' | wc -l)
LastSnapshotField=$((Fields - 24))
LastSnapshotID=$(/usr/bin/curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep '"' | cut -d '"' -f $LastSnapshotField)

We are using mostly command substitutions with curl here. 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.

Let’s go through some of this. We will get the current number of snapshots using grep and wc.

SnapshotCount=$(/usr/bin/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=$(/usr/bin/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 very last snapshot. This will allow us to destroy that snapshot when we reach Vultr’s limit automatically.

I already know that the last 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 very last snapshot ID.

LastSnapshotID=$(/usr/bin/curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep '"' | cut -d '"' -f $LastSnapshotField)

Once done, we execute a simple if statement to destroy that snapshot when necessary. Nothing fancy.

if [ "$SnapshotCount" -eq "$SnapshotLimit" ]
  then
    /usr/bin/curl -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/destroy --data "SNAPSHOTID=$LastSnapshotID";
fi

/usr/bin/curl -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/create --data 'SUBID=YourSUBID';

Our full script now looks like this;

#!/bin/bash

Key="YourAPIKEY"
SnapshotLimit=11
SnapshotCount=$(/usr/bin/curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep -o SNAPSHOTID | wc -l)
Fields=$(/usr/bin/curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep -o '"' | wc -l)
LastSnapshotField=$((Fields - 24))
LastSnapshotID=$(/usr/bin/curl -s -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/list | grep '"' | cut -d '"' -f $LastSnapshotField)

if [ "$SnapshotCount" -eq "$SnapshotLimit" ]
  then
    /usr/bin/curl -H "API-Key: $Key" https://api.vultr.com/v1/snapshot/destroy --data "SNAPSHOTID=$LastSnapshotID";
fi

/usr/bin/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

[Install]
WantedBy=timers.target

That’s it. This is a quick way of supplementing your normal backups with automatic Vultr snapshots.

Updated 2 May 2019