Learn how to use the IBM Cloud CLI and Terraform for instance snapshots.
A snapshot is a point-in-time copy of volume. When a volume snapshot is requested, the volume contents at a single moment are identified. Writes performed while the snapshot is being persisted will not affect the snapshot contents. The snapshot of the boot volume will capture all the blocks required to provision future instances.
New instances can be provisioned from a boot snapshot or a new data volume can be restored from a snapshot. This blog describes how to create the instance, take snapshots of the volumes and then create a new instance from the snapshots. The basic steps are captured in this diagram:
It also describes some Linux commands for handling partitions (fdisk), file systems (mkfs), mounting (mount) and device unique identifiers (blkid).
Using automation to avoid repetitive steps
Going through this process for one instance with one volume, one time, is okay to start, but you may want to automate the steps so you can take the snapshots automatically. You can then adjust these scripts to fit into your CI/CD pipeline, backup schedule, automated testing environment, etc.
Once you go through the steps manually, it becomes clear that all those steps in the IBM Cloud console can be automated with their command line counterparts. Equipped with IBM Cloud CLI and Terraform, I decided to write a set of shell scripts and Terraform templates to prove it.
The files can be found in the Git repository. Note that you will find more VPC examples in other folders in this repository. These examples are companions to our VPC tutorials.
The scripts under
vpc-snapshot/ do the work:
- Use Terraform to create the VPC, network resources, data volumes and instance.
- Create snapshots of the boot volume and the data volumes.
- Restore snapshots into a new instance with associated new data volumes.
- Test the restored instance.
- Delete the restored instance, restored volumes, snapshots, etc.
- Use Terraform destroy to delete the original instance, data volumes and network resources.
Running the automation scripts
To make it easier to understand what happens, I created several scripts mapping to the high-level steps:
Instructions on how to run the scripts can be found in the folder’s README. You will need the right permissions to work with VPC. Try it in the IBM Cloud Shell or verify the prerequisites on your development computer: IBM Cloud CLI, Terraform, IBM Cloud Provider for Terraform and JQ. You will also need an SSH key, which you should be familiar with if you are working with virtual servers.
Once you have configured your environment with the local.env file, you can start running the scripts
./010-terraform-create.sh, etc. If you change the values of
local.env, start from scratch with 000. Below I’ll explain what is happening step by step.
Step by step
After executing the
010-terraform-create.sh, navigate to Virtual server instances for VPC in the IBM Cloud console and find your instance. I kept the default PREFIX=snaps and got the instance “snaps,” and it had the data volumes snaps0 and snaps1:
Navigate through the “snaps0” volume name and notice the volume and Snapshots panel:
You will see that it is empty — no snapshots yet. The script,
ssbackup.sh, takes a snapshot of the boot and data volumes but requires an instance id as a parameter. The
020-snapshot-backup.sh script finds the instance id from the Terraform output before invoking
020-snapshot-backup.sh, navigate back to the volumes in the IBM Cloud console and observe the snapshot created for each volume. This was my snaps0:
It is possible to initialize a new instance from these snapshots. The script,
ssrestore.sh, does the heavy lifting but it takes a lot of parameters:
Execute the 030-snapshot-restore.sh script. While it is executing, open the script to see how these parameters are obtained from the Terraform output. After the script completes, navigate to Virtual server instances for VPC, then to the “snaps-restore” instance and check out the volumes created. Take note of the IP address of the restored instance:
040-snapshot-test.sh to verify that the restored instance has the same contents as the original instance and volumes. The next section has the details. A shell script will be run on the restored instance; the output looks like this:
You can clean up in two steps, but you may want to first take a look at the next section and learn more about Linux volumes. Clean up the restored instance, volumes, snapshots, etc. with
080-snapshot-cleanup.sh. Then clean up the Terraform created resources with
Linux commands for partitions (fdisk), file systems (mkfs), mounting (mount) and device unique identifiers (blkid)
This section describes the details of partitioning disks, making file systems, etc. Study, skim or skip depending on your needs.
The initial instance configuration was completed in the
010-terraform-create.sh step in a cloud-init user-data script. Check out the user_data in the
terraform/main.tf instance configuration:
The contents of user_data is expanded from the
/dev/disk/by-id directory contains the volumes identified by their volume attachment ids. It is not possible to predict these ids, so any disks that have not been previously partitioned are initialized.
Followthe instructions in the documentation for Using your block storage data volume (CLI). The following steps are automated.
The fdisk command creates a new, primary partition. The rest of the parameters are defaulted. The sed script provides a self-documenting way to capture the inputs to the fdisk interactive command. The results are a new partition ending in “1” that is about as big as the disk. One of my volumes was
/dev/vde. The resulting primary partition was
The mkfs command makes a file system on the partition. This is required before the device can be mounted. The command was
mkfs -t ext4 /dev/vde1. A unique ID, UUID, for the device is also available after the file system is created and is displayed with the command
blkid -sUUID -ovalue /dev/vde1.
One can mount
/dev/vde1, but it is also possible to mount the disk by the UUID. After the mount instructions are put into the /etc/fstab, it is possible to mount just using the directory name, which also happens to match the UUID. For me, this was:
Finally, some data is put into a version.txt file.
If you ssh to the instance created by Terraform, you can see the /etc/fstab:
While on the instance, you can see the results of the cloud-init execution. Look in this file for the cloud-init steps. I’m a vi user:
Check out the version.txt files:
All entries in
/etc/fstab will be mounted during instance initialization. This is why the instance restored from snapshots is correctly initialized. This allows the
040-snapshot-test.sh script to verify that the volumes are working.
For me, the restored instance (snaps-restore
/dev/vdc1) did not have the same volume devices as the original (snaps
/etc/fstab is referencing them by UUID to avoid any problems:
You can ssh to the restored instance. The output of
./030-snapshot-restore.sh had the IP address:
While you are ssh’d to snaps-restore, check out the data volumes. For example:
Remove the snapshots and instance that was restored from the snapshot. Destroy the Terraform resources: