Starting a Google Compute instance with Python

Question:

I am trying to start a Google Compute instance with the Google API Python Client Library. This is so that a cheap instance (running on a single core) can periodically start and stop a more expensive instance (with many cores) periodically, to keep costs down.

I have successfully installed the different components and run Google’s example script create_instance.py (which creates an instances, runs a startup script, and deletes the instance). Inspecting the PyDoc reference for the Compute Engine API, and cross-referencing how the other instances() functions work in the create_instance.py example, I would expect the start instance command to be:

python compute.instances().start(project=*, zone=*, instance=*).execute()

The above command gives me the error “An expression was expected after ‘(‘. at line:1 char:34” – this is the first parenthesis.

a. What have I done wrong?

b. Is using the Google API with Python a good way to start instances from other instances, programmatically?

Asked By: fifthace

||

Answers:

  1. Generally I would expect you would need to import the api library with an import statement or perhaps a runtime flag (-m somemodule?). Running a line of python directly from the command line is usually not the best way to proceed. Instead Google provides the gcloud command line tool.

  2. An authentication/login function is usually called before sending the API actual commands. On a Google VM, this can be either an id/private key or a blank id/key if the VM is specifically authorized to call the API or act as a specific account. This authorization can be set up from the compute engine web control panel when creating a Google VM the first time. On an external VM, it will need an id/private key to supply to the Google API. So, a one liner in python probably won’t work as it is missing this step.

  3. The compute.instances().start() function takes required parameters to start a specific instance that has stopped. That means:

    • the VM instance has been created previously
    • the VM instance is in the stopped state
    • the instance to be restarted is identified by a specific project id, a (geo) zone, and an instance name that is supplied in the call to start

From Google Cloud Python Documentation

start(project=, zone=, instance=*) Starts an instance that was
stopped using the instances().stop method. For more
information, see Restart an instance.

Args: project: string, Project ID for this request. (required)
zone: string, The name of the zone for this request. (required)
instance: string, Name of the instance resource to start. (required)

Answered By: Paul

Below is the code needed to start a compute engine instance

from googleapiclient import discovery

service = discovery.build('compute', 'v1')
print('VM Instance starting')

# Project ID for this request.
project = 'project_name' 

# The name of the zone for this request.
zone = 'zone_value'  

# Name of the instance resource to start.
instance = 'instance_name'

request = service.instances().start(project=project, zone=zone, instance=instance)
response = request.execute()

print('VM Instance started')

This is the code I used for starting my VM instance from a cloud function.

An important thing to note here is that this can only start an instance if the instance is in stopped state, which suits my requirements perfectly.

Answered By: user570778

I used the code shared by @user570778, and for me it worked fine.

`from googleapiclient import discovery

service = discovery.build(‘compute’, ‘v1’)
print(‘VM Instance starting’)

Project ID for this request.

project = ‘project_name’

The name of the zone for this request.

zone = ‘zone_value’

Name of the instance resource to start.

instance = ‘instance_name’

request = service.instances().start(project=project, zone=zone, instance=instance)
response = request.execute()

print(‘VM Instance started’)
`
I’m wondering, is it possible to start multiples instance in the same function?

Answered By: Joaze Oliveira
from google.cloud import compute_v1

project = ""
zone = ""
instance_client = compute_v1.InstancesClient.from_service_account_file("ServiceAccount.json")
instance_list = instance_client.list(project=project, zone=zone)
for instance in instance_list:
    print(instance.name)
    instance_client.start(project=project, zone=zone, instance=instance.name)

Requires iam role Compute Admin
Source available here: https://github.com/googleapis/python-compute

Answered By: Ryan Sneyd