Using App Engine to start a Compute Engine VM
Sometimes we don’t want (or need) a compute engine instance running 24hs every day but we need to run task/s periodically. To solve this we can have an app engine task runing using cron service to start the VM instance. Once the VM has started, it can have a startup script that runs the actual task it was needed for and then stops the machine.
VM Start
We want to run a scheduled task once a day (at midnight let’s say) in order to start. I will call the task url /vm/start but it could be whatever you want. Here is the cron file:
cron.yaml
cron:
- description: run instance
url: /vm/start
schedule: every day 00:00
Endpoint handler
Once set that we need to hadle the url call on the appengine app. I’m using Flask framework but it should work with whatever you’re using:
@app.route('/vm/start')
def start_vm():
credentials = AppAssertionCredentials(scope='https://www.googleapis.com/auth/compute')
http = credentials.authorize(httplib2.Http(memcache))
compute = discovery.build('compute', 'v1', http=http)
# Start the VM!
result = compute.instances().start(instance=INSTANCE_NAME, zone=INSTANCE_ZONE, project=PROJECT).execute() logging.debug(result)
return json.dumps(result, indent=4)
First you need to get credentials. As we are calling from inside GCP we can use app engine service accounts (you can learn more here). Then we use google api client to build and use compute engine api. And with that is just as simple as calling the instance start method.
Configuring access
If you try to run the code as is, you will find a Encountered 403 Forbidden with reason “accessNotConfigured” message on the logs. We need to enable Compute Engine API for our project. To do that go to API Manager > Library > Compute Engine API and click ENABLE
Also when creating the VM, we need to set up access rights to cloud API’s
This is what’s required to start the VM. Once deployed a simple call to http://your-project.appspot.com/vm/start will start the virtual machine.
VM Stop
Now the startup script should run some process to do the work you want to do on this instance and then as the last line should do something like this:
gcloud compute instances stop vm-instance --zone "YOUR-VM-ZONE"
This needs to be configured when creating the VM:
If you want to see all the code for this example you can check this github repo.