Preemptible Virtual Machines (PVMs) are Google’s Low Cost VMs that are supplied on demand to users who are willing to sacrifice availability for cost. According to the documentation, PVMs can be reclaimed by Google at any time, and can only run for a maximum of 24 hours before being preempted, however while they are running they can cost 30% of the actual price in most cases, which is a huge win! If you’re like me, you want to minimize costs but also ensure that your VM can recover quickly from preemption.

In this article we use Cloud Scheduler to poll a cloud function that checks the status of a PVM in question. If the VM is in the stopped state, we use cloud functions to resurrect it and keep it going. (Click here for the code)

1. Architecting the Solution

1.1 Creating a Preemptible VM

In the Compute Engine section of GCP console, let’s create a simple VM, we shall give it the name lazarus-batch-workload , 😉 (Figure 1)

Figure 1: Creating the Virtual Machine

In the management section, under the availability policy column we can enable preemtibility. Let’s click create to start the VM (Figure 2).

Figure 2: Enabling Preemptiblity

1.2 Create a Service Account

We need a service account (SA) that cloud functions uses to act on behalf of us (the user) to manage access to the VM. Without it, Cloud Functions wont be authorized to do so. In my example I call the SA compute-admin-sa , I give it a description to better identify its role (Figure 3).

Figure 3: Creating the Service Account

1.2.2 Apply Service Account Permission.

In this step we define permissions our service account will have. I give it Compute Admin role which grants it full control over Compute Engine (Figure 4). In your case, you can choose to be more granular with the permissions. After this step, we create the cloud function.

Figure 4: Applying Roles to Service Account

1.3 Creating the Cloud Function

In the Cloud Function section of GCP console (Figure 5), let’s create a Cloud Function.

Figure 5: Creating the Cloud Function

We can give it a name lazarus-awakener (you can pick a more formal name 😅), as well as a good description. We can leave most of the other sections as is. Let’s ensure we select HTTP trigger, this will give us a URL cloud scheduler will hit to trigger the cloud function. Copy the URL to your clipboard or elsewhere, as we shall need it in the next section.

Figure 6: Configuring the Cloud Function

In the runtime selection select Go 1.x and in the code section, let’s copy in the Go code from this GitHub link (too long to paste here, I have commented the code for your convenience). Lastly we can select the service account we just created compute-admin-sa and click create.

1.4 Setting up the Cloud Scheduler.

Lastly, we can create the scheduler that will periodically poll the cloud function to check if the lazarus-batch-workload VM has stopped or terminated.

Figure 7: Creating the Cloud Scheduler Job

Let’s navigate to Cloud Scheduler in the console (Figure 7), let’s give it a name and description. Let’s input the cron. In our case we want to ensure the cloud function is polled every 10 minutes (you can play with this crontab). Let’s also select HTTP trigger and paste in the URL provided by the cloud function. Finally click create.

2. Testing the Solution