Automate Vultr Snapshots Using Bash

Note: This article is out of date. Vultr’s API v1 end of life was announced June 30, 2023
Vultr Snapshot Dashboard
Vultr Snapshot Dashboard

Vultr is a VPS (Virtual Private Server) hosting platform that uses KVM (Kernel–based Virtual Machine) virtualization. Signing into their website over and over again to make a snapshot can be tedious. Let’s automate this process using bash, and systemd timers.

Vultr offers an excellent API (Application Programming 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.

Update: Vultr’s Other low level methods for snapshotting exist. This is merely a nice convenience. used to be free, but the pricing changed to $0.05/GB per month. Keeping this in mind the script below sets an Vultr used to support up to 11 free snapshots. limit of 11 snapshots.

Vultr Snapshot Disclaimer
Vultr Snapshot Disclaimer

First let’s set up the variables that our script will use to create and rotate snapshots.

bash
#!/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. First, we’ll get the current number of snapshots using grep and wc.

bash
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 ".

bash
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 the limit automatically. I already know that the oldest snapshot ID is always 28 fields away from the end of the delimited json output.

bash
LastSnapshotField=$((Fields - 28)

Finish up by using grep and cut to extract the oldest snapshot ID.

bash
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.

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

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

Our full script now looks like this and is complete.

bash
#!/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" || exit 1;
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.

ini
[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.

ini
[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.

2 May 2019 — Written
14 August 2022 — Updated
Thedro Neely — Creator
automate-vultr-snapshots-using-bash.md — Article

More Content

Openring

Web Ring

Comments

References

  1. https://thedroneely.com/git/
  2. https://thedroneely.com/
  3. https://thedroneely.com/posts/
  4. https://thedroneely.com/projects/
  5. https://thedroneely.com/about/
  6. https://thedroneely.com/contact/
  7. https://thedroneely.com/abstracts/
  8. https://ko-fi.com/thedroneely
  9. https://thedroneely.com/tags/bash/
  10. https://thedroneely.com/tags/hosting/
  11. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#isso-thread
  12. https://thedroneely.com/posts/rss.xml
  13. https://thedroneely.com/images/automate-vultr-snapshots-using-bash.png
  14. https://www.vultr.com/
  15. https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29
  16. https://en.wikipedia.org/wiki/Systemd
  17. https://www.vultr.com/api/
  18. https://www.vultr.com/news/Vultr-will-begin-charging-for-snapshot-storage-on-October-1/
  19. https://thedroneely.com/images/vultr-snapshot-notice.png
  20. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#code-block-a732952
  21. https://stedolan.github.io/jq/
  22. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#code-block-5686962
  23. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#code-block-16199c0
  24. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#code-block-b58e610
  25. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#code-block-ec4f8e5
  26. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#code-block-7545efa
  27. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#code-block-8a0277b
  28. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#code-block-5a51da9
  29. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#code-block-e5d0d6f
  30. https://www.thedroneely.com/posts/automate-vultr-snapshots-using-bash.md
  31. https://thedroneely.com/posts/now-dns-pfsense/
  32. https://thedroneely.com/archives/projects/
  33. https://thedroneely.com/abstracts/the-fate-of-empires/
  34. https://git.sr.ht/~sircmpwn/openring
  35. https://drewdevault.com/2022/11/12/In-praise-of-Plan-9.html
  36. https://drewdevault.com/
  37. https://mxb.dev/blog/the-indieweb-for-everyone/
  38. https://mxb.dev/
  39. https://www.taniarascia.com/simplifying-drag-and-drop/
  40. https://www.taniarascia.com/
  41. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#isso-thread
  42. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#code-block-a732952
  43. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#code-block-5686962
  44. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#code-block-16199c0
  45. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#code-block-b58e610
  46. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#code-block-ec4f8e5
  47. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#code-block-7545efa
  48. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#code-block-8a0277b
  49. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#code-block-5a51da9
  50. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#code-block-e5d0d6f
  51. https://thedroneely.com/posts/keeping-up-with-open-source/
  52. https://thedroneely.com/posts/a-few-abstracts/
  53. https://thedroneely.com/posts/website-auditing-tools/
  54. https://thedroneely.com/posts/making-web-pages/
  55. https://thedroneely.com/posts/ssh-port-forwarding/
  56. https://thedroneely.com/posts/tweaking-goaccess-for-analytics/
  57. https://drewdevault.com/2022/09/16/Open-source-matters.html
  58. https://mxb.dev/blog/make-free-stuff/
  59. https://thedroneely.com/sitemap.xml
  60. https://thedroneely.com/index.json
  61. https://thedroneely.com/resume/
  62. https://gitlab.com/tdro
  63. https://github.com/tdro
  64. https://codeberg.org/tdro
  65. https://thedroneely.com/analytics
  66. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash#
  67. https://creativecommons.org/licenses/by-sa/2.0/
  68. https://thedroneely.com/git/thedroneely/thedroneely.com
  69. https://opensource.org/licenses/GPL-3.0
  70. https://www.thedroneely.com/
  71. https://thedroneely.com/posts/automate-vultr-snapshots-using-bash/#