This tutorial shows how to use Cloud Scheduler and Cloud Run functions to automatically start and stop Compute Engine instances on a regular schedule using resource labels .
Objectives
- Write and deploy a set of functions with Cloud Run functions that start and stop Compute Engine instances.
 - Create a set of jobs with Cloud Scheduler that schedule instances
with a 
devresource label to run 09:00-17:00, Monday-Friday to match typical business hours. 
Costs
In this document, you use the following billable components of Google Cloud:
- Cloud Scheduler
 - Cloud Run functions
 - Pub/Sub
 - Compute Engine
 
To generate a cost estimate based on your projected usage, use the pricing calculator .
Before you begin
- Set up your environment for Cloud Scheduler.
 -  
Enable the Cloud Run functions, Pub/Sub, and Compute Engine APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles . 
Application architecture
This solution includes the following Google Cloud components:
- Compute Engine instance we want to run on a schedule.
 - Cloud Run functions to start and stop the instance we want to schedule.
 - Pub/Sub messages sent and received for each start and stop event.
 - Cloud Scheduler jobs to make calls on a set schedule to start and stop the instance.
 

Location requirements
Some components are only supported in certain regions:
- Compute Engine instance: supported in any region listed in Regions and zones .
 - Cloud Run functions: supported in the regions listed in Locations .
 - Pub/Sub messages: supported globally as Pub/Sub is a global service.
 - Cloud Scheduler jobs with Pub/Sub targets: supported in any Google Cloud location .
 
Why not HTTP instead of Pub/Sub?
You may want to simplify this architecture by using Cloud Run functions HTTP Triggers instead of Pub/Sub Triggers .
This tutorial uses Pub/Sub as the Cloud Run functions trigger because this method was formerly more secure than using HTTP. However, HTTP is also a valid choice and can now be secured by requiring authentication.
To learn about securing Cloud Run functions, see the Cloud Run functions security overview . For a comparison between HTTP and Pub/Sub triggers, see the Cloud Run functions triggers documentation.
Set up the Compute Engine instance
Console
- Go to the VM instancespage in the Google Cloud console.
Go to the VM instances page . - Click Create instance.
 - Set the Nameto 
dev-instance. - Under Labels, click Add labels.
 - Click Add label.
 - Enter 
envfor Keyanddevfor Value. - For Regionselect us-west1.
 - For Zoneselect us-west1-b.
 - Click Save.
 - Click Createat the bottom of the page.
 
gcloud
gcloud compute instances create dev-instance \
    --network default \
    --zone us-west1-b \
    --labels=env=dev 
Deploy functions triggered by Pub/Sub through Cloud Run functions
Create and deploy the functions
Console
Create the start function.
- Go to the Cloud Run functionspage in the Google Cloud console.
Go to the Cloud Run functions page . - Click Create Function.
 - For Environment, select 1st gen.
 - Set Function nameto 
startInstancePubSub. - Leave Regionat its default value.
 - For Trigger type, select Cloud Pub/Sub.
 - For Select a Cloud Pub/Sub topic, click Create a topic.
 - A Create topicdialog should appear. 
- Under Topic ID, enter 
start-instance-event. - Click Createto finish the dialog.
 
 - Under Topic ID, enter 
 - Click Saveat the bottom of the Triggerbox.
 - Click Nextat the bottom of the page.
 - For Runtime, select Node.js 16or later.
 - For Entry point, enter 
startInstancePubSub. - On the left side of the code editor, select index.js.
 -  
Replace the starter code with the following code:
 -  
On the left side of the code editor, select the package.json.
 -  
Replace the starter code with the following code:
 -  
Click Deployat the bottom of the page.
 
Create the stop function.
- You should be on the Cloud Run functionspage in the Google Cloud console.
 - Click Create Function.
 - For Environment, select 1st gen.
 - Set Function nameto 
stopInstancePubSub. - Leave Regionat its default value.
 - For Trigger type, select Cloud Pub/Sub.
 - For Select a Cloud Pub/Sub topic, click Create a topic.
 - A Create topicdialog should appear. 
- Under Topic ID, enter 
stop-instance-event. - Click Createto finish the dialog.
 
 - Under Topic ID, enter 
 - Click Saveat the bottom of the Triggerbox.
 - Click Nextat the bottom of the page.
 - For Runtime, select Node.js 16or later.
 - For Entry point, enter 
stopInstancePubSub. - On the left side of the code editor, select index.js.
 -  
Replace the starter code with the following code:
 -  
On the left side of the code editor, select the package.json.
 -  
Replace the starter code with the following code:
 -  
Click Deployat the bottom of the page.
 
gcloud
Create the Pub/Sub topics.
gcloud pubsub topics create start-instance-event
gcloud pubsub topics create stop-instance-event
Get the code
-  
Download the code.
git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
Alternatively, you can download the sample as a zip file and extract it.
 -  
Go to the correct directory.
cd nodejs-docs-samples/functions/scheduleinstance/
 
