Tutorial sull'utilizzo di Workflows con Cloud Run e Cloud Run Functions

Questo tutorial mostra come utilizzare Workflows per collegare una serie di servizi. Se colleghi due servizi HTTP pubblici utilizzando Cloud Run Functions, un'API REST esterna e un servizio Cloud Run privato, puoi creare un'applicazione serverless flessibile.

Obiettivi

In questo tutorial utilizzi Google Cloud CLI per creare un singolo workflow, collegando un servizio alla volta:

  1. Esegui il deployment di due funzioni Cloud Run: la prima funzione genera un numero casuale e lo passa alla seconda funzione che lo moltiplica.
  2. Utilizzerai Workflows per collegare le due funzioni HTTP. Eseguirai il workflow ottenendo un risultato che viene poi passato a un'API esterna.
  3. Utilizzando Workflows, collegherai un'API HTTP esterna che restituisce il log per un determinato numero. Eseguirai il workflow ottenendo un risultato che viene poi passato a un servizio Cloud Run.
  4. Eseguirai il deployment di un servizio Cloud Run che consente solo l'accesso autenticato. Il servizio restituisce il math.floor per un numero specificato.
  5. Utilizzando Workflows, collegherai il servizio Cloud Run, eseguirai l'intero workflow e otterrai il risultato finale.

Il diagramma di seguito mostra sia una panoramica della procedura sia una visualizzazione del workflow finale:

Visualizzazione del workflow

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi utenti di Google Cloud potrebbero avere diritto a una prova senza costi.

Prima di iniziare

I vincoli di sicurezza definiti dalla tua organizzazione potrebbero impedirti di completare i passaggi seguenti. Per informazioni sulla risoluzione dei problemi, vedi Sviluppare applicazioni in un ambiente Google Cloud vincolato.

  1. Accedi al tuo account Google Cloud . Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti senza costi per l'esecuzione, il test e il deployment dei workload.
  2. Installa Google Cloud CLI.

  3. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  4. Per inizializzare gcloud CLI, esegui questo comando:

    gcloud init
  5. Crea o seleziona un Google Cloud progetto.

    Ruoli richiesti per selezionare o creare un progetto

    • Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
    • Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto (roles/resourcemanager.projectCreator), che contiene l'autorizzazione resourcemanager.projects.create. Scopri come concedere i ruoli.
    • Creare un progetto Google Cloud :

      gcloud projects create PROJECT_ID

      Sostituisci PROJECT_ID con un nome per il progetto Google Cloud che stai creando.

    • Seleziona il progetto Google Cloud che hai creato:

      gcloud config set project PROJECT_ID

      Sostituisci PROJECT_ID con il nome del progetto Google Cloud .

  6. Verifica che la fatturazione sia abilitata per il tuo progetto Google Cloud .

  7. Abilita le API Artifact Registry, Cloud Build, Cloud Run, Cloud Run Functions, Cloud Storage e Workflows:

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi disporre del ruolo IAM Amministratore utilizzo dei servizi (roles/serviceusage.serviceUsageAdmin), che include l'autorizzazione serviceusage.services.enable. Scopri come concedere i ruoli.

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com cloudfunctions.googleapis.com storage.googleapis.com workflows.googleapis.com
  8. Installa Google Cloud CLI.

  9. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  10. Per inizializzare gcloud CLI, esegui questo comando:

    gcloud init
  11. Crea o seleziona un Google Cloud progetto.

    Ruoli richiesti per selezionare o creare un progetto

    • Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
    • Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto (roles/resourcemanager.projectCreator), che contiene l'autorizzazione resourcemanager.projects.create. Scopri come concedere i ruoli.
    • Creare un progetto Google Cloud :

      gcloud projects create PROJECT_ID

      Sostituisci PROJECT_ID con un nome per il progetto Google Cloud che stai creando.

    • Seleziona il progetto Google Cloud che hai creato:

      gcloud config set project PROJECT_ID

      Sostituisci PROJECT_ID con il nome del progetto Google Cloud .

  12. Verifica che la fatturazione sia abilitata per il tuo progetto Google Cloud .

  13. Abilita le API Artifact Registry, Cloud Build, Cloud Run, Cloud Run Functions, Cloud Storage e Workflows:

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi disporre del ruolo IAM Amministratore utilizzo dei servizi (roles/serviceusage.serviceUsageAdmin), che include l'autorizzazione serviceusage.services.enable. Scopri come concedere i ruoli.

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com cloudfunctions.googleapis.com storage.googleapis.com workflows.googleapis.com
  14. Aggiorna i componenti di Google Cloud CLI:
    gcloud components update
  15. Se esegui i comandi all'interno di Cloud Shell, l'autenticazione con gcloud CLI è già stata eseguita. In caso contrario, accedi utilizzando il tuo account:
    gcloud auth login
  16. Imposta la località predefinita utilizzata in questo tutorial:
    gcloud config set project PROJECT_ID
    export REGION=REGION
    gcloud config set functions/region ${REGION}
    gcloud config set run/region ${REGION}
    gcloud config set workflows/location ${REGION}

    Sostituisci REGION con la località Workflows supportata che preferisci.

  17. Se hai creato il progetto, ti viene assegnato il ruolo di base Proprietario (roles/owner). Per impostazione predefinita, questo ruolo Identity and Access Management (IAM) include le autorizzazioni necessarie per l'accesso completo alla maggior parte delle risorse Google Cloud e puoi saltare questo passaggio.

    Se non sei il creatore del progetto, le autorizzazioni richieste devono essere concesse al principal appropriato. Ad esempio, un'entità può essere un Account Google (per gli utenti finali) o un account di servizio (per applicazioni e carichi di lavoro di calcolo). Per saperne di più, consulta la pagina Ruoli e autorizzazioni per la destinazione eventi.

    Autorizzazioni obbligatorie

    Per ottenere le autorizzazioni necessarie per completare il tutorial, chiedi all'amministratore di concederti i seguenti ruoli IAM nel progetto:

    Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

    Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

  18. Quando esegui il deployment del workflow, lo associ a un account di servizio specificato. Crea un service account per Workflows:
    export SERVICE_ACCOUNT=workflows-sa
    gcloud iam service-accounts create ${SERVICE_ACCOUNT}
  19. Per impostazione predefinita, tutti i servizi Cloud Run vengono implementati privatamente e possono essere chiamati solo da proprietari del progetto, editor del progetto, amministratori Cloud Run e chiamanti Cloud Run. Per consentire al account di servizio di chiamare un servizio Cloud Run autenticato, concedi il ruolo run.invoker al account di servizio Workflows:
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member "serviceAccount:${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com" \
        --role "roles/run.invoker"

