Server-Less! Avviare e fermare istanze Scaleway con una semplice chiamata API!

447
0
Scaleway

Scaleway è tutto ciò che potresti desiderare da un cloud provider: semplice da usare, veloce nella creazione delle tue risorse, ma soprattutto economico. Grazie alla console di Scaleway, possiamo creare, avviare, fermare e riavviare le nostre istanze (VPS) con un semplice click!

Ma se avessimo bisogno di spegnere un server (e riaccenderlo) sempre alla stessa ora, come potremmo fare? Allacciate le cinture e preparatevi a scoprire Scaleway e una delle sue principali (e più nuove!) funzionalità, il Serverless!

TL;DR: Scaricate lo zip che trovate qui, create una funzione serverless su Scaleway, inserite tutte le variabili di ambiente richieste nella chiamata ed effettuate la chiamata via API o tramite CRON.


Andiamo a creare la nostra instanza

Creare una istanza su Scaleway è facilissimo e il processo richiede circa un minuto, e se proprio non mi credi dai un occhiata qui sotto!

Una volta creata la nostra istanza avremo bisogno di appuntarci il campo “Instance ID”, ci servirà più tardi per indicare quale istanza deve essere fermata / avviata.


Scriviamo la nostra serverless function

Se non si fosse ancora capito, andremo ad scrivere una funzione e la pubblicheremo sul servizio Serverless di Scaleway, andiamo quindi a scrivere la nostra funzione riga per riga!

Prima di tutto creiamo il nostro progetto eseguendo i seguenti comandi in una cartella di nostra scelta:

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

Andiamo quindi a definire la base della nostra funzione

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

export {handle};

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

All’interno della funzione handle andiamo innanzitutto a controllare che le variabili d’ambiente siano state impostate correttamente:

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"})}

Controlliamo inoltre che il body della chiamata effettuata contenga i parametri necessari:

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"})}

Infine inizializziamo il nostro 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)

Eseguiamo l’azione richiesta dalla chiamata API

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

E ritorniamo un oggetto dalla nostra funzione per indicare che abbiamo completato l’operazione:

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

Il codice finale sarà quindi il seguente:

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,
    };
}

L’ultima cosa rimasta da fare è creare uno zip del nostro codice, andiamo quindi a creare lo zip dai seguenti file:

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

Potete inoltre trovare uno zip già pronto nel repository del progetto!


Creiamo la nostra funzione serverless

Il prossimo passo è quello di creare un namespace per le nostre funzioni serverless, andiamo quindi a crearlo nel seguente modo

E infine creiamo la nostra funzione


Chiamiamo la nostra funzione

Per poter chiamare la nostra funzione e testare il suo corretto funzionamento ci servirà andare a creare un Access Token, andiamo a crearlo all’interno della nostra funzione utilizzando il seguente bottone

Questo token potrà essere usato come header “X-Auth-Token” della nostra chiamata per autenticarci.

Chiamiamo quindi la nostra funzione nel seguente modo:

curl --location --request POST 'https://scwautostartstopdwzcguy1-startstop.functions.fnc.fr-par.scw.cloud' \
--header 'X-Auth-Token: .....' \
--header 'Content-Type: application/json' \
--data-raw '{
    "action": "poweroff",
    "instance": "e0f8573e-7ae4-44ac-b7f2-8c7634b391b3",
    "region": "fr-par",
    "zone": "fr-par-1"
}'

Attendendo qualche secondo potremo notare che la nostra istanza è stata spenta correttamente!


Scheduliamo l’accensione e lo spegnimento dell’istanza

Arriviamo quindi al dunque, facciamo sì che la nostra istanza si spenga in automatico alle 24:00 ogni giorno e si riaccenda alle 8:00.

Nella pagina “Function Deployment” vi sono delle opzioni avanzate, tra queste possiamo trovare i “Triggers”

Aggiungiamo quindi un trigger per spegnere e riaccendere il nostro server alle ore determinate

E questo è quanto! Il resto lo gestirà Scaleway per noi!

Grazie e alla prossima!

Leave a Reply

Your email address will not be published. Required fields are marked *