Create the start and stop functions.
You should be in the nodejs-docs-samples/functions/scheduleinstance/ 
directory.
gcloud functions deploy startInstancePubSub \ --trigger-topic start-instance-event \ --runtime nodejs18 \ --allow-unauthenticated
gcloud functions deploy stopInstancePubSub \ --trigger-topic stop-instance-event \ --runtime nodejs18 \ --allow-unauthenticated
(Optional) Verify the functions work
Console
Stop the instance
- Go to the Cloud Run functionspage in the Google Cloud console.
Go to the Cloud Run functions page . - Click on the function named 
stopInstancePubSub. - You should see a number of tabs: General, Trigger, Source, Permissions, and Testing. Click on the Testingtab.
 -  
For Triggering evententer the following:
{"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsICJsYWJlbCI6ImVudj1kZXYifQo="}-  
This is simply the base64-encoded string for
{"zone":"us-west1-b", "label":"env=dev"} -  
If you want to encode your own string, feel free to use any online base64 encoding tool .
 
 -  
 -  
Click the Test the functionbutton.
 -  
When it is done running, you should see
Successfully stopped instance dev-instanceprinted under Output. It may take up to 60 seconds to finish running.-  
If instead you see
error: 'Error: function failed to load.', just wait 10 seconds or so for the function to finish deploying and try again. -  
If instead you see
error: 'Error: function execution attempt timed out.', just move on to the next step to see if the instance is just taking a long time to shut down. -  
If instead it finishes running, but shows nothing, it probably also just timed out. Just move on to the next step to see if the instance is just taking a long time to shut down.
 
 -  
 -  
Go to the VM instancespage in the Google Cloud console.
Go to the VM instances page . -  
Verify that the instance named
dev-instancehas a grey square next to its name, indicating that it has stopped. It may take up to 30 seconds to finish shutting down.- If it doesn't seem to be finishing, try clicking Refreshat the top of the page.
 
 
Start the instance
- Go to the Cloud Run functionspage in the Google Cloud console.
Go to the Cloud Run functions page . - Click on the function named 
startInstancePubSub. - You should see a number of tabs: General, Trigger, Source, Permissions, and Testing. Click on the Testingtab.
 -  
For Triggering evententer the following:
{"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsICJsYWJlbCI6ImVudj1kZXYifQo="}- Again, this is simply the base64-encoded string for 
{"zone":"us-west1-b", "label":"env=dev"} 
 - Again, this is simply the base64-encoded string for 
 -  
Click the Test the functionbutton.
 -  
When it is done running, you should see
Successfully started instance dev-instanceprinted under Output. -  
Go to the VM instancespage in the Google Cloud console.
Go to the VM instances page . -  
Verify that the instance named
dev-instancehas a green checkmark next to its name, indicating that it is running. It may take up to 30 seconds to finish starting up. 
gcloud
Stop the instance
-  
Call the function to stop the instance.
gcloud functions call stopInstancePubSub \ --data '{"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsICJsYWJlbCI6ImVudj1kZXYifQo="}'-  
This is simply the base64-encoded string for
{"zone":"us-west1-b", "label":"env=dev"} -  
If you want to encode your own string, feel free to use any tool. Here's an example using the
base64command line tool:echo '{"zone":"us-west1-b", "label":"env=dev"}' | base64eyJ6b25lIjoidXMtd2VzdDEtYiIsICJsYWJlbCI6ImVudj1kZXYifQo=
 
When the function has finished you should see the following:
result: Successfully stopped instance dev-instance
It may take up to 60 seconds to finish running.
-  
If instead you get the error:
error: 'Error: function failed to load.`
Just wait 10 seconds or so for the function to finish deploying and try again.
 -  
If instead you get the error:
error: `Error: function execution attempt timed out.`
Move on to the next step to see if the instance is just taking a long time to shut down.
 -  
If instead you get no result, the function probably just timed out. Move on to the next step to see if the instance is just taking a long time to shut down.
 
 -  
 -  
Check that the instance has a status of
TERMINATED. It may take up to 30 seconds to finish shutting down.gcloud compute instances describe dev-instance \ --zone us-west1-b \ | grep statusstatus: TERMINATED
 
Start the instance
-  
Call the function to start the instance.
gcloud functions call startInstancePubSub \ --data '{"data":"eyJ6b25lIjoidXMtd2VzdDEtYiIsICJsYWJlbCI6ImVudj1kZXYifQo="}'- Again, this is simply the base64-encoded string for 
{"zone":"us-west1-b", "label":"env=dev"} 
When the function has finished you should see the following:
result: Successfully started instance dev-instance
 - Again, this is simply the base64-encoded string for 
 -  
Check that the instance has a status of
RUNNING. It may take up to 30 seconds to finish starting up.gcloud compute instances describe dev-instance \ --zone us-west1-b \ | grep statusstatus: RUNNING
 
Set up the Cloud Scheduler jobs to call Pub/Sub
Create the jobs
Console
Create the start job.
- Go to the Cloud Schedulerpage in the Google Cloud console.
Go to the Cloud Scheduler page . - Click Create a job.
 - Leave the default region.
 - Set the Nameto 