Esegui il deployment della prima funzione Cloud Run

Dopo aver ricevuto una richiesta HTTP, questa funzione HTTP genera un numero casuale compreso tra 1 e 100, quindi restituisce il numero in formato JSON.

  1. Crea una directory denominata randomgen e passa a questa directory:

    mkdir ~/randomgen
    cd ~/randomgen
  2. Crea un file di testo con il nome file main.py contenente il seguente codice Python:

    import functions_framework
    import random
    from flask import jsonify
    
    
    @functions_framework.http
    def randomgen(request):
        randomNum = random.randint(1, 100)
        output = {"random": randomNum}
        return jsonify(output)
  3. Per supportare una dipendenza su Flask per l'elaborazione HTTP, crea un file di testo per il gestore di pacchetti pip. Assegnagli il nome file requirements.txt e aggiungi quanto segue:

    flask>=1.0.2
    functions-framework==3.0.0
  4. Esegui il deployment della funzione con un trigger HTTP e consenti l'accesso non autenticato:

    gcloud functions deploy randomgen-function \
        --gen2 \
        --runtime python310 \
        --entry-point=randomgen \
        --trigger-http \
        --allow-unauthenticated

    Il deployment della funzione potrebbe richiedere alcuni minuti. In alternativa, puoi utilizzare l'interfaccia di Cloud Run Functions nella console Google Cloud per eseguire il deployment della funzione.

  5. Una volta eseguito il deployment della funzione randomgen, puoi confermare la proprietà httpsTrigger.url:

    gcloud functions describe randomgen-function \
        --gen2 \
        --format="value(serviceConfig.uri)"
  6. Salva l'URL. Dovrai aggiungerlo al file di origine del flusso di lavoro negli esercizi successivi.

  7. Puoi provare la funzione con il comando curl seguente:

    curl $(gcloud functions describe randomgen-function \
        --gen2 \
        --format="value(serviceConfig.uri)")

    Viene generato e restituito un numero casuale.

Esegui il deployment della seconda funzione Cloud Run

