Scaleway is everything you wish you had from a Cloud Provider. Its simple to use, fast in creating resources and cheap. Thanks to its console, we can create, start, stop and restart our instances with a simple click!

But what if we needed to start&stop an instance at a predetermined time? Well buckle up and let’s find out how to do so thanks to Serverless functions!

TL;DR: Download this zip, create a serverless function, set all the env variables requested and setup a cron schedule to call the function.

Let’s create our instance

Creating an instance on Scaleway is super-easy, the process takes about a minute, here is the walkthrough:

Once the instance was created we need to save the Instance ID, we’ll need it later to let the serverless function know with instance to stop/start.

Let’s write our serverless function

npm init
npm i @scaleway/sdk
touch handler.js

Let’s define the base of our function

import {createClient, Instance} from "@scaleway/sdk";

export {handle};

async function handle(event, context) {
    ...
}

In the handle function, let’s check that the env variables are correctly set

if(!process.env.ACCESS_KEY) return {statusCode: 400, body: JSON.stringify({reason: "ACCESS_KEY"})}
if(!process.env.SECRET_KEY) return {statusCode: 400, body: JSON.stringify({reason: "SECRET_KEY"})}
if(!process.env.PROJECT_ID) return {statusCode: 400, body: JSON.stringify({reason: "PROJECT_ID"})}

Let’s also check that the request body is well formatted

const body = JSON.parse(event.body);

// one of "poweron" | "backup" | "stop_in_place" | "poweroff" | "terminate" | "reboot"
if(!body.action) return {statusCode: 400, body: JSON.stringify({reason: "action"})}
if(!body.instance) return {statusCode: 400, body: JSON.stringify({reason: "instance"})}
if(!body.region) return {statusCode: 400, body: JSON.stringify({reason: "region"})}
if(!body.zone) return {statusCode: 400, body: JSON.stringify({reason: "zone"})}

Let’s then initialize the Scaleway SDK

const client = createClient({
   accessKey: process.env.ACCESS_KEY,
   secretKey: process.env.SECRET_KEY,
   defaultProjectId: process.env.PROJECT_ID,
   defaultRegion: body.region,
   defaultZone: body.zone,
})

const api = new Instance.v1.API(client)

And finally, let’s execute our server action and return something back from the function

await api.serverAction({
   action: body.action,
   serverId: body.instance
})

return {
    body: JSON.stringify({
        action: body.action
    }),
    statusCode: 200,
};

The final code will look something like this

import {createClient, Instance} from "@scaleway/sdk";

export {handle};

async function handle(event, context) {
    const body = JSON.parse(event.body);

    if(!body.action) return {statusCode: 400, body: JSON.stringify({reason: "action"})}
    if(!body.instance) return {statusCode: 400, body: JSON.stringify({reason: "instance"})}
    if(!body.region) return {statusCode: 400, body: JSON.stringify({reason: "region"})}
    if(!body.zone) return {statusCode: 400, body: JSON.stringify({reason: "zone"})}
    if(!process.env.ACCESS_KEY) return {statusCode: 400, body: JSON.stringify({reason: "ACCESS_KEY"})}
    if(!process.env.SECRET_KEY) return {statusCode: 400, body: JSON.stringify({reason: "SECRET_KEY"})}
    if(!process.env.PROJECT_ID) return {statusCode: 400, body: JSON.stringify({reason: "PROJECT_ID"})}

    const client = createClient({
        accessKey: process.env.ACCESS_KEY,
        secretKey: process.env.SECRET_KEY,
        defaultProjectId: process.env.PROJECT_ID,
        defaultRegion: body.region,
        defaultZone: body.zone,
    })

    const api = new Instance.v1.API(client)

    await api.serverAction({
        action: body.action,
        serverId: body.instance
    })

    return {
        body: JSON.stringify({
            action: body.action
        }),
        statusCode: 200,
    };
}

Let’s then zip our code the zip should contain the following files:

  • handler.js
  • package.json
  • package-lock.json
  • node_modules

Deploying the Serverless function

The next step is to deploy our function to Scaleway, let’s start by creating the function namespace:

And then let’s create our function:

Schedule the function to stop & start our instance

Lastly we need to actually schedule the function to start and stop our instance at certain times.

In the “Function Deployment” page there is an “Advanced option” section, where we can find “Triggers”

Triggers

Let’s then add a trigger to stop and a trigger to start our instance when we want.

Triggers Example

And that’s it! Leave the rest to Scaleway!