startup-dev-instances. - For Frequency, enter 
0 9 * * 1-5.- This will execute at 9:00 every day Mon-Fri.
 
 - For Timezone, select your desired country and timezone. This
example will use 
United StatesandLos Angeles. - Click Continue.
 - For Target type, select 
Pub/Sub. - Select 
start-instance-eventfrom the topic dropdown. - For Message, enter the following: 
{"zone":"us-west1-b","label":"env=dev"} - Click Create.
 
Create the stop job.
- You should be on the Cloud Schedulerpage in the Google Cloud console.
 - Click Create Job.
 - Leave the default region and click Nextat the bottom of the page.
 - Set the Nameto 
shutdown-dev-instances. - For Frequency, enter 
0 17 * * 1-5.- This will execute at 17:00 every day Mon-Fri.
 
 - For Timezone, select your desired country and timezone. This
example will use 
United StatesandLos Angeles. - Click Continue.
 - For Target type, select 
Pub/Sub. - Select 
stop-instance-eventfrom the topic dropdown.. - For Message, enter the following: 
{"zone":"us-west1-b","label":"env=dev"} - Click Create.
 
gcloud
Create the start job.
gcloud scheduler jobs create pubsub startup-dev-instances \
    --schedule '0 9 * * 1-5' \
    --topic start-instance-event \
    --message-body '{"zone":"us-west1-b", "label":"env=dev"}' \
    --time-zone 'America/Los_Angeles' \
    --location us-central1 
Create the stop job.
gcloud scheduler jobs create pubsub shutdown-dev-instances \
    --schedule '0 17 * * 1-5' \
    --topic stop-instance-event \
    --message-body '{"zone":"us-west1-b", "label":"env=dev"}' \
    --time-zone 'America/Los_Angeles' \
    --location us-central1 
(Optional) Verify the jobs work
Console
Stop the instance
- Go to the Cloud Schedulerpage in the Google Cloud console.
Go to the Cloud Scheduler page . - For the job named 
shutdown-dev-instances, click the Run nowbutton on the far right side of the page. - Go to the VM instancespage in the Google Cloud console.
Go to the VM instances page . - Verify that the instance named 
dev-instancehas a grey square next to its name, indicating that it has stopped. It may take up to 30 seconds for it to finish shutting down. 
Start the instance
- Go to the Cloud Schedulerpage in the Google Cloud console.
Go to the Cloud Scheduler page . - For the job named 
startup-dev-instances, click the Run nowbutton on the far right side of the page. - Go to the VM instancespage in the Google Cloud console.
Go to the VM instances page . - Verify that the instance named 
dev-instancehas a green checkmark next to its name, indicating that it is running. It may take up to 30 seconds for it to finish starting up. 
gcloud
Stop the instance
-  
Run the scheduler job to stop the instance.
gcloud beta scheduler jobs run shutdown-dev-instances
 -  
Check that the instance has a status of
TERMINATED. It may take up to 30 seconds for it to finish shutting down.gcloud compute instances describe dev-instance \ --zone us-west1-b \ | grep statusstatus: TERMINATED
 
Start the instance
-  
Run the scheduler job to start the instance.
gcloud beta scheduler jobs run startup-dev-instances
 -  
Check that the instance has a status of
RUNNING. It may take up to 30 seconds to finish starting up.gcloud compute instances describe dev-instance \ --zone us-west1-b \ | grep statusstatus: RUNNING
 
Clean up
After you finish the tutorial, you can clean up the resources that you created so that they stop using quota and incurring charges. The following sections describe how to delete or turn off these resources.
Delete the Cloud Scheduler jobs
-  
Go to the Cloud Schedulerpage in the Google Cloud console.
 -  
Click the checkboxes next to your jobs.
 -  
Click the Deletebutton at the top of the page and confirm your delete.
 
Delete the Pub/Sub topics
-  
Go to the Pub/Subpage in the Google Cloud console.
 -  
Click the checkboxes next to your topics.
 -  
Click Deleteat the top of the page and confirm your delete.
 
Delete the functions deployed through Cloud Run functions
-  
Go to the Cloud Run functionspage in the Google Cloud console.
 -  
Click the checkboxes next to your functions.
 -  
Click the Deletebutton at the top of the page and confirm your delete.
 
Delete the Compute Engine instance
To delete a Compute Engine instance:
- In the Google Cloud console, go to the VM instances page.
 - Select the checkbox for the instance that you want to delete.
 - To delete the instance, click More actions , click Delete , and then follow the instructions.
 
Delete the project
The easiest way to eliminate billing is to delete the project that you created for the tutorial.
To delete the project:
- In the Google Cloud console, go to the Manage resources page.
 - In the project list, select the project that you want to delete, and then click Delete .
 - In the dialog, type the project ID, and then click Shut down to delete the project.
 
What's next
- Explore reference architectures, diagrams, and best practices about Google Cloud. Take a look at our Cloud Architecture Center .
 