Dopo aver ricevuto una richiesta HTTP, questa funzione HTTP estrae input dal corpo JSON, lo moltiplica per 2 e restituisce il risultato in formato JSON.

  1. Torna alla home directory:

    cd ~
  2. Crea una directory denominata multiply e passa a questa directory:

    mkdir ~/multiply
    cd ~/multiply
  3. Crea un file di testo con il nome file main.py contenente il seguente codice Python:

    import functions_framework
    from flask import jsonify
    
    
    @functions_framework.http
    def multiply(request):
        request_json = request.get_json()
        output = {"multiplied": 2 * request_json['input']}
        return jsonify(output)
  4. Per supportare una dipendenza su Flask per l'elaborazione HTTP, crea un file di testo per il gestore di pacchetti pip. Assegnagli il nome file requirements.txt e aggiungi quanto segue:

    flask>=1.0.2
    functions-framework==3.0.0
  5. Esegui il deployment della funzione con un trigger HTTP e consenti l'accesso non autenticato:

    gcloud functions deploy multiply-function \
        --gen2 \
        --runtime python310 \
        --entry-point=multiply \
        --trigger-http \
        --allow-unauthenticated

    Il deployment della funzione potrebbe richiedere alcuni minuti. In alternativa, puoi utilizzare l'interfaccia di Cloud Run Functions nella console Google Cloud per eseguire il deployment della funzione.

  6. Una volta eseguito il deployment della funzione multiply, puoi confermare la proprietà httpsTrigger.url:

    gcloud functions describe multiply-function \
        --gen2\
        --format="value(serviceConfig.uri)"
  7. Salva l'URL. Dovrai aggiungerlo al file di origine del flusso di lavoro negli esercizi successivi.

  8. Puoi provare la funzione con il comando curl seguente:

    curl -X POST MULTIPLY_FUNCTION_URL \
        -H "Authorization: Bearer $(gcloud auth print-identity-token)" \
        -H "Content-Type: application/json" \
        -d '{"input": 5}'

    Dovrebbe essere restituito il numero 10.

Collega le due funzioni Cloud Run in un workflow

Un workflow è costituito da una serie di passaggi descritti utilizzando la sintassi di Workflows, che può essere scritta in formato YAML o JSON. Questa è la definizione di workflow. Per una spiegazione dettagliata, consulta la pagina di riferimento per la sintassi.

  1. Torna alla home directory:

    cd ~
  2. Crea un file di testo con il nome file workflow.yaml contenente quanto segue:

    - randomgen_function:
        call: http.get
        args:
            url: RANDOMGEN_FUNCTION_URL
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: MULTIPLY_FUNCTION_URL
            body:
                input: ${randomgen_result.body.random}
        result: multiply_result
    - return_result:
        return: ${multiply_result}
    
    • Sostituisci RANDOMGEN_FUNCTION_URL con l'URL della tua funzione randomgen.
    • Sostituisci MULTIPLY_FUNCTION_URL con l'URL della tua funzione multiply.

    Questo file di origine collega le due funzioni HTTP e restituisce un risultato finale.

  3. Dopo aver creato il workflow, puoi eseguire il deployment, rendendolo pronto per l'esecuzione.

    gcloud workflows deploy WORKFLOW_NAME \
        --source=workflow.yaml \
        --service-account=${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com

    Sostituisci WORKFLOW_NAME con un nome per il workflow.

  4. Esegui il workflow:

    gcloud workflows run WORKFLOW_NAME

    Un'esecuzione è una singola esecuzione della logica contenuta nella definizione di un workflow. Tutte le esecuzioni di un workflow sono indipendenti e la scalabilità rapida di Workflows consente un numero elevato di esecuzioni simultanee.

    Dopo l'esecuzione del workflow, l'output dovrebbe essere simile al seguente:

    result: '{"body":{"multiplied":120},"code":200,"headers":{"Alt-Svc":"h3-29=\":443\";
    ...
    startTime: '2021-05-05T14:17:39.135251700Z'
    state: SUCCEEDED
    ...
    

Collega un servizio REST pubblico nel workflow

Aggiorna il workflow esistente e collega un'API REST pubblica (math.js) che può valutare espressioni matematiche. Ad esempio, curl https://api.mathjs.org/v4/?'expr=log(56)'.

Tieni presente che, dato che hai eseguito il deployment del workflow, puoi modificarlo anche tramite la pagina Workflows della console Google Cloud .

  1. Modifica il file di origine del workflow e sostituiscilo con i contenuti seguenti:

    - randomgen_function:
        call: http.get
        args:
            url: RANDOMGEN_FUNCTION_URL
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: MULTIPLY_FUNCTION_URL
            body:
                input: ${randomgen_result.body.random}
        result: multiply_result
    - log_function:
        call: http.get
        args:
            url: https://api.mathjs.org/v4/
            query:
                expr: ${"log(" + string(multiply_result.body.multiplied) + ")"}
        result: log_result
    - return_result:
        return: ${log_result}
    
    • Sostituisci RANDOMGEN_FUNCTION_URL con l'URL della tua funzione randomgen.
    • Sostituisci MULTIPLY_FUNCTION_URL con l'URL della tua funzione multiply.

    In questo modo, il servizio REST esterno viene collegato alle funzioni Cloud Run, restituendo un risultato finale.

  2. Esegui il deployment del workflow modificato:

    gcloud workflows deploy WORKFLOW_NAME \
        --source=workflow.yaml \
        --service-account=${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com

Esegui il deployment di un servizio Cloud Run

Esegui il deployment di un servizio Cloud Run che, dopo aver ricevuto una richiesta HTTP, estrae input dal corpo JSON, ne calcola math.floor e restituisce il risultato.

  1. Crea una directory denominata floor e passa a questa directory:

    mkdir ~/floor
    cd ~/floor
  2. Crea un file di testo con il nome file app.py contenente il seguente codice Python:

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

  3. Nella stessa directory, crea un Dockerfile con il contenuto seguente:

    # 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

  4. Crea un repository standard di Artifact Registry in cui puoi archiviare l'immagine container Docker:

    gcloud artifacts repositories create REPOSITORY \
        --repository-format=docker \
        --location=${REGION}

    Sostituisci REPOSITORY con un nome univoco per il repository.

  5. Crea l'immagine container:

    export SERVICE_NAME=floor
    gcloud builds submit --tag ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}
  6. Esegui il deployment dell'immagine container in Cloud Run, assicurandoti che accetti solo chiamate autenticate:

    gcloud run deploy ${SERVICE_NAME} \
        --image ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}:latest \
        --no-allow-unauthenticated

Quando vedi l'URL del servizio, significa che il deployment è stato completato. Dovrai specificare questo URL quando aggiorni la definizione del workflow.

Collega il servizio Cloud Run nel workflow

Aggiorna il workflow esistente e specifica l'URL del servizio Cloud Run.

  1. Torna alla home directory:

    cd ~
  2. Modifica il file di origine del workflow e sostituiscilo con i contenuti seguenti:

    - randomgen_function:
        call: http.get
        args:
            url: RANDOMGEN_FUNCTION_URL
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: MULTIPLY_FUNCTION_URL
            body:
                input: ${randomgen_result.body.random}
        result: multiply_result
    - log_function:
        call: http.get
        args:
            url: https://api.mathjs.org/v4/
            query:
                expr: ${"log(" + string(multiply_result.body.multiplied) + ")"}
        result: log_result
    - floor_function:
        call: http.post
        args:
            url: CLOUD_RUN_SERVICE_URL
            auth:
                type: OIDC
            body:
                input: ${log_result.body}
        result: floor_result
    - create_output_map:
        assign:
          - outputMap:
              randomResult: ${randomgen_result}
              multiplyResult: ${multiply_result}
              logResult: ${log_result}
              floorResult: ${floor_result}
    - return_output:
        return: ${outputMap}
    
    • Sostituisci RANDOMGEN_FUNCTION_URL con l'URL della tua funzione randomgen.
    • Sostituisci MULTIPLY_FUNCTION_URL con l'URL della tua funzione multiply.
    • Sostituisci CLOUD_RUN_SERVICE_URL con l'URL del servizio Cloud Run.

    In questo modo viene collegato il servizio Cloud Run nel workflow. Tieni presente che la chiave auth garantisce che un token di autenticazione venga trasmesso nella chiamata al servizio Cloud Run. Per saperne di più, consulta Effettua richieste autenticate da un workflow.

  3. Esegui il deployment del workflow modificato:

    gcloud workflows deploy WORKFLOW_NAME \
        --source=workflow.yaml \
        --service-account=${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com
  4. Esegui il workflow finale:

    gcloud workflows run WORKFLOW_NAME

    L'output dovrebbe essere simile al seguente:

    result: '{"floorResult":{"body":"4","code":200
      ...
      "logResult":{"body":"4.02535169073515","code":200
      ...
      "multiplyResult":{"body":{"multiplied":56},"code":200
      ...
      "randomResult":{"body":{"random":28},"code":200
      ...
    startTime: '2023-11-13T21:22:56.782669001Z'
    state: SUCCEEDED
    

Complimenti! Hai completato il deployment ed eseguito un workflow che collega una serie di servizi.

Per creare workflow più complessi utilizzando espressioni, salti condizionali, codifica o decodifica Base64, workflow secondari e altro ancora, consulta i riferimenti alla sintassi di Workflows e la panoramica della libreria standard.

Esegui la pulizia

Se hai creato un nuovo progetto per questo tutorial, eliminalo. Se hai utilizzato un progetto esistente e vuoi conservarlo senza le modifiche aggiunte in questo tutorial, elimina le risorse create per il tutorial.

Elimina il progetto

Il modo più semplice per eliminare la fatturazione è eliminare il progetto creato per il tutorial.

Per eliminare il progetto:

  1. Nella console Google Cloud , vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona quello che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Elimina le risorse del tutorial

Passaggi successivi