Informazioni su questo codelab
1. Introduzione
Puoi utilizzare Workflows per creare flussi di lavoro serverless che collegano una serie di attività serverless in un ordine definito da te. Puoi combinare la potenza delle API di Google Cloud, i prodotti serverless come Cloud Functions e Cloud Run e le chiamate ad API esterne per creare applicazioni serverless flessibili.
I flussi di lavoro non richiedono alcuna gestione dell'infrastruttura e offrono scalabilità senza interruzioni in base alla domanda, incluso lo scale down fino a zero. Grazie al modello di prezzi a consumo, paghi solo in base al tempo di esecuzione.
In questo codelab imparerai a collegare vari servizi Google Cloud e API HTTP esterne con Workflows. Nello specifico, collegherai due servizi Cloud Functions pubblici, un servizio Cloud Run privato e un'API HTTP pubblica esterna in un flusso di lavoro.
Obiettivi didattici
- Nozioni di base su Workflows.
- Come collegare Cloud Functions pubbliche con i flussi di lavoro.
- Come collegare i servizi Cloud Run privati con i flussi di lavoro.
- Come collegare API HTTP esterne a Workflows.
2. Configurazione e requisiti
Configurazione dell'ambiente a tuo ritmo
- Accedi alla console Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o G Suite, devi crearne uno.
Ricorda l'ID progetto, un nome univoco per tutti i progetti Google Cloud (il nome sopra indicato è già stato utilizzato e non funzionerà per te, scusa). In seguito in questo codelab verrà chiamato PROJECT_ID
.
- Successivamente, dovrai abilitare la fatturazione in Cloud Console per poter utilizzare le risorse Google Cloud.
L'esecuzione di questo codelab non dovrebbe costare molto, se non del tutto. Assicurati di seguire le istruzioni nella sezione "Pulizia" che ti consigliano come arrestare le risorse per evitare addebiti al termine di questo tutorial. I nuovi utenti di Google Cloud sono idonei al programma Prova senza costi di 300$.
Avvia Cloud Shell
Sebbene Google Cloud possa essere utilizzato da remoto dal tuo laptop, in questo codelab utilizzerai Google Cloud Shell, un ambiente a riga di comando in esecuzione nel cloud.
Nella console Google Cloud, fai clic sull'icona di Cloud Shell nella barra degli strumenti in alto a destra:
Dovrebbe richiedere solo pochi istanti per eseguire il provisioning e connettersi all'ambiente. Al termine, dovresti vedere qualcosa di simile a questo:
Questa macchina virtuale contiene tutti gli strumenti di sviluppo di cui avrai bisogno. Offre una home directory permanente da 5 GB e viene eseguita su Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione di rete. Tutto il lavoro in questo lab può essere svolto semplicemente con un browser.
3. Panoramica di Workflows
Nozioni di base
Un flusso di lavoro è costituito da una serie di passaggi descritti utilizzando la sintassi basata su YAML di Workflows. Questa è la definizione del flusso di lavoro. Per una spiegazione dettagliata della sintassi YAML di Workflows, consulta la pagina Riferimento alla sintassi.
Quando viene creato, un workflow viene implementato e reso pronto per l'esecuzione. Un'esecuzione è una singola esecuzione della logica contenuta nella definizione di un flusso di lavoro. Tutte le esecuzioni dei flussi di lavoro sono indipendenti e il prodotto supporta un numero elevato di esecuzioni simultanee.
Attivare i servizi
In questo codelab, collegherai Cloud Functions e i servizi Cloud Run con i flussi di lavoro. Utilizzerai anche Cloud Build e Cloud Storage durante la creazione dei servizi.
Attiva tutti i servizi necessari:
gcloud services enable \ cloudfunctions.googleapis.com \ run.googleapis.com \ workflows.googleapis.com \ cloudbuild.googleapis.com \ storage.googleapis.com
Nel passaggio successivo, collegherai due funzioni Cloud in un flusso di lavoro.
4. Esegui il deployment della prima funzione Cloud
La prima funzione è un generatore di numeri casuali in Python.
Crea e vai a una directory per il codice della funzione:
mkdir ~/randomgen cd ~/randomgen
Crea un file main.py
nella directory con i seguenti contenuti:
import random, json from flask import jsonify def randomgen(request): randomNum = random.randint(1,100) output = {"random":randomNum} return jsonify(output)
Quando riceve una richiesta HTTP, questa funzione genera un numero casuale compreso tra 1 e 100 e restituisce al chiamante il valore in formato JSON.
La funzione si basa su Flask per l'elaborazione HTTP e dobbiamo aggiungerla come dipendenza. Le dipendenze in Python sono gestite con pip ed espresse in un file di metadati denominato requirements.txt
.
Crea un file requirements.txt
nella stessa directory con il seguente contenuto:
flask>=1.0.2
Esegui il deployment della funzione con un trigger HTTP e con le richieste non autenticate consentite con questo comando:
gcloud functions deploy randomgen \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
Una volta eseguita il deployment della funzione, puoi visualizzare l'URL della funzione nella proprietà url
visualizzata nella console o con il comando gcloud functions describe
.
Puoi anche visitare l'URL della funzione con il seguente comando curl
:
curl $(gcloud functions describe randomgen --format='value(url)')
La funzione è pronta per il flusso di lavoro.
5. Esegui il deployment della seconda funzione Cloud
La seconda funzione è un moltiplicatore. Moltiplica l'input ricevuto per 2.
Crea e vai a una directory per il codice della funzione:
mkdir ~/multiply cd ~/multiply
Crea un file main.py
nella directory con i seguenti contenuti:
import random, json from flask import jsonify def multiply(request): request_json = request.get_json() output = {"multiplied":2*request_json['input']} return jsonify(output)
Quando riceve una richiesta HTTP, questa funzione estrae input
dal corpo JSON, lo moltiplica per 2 e lo restituisce al chiamante in formato JSON.
Crea lo stesso file requirements.txt
nella stessa directory con i seguenti contenuti:
flask>=1.0.2
Esegui il deployment della funzione con un trigger HTTP e con le richieste non autenticate consentite con questo comando:
gcloud functions deploy multiply \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
Una volta eseguita la funzione, puoi anche visitare l'URL della funzione con il seguente comando curl
:
curl $(gcloud functions describe multiply --format='value(url)') \ -X POST \ -H "content-type: application/json" \ -d '{"input": 5}'
La funzione è pronta per il flusso di lavoro.
6. Collegare due funzioni Cloud
Nel primo flusso di lavoro, collega le due funzioni.
Crea un file workflow.yaml
con i seguenti contenuti.
- randomgenFunction: call: http.get args: url: https://<region>-<project-id>.cloudfunctions.net/randomgen result: randomgenResult - multiplyFunction: call: http.post args: url: https://<region>-<project-id>.cloudfunctions.net/multiply body: input: ${randomgenResult.body.random} result: multiplyResult - returnResult: return: ${multiplyResult}
In questo flusso di lavoro, ottieni un numero casuale dalla prima funzione e lo passi alla seconda. Il risultato è il numero casuale moltiplicato.
Esegui il deployment del primo flusso di lavoro:
gcloud workflows deploy workflow --source=workflow.yaml
Esegui il primo flusso di lavoro:
gcloud workflows execute workflow
Una volta eseguito il flusso di lavoro, puoi visualizzare il risultato passando l'ID esecuzione indicato nel passaggio precedente:
gcloud workflows executions describe <your-execution-id> --workflow workflow
L'output includerà result
e state
:
result: '{"body":{"multiplied":108},"code":200 ... } ... state: SUCCEEDED
7. Collegare un'API HTTP esterna
Successivamente, collegherai math.js come servizio esterno nel flusso di lavoro.
In math.js, puoi valutare espressioni matematiche come questa:
curl https://api.mathjs.org/v4/?'expr=log(56)'
Questa volta utilizzerai Cloud Console per aggiornare il nostro flusso di lavoro. Individua Workflows
nella console Google Cloud:
Individua il tuo flusso di lavoro e fai clic sulla scheda Definition
:
Modifica la definizione del flusso di lavoro e includi una chiamata a math.js
.
- randomgenFunction: call: http.get args: url: https://<region>-<project-id>.cloudfunctions.net/randomgen result: randomgenResult - multiplyFunction: call: http.post args: url: https://<region>-<project-id>.cloudfunctions.net/multiply body: input: ${randomgenResult.body.random} result: multiplyResult - logFunction: call: http.get args: url: https://api.mathjs.org/v4/ query: expr: ${"log(" + string(multiplyResult.body.multiplied) + ")"} result: logResult - returnResult: return: ${logResult}
Ora il workflow inserisce l'output della funzione moltiplica in una chiamata della funzione di log in math.js
.
L'interfaccia utente ti guiderà nella modifica e nel deployment del flusso di lavoro. Una volta eseguito il deployment, fai clic su Execute
per eseguire il flusso di lavoro. Vedrai i dettagli dell'esecuzione:
Nota il codice di stato 200
e un body
con l'output della funzione di log.
Hai appena integrato un servizio esterno nel nostro flusso di lavoro, fantastico.
8. Esegui il deployment di un servizio Cloud Run
Nell'ultima parte, completa il flusso di lavoro con una chiamata a un servizio Cloud Run privato. Ciò significa che il flusso di lavoro deve essere autenticato per chiamare il servizio Cloud Run.
Il servizio Cloud Run restituisce il math.floor
del numero passato.
Crea e vai a una directory per il codice del servizio:
mkdir ~/floor cd ~/floor
Crea un file app.py
nella directory con i seguenti contenuti:
import json import logging import os import math from flask import Flask, request app = Flask(__name__) @app.route('/', methods=['POST']) def handle_post(): content = json.loads(request.data) input = float(content['input']) return f"{math.floor(input)}", 200 if __name__ != '__main__': # Redirect Flask logs to Gunicorn logs gunicorn_logger = logging.getLogger('gunicorn.error') app.logger.handlers = gunicorn_logger.handlers app.logger.setLevel(gunicorn_logger.level) app.logger.info('Service started...') else: app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))
Cloud Run esegue il deployment di container, quindi devi avere un Dockerfile
e il container deve essere associato alle variabili di ambiente 0.0.0.0
e PORT
, da qui il codice riportato sopra.
Quando riceve una richiesta HTTP, questa funzione estrae input
dal corpo JSON, chiama math.floor e restituisce il risultato al chiamante.
Nella stessa directory, crea il seguente Dockerfile
:
# Use an official lightweight Python image. # https://hub.docker.com/_/python FROM python:3.7-slim # Install production dependencies. RUN pip install Flask gunicorn # Copy local code to the container image. WORKDIR /app COPY . . # Run the web service on container startup. Here we use the gunicorn # webserver, with one worker process and 8 threads. # For environments with multiple CPU cores, increase the number of workers # to be equal to the cores available. CMD exec gunicorn --bind 0.0.0.0:8080 --workers 1 --threads 8 app:app
Crea il contenitore:
export SERVICE_NAME=floor gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}
Una volta creato il container, esegui il deployment in Cloud Run. Nota il flag no-allow-unauthenticated
. In questo modo, il servizio accetta solo chiamate autenticate:
gcloud run deploy ${SERVICE_NAME} \ --image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \ --platform managed \ --no-allow-unauthenticated
Una volta eseguito il deployment, il servizio è pronto per il flusso di lavoro.
9. Connetti il servizio Cloud Run
Prima di poter configurare Workflows per chiamare il servizio Cloud Run privato, devi creare un account di servizio da utilizzare per Workflows:
export SERVICE_ACCOUNT=workflows-sa gcloud iam service-accounts create ${SERVICE_ACCOUNT}
Concedi il ruolo run.invoker
all'account di servizio. In questo modo, l'account di servizio potrà chiamare i servizi Cloud Run autenticati:
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \ --member "serviceAccount:${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \ --role "roles/run.invoker"
Aggiorna la definizione del flusso di lavoro in workflow.yaml
in modo da includere il servizio Cloud Run. Tieni presente che includi anche il campo auth
per assicurarti che Workflows trasmetta il token di autenticazione nelle chiamate al servizio Cloud Run:
- randomgenFunction: call: http.get args: url: https://<region>-<project-id>.cloudfunctions.net/randomgen result: randomgenResult - multiplyFunction: call: http.post args: url: https://<region>-<project-id>.cloudfunctions.net/multiply body: input: ${randomgenResult.body.random} result: multiplyResult - logFunction: call: http.get args: url: https://api.mathjs.org/v4/ query: expr: ${"log(" + string(multiplyResult.body.multiplied) + ")"} result: logResult - floorFunction: call: http.post args: url: https://floor-<random-hash>.run.app auth: type: OIDC body: input: ${logResult.body} result: floorResult - returnResult: return: ${floorResult}
Aggiorna il flusso di lavoro. Questa volta passando l'account di servizio:
gcloud workflows deploy workflow \ --source=workflow.yaml \ --service-account=${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com
Esegui il flusso di lavoro:
gcloud workflows execute workflow
Dopo pochi secondi, puoi dare un'occhiata all'esecuzione del flusso di lavoro per vedere il risultato:
gcloud workflows executions describe <your-execution-id> --workflow workflow
L'output includerà un numero intero result
e state
:
result: '{"body":"5","code":200 ... } ... state: SUCCEEDED
10. Complimenti!
Complimenti per aver completato il codelab.
Argomenti trattati
- Nozioni di base su Workflows.
- Come collegare Cloud Functions pubbliche con i flussi di lavoro.
- Come collegare i servizi Cloud Run privati con i flussi di lavoro.
- Come collegare API HTTP esterne a Workflows.