Tutoriel Utiliser les workflows avec Cloud Run et Cloud Functions

Ce tutoriel explique comment utiliser Workflows pour associer une série de services. En connectant deux services HTTP publics (à l'aide de Cloud Functions), une API REST externe et un service Cloud Run privé, vous pouvez créer une application sans serveur flexible.

Objectifs

Dans ce tutoriel, vous allez créer un workflow unique, en connectant un service à la fois :

  1. Déployez deux services Cloud Functions : la première fonction génère un nombre aléatoire, puis le transmet à la deuxième fonction qui le multiplie.
  2. À l'aide de Workflows, connectez les deux fonctions HTTP. Exécutez le workflow afin de renvoyer un résultat qui est ensuite transmis à une API externe.
  3. À l'aide de Workflows, connectez une API HTTP externe qui renvoie log pour un nombre donné. Exécutez le workflow afin de renvoyer un résultat qui est ensuite transmis à un service Cloud Run.
  4. Déployez un service Cloud Run qui n'autorise que les accès authentifiés. Le service renvoie le paramètre math.floor pour un nombre donné.
  5. À l'aide de Workflows, connectez le service Cloud Run, exécutez l'intégralité du workflow, puis renvoyez un résultat final.

Le schéma suivant montre une vue d'ensemble du processus ainsi qu'une visualisation du workflow final :

Visualisation des workflows

Coûts

Ce tutoriel utilise les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

Certaines étapes de ce document risquent de ne pas fonctionner correctement si votre organisation applique des contraintes à votre environnement Google Cloud. Dans ce cas, vous ne pourrez peut-être pas effectuer des tâches telles que la création d'adresses IP publiques ou de clés de compte de service. Si vous effectuez une requête qui renvoie une erreur concernant des contraintes, consultez la section Développer des applications dans un environnement Google Cloud limité.

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Assurez-vous que la facturation est activée pour votre projet Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

  4. Activer les API Cloud Build, Cloud Functions, Cloud Run, Cloud Storage, Container Registry, Workflows .

    Activer les API

  5. Installez et initialisez le SDK Cloud.
  6. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  7. Assurez-vous que la facturation est activée pour votre projet Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

  8. Activer les API Cloud Build, Cloud Functions, Cloud Run, Cloud Storage, Container Registry, Workflows .

    Activer les API

  9. Installez et initialisez le SDK Cloud.
  10. Mettez à jour les composants gcloud :
    gcloud components update
  11. Connectez-vous à votre compte :
    gcloud auth login
  12. Créez un compte de service à utiliser avec Workflows :

    export SERVICE_ACCOUNT=workflows-sa
    gcloud iam service-accounts create ${SERVICE_ACCOUNT}
    

  13. Pour permettre au compte de service d'appeler des services Cloud Run authentifiés, accordez le rôle run.invoker au compte de service Workflows :

    gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
        --member "serviceAccount:${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
        --role "roles/run.invoker"
    

  14. Définissez l'emplacement par défaut utilisé dans ce tutoriel :
    gcloud config set project PROJECT_ID
    export REGION=REGION
    gcloud config set run/region ${REGION}
    gcloud config set workflows/location ${REGION}
    

    Remplacez :

    • PROJECT_ID par l'ID de votre projet Google Cloud
    • REGION par l'emplacement Workflows compatible de votre choix

Déployer le premier service Cloud Functions

Après avoir reçu une requête HTTP, cette fonction HTTP génère un nombre aléatoire compris entre 1 et 100, puis renvoie le nombre au format JSON.

  1. Créez un répertoire nommé randomgen et remplacez les éléments par ce qui suit :

    mkdir ~/randomgen
    cd ~/randomgen
    
  2. Créez un fichier texte avec le nom de fichier main.py contenant le code Python suivant :

    import random, json
    from flask import jsonify
    
    def randomgen(request):
        randomNum = random.randint(1,100)
        output = {"random":randomNum}
        return jsonify(output)
  3. Pour être compatible avec Flask pour le traitement HTTP, créez un fichier texte pour le gestionnaire de packages pip. Attribuez-lui le nom de fichier requirements.txt et ajoutez les éléments suivants :

    flask>=1.0.2
    
  4. Déployer la fonction avec un déclencheur HTTP et autoriser les accès non authentifiés :

    gcloud functions deploy randomgen \
    --runtime python37 \
    --trigger-http \
    --allow-unauthenticated
    

    Le déploiement de la fonction peut prendre quelques minutes. Vous pouvez également utiliser l'interface Cloud Functions dans Cloud Console pour déployer la fonction.

  5. Une fois la fonction déployée, vous pouvez confirmer la propriété httpsTrigger.url :

    gcloud functions describe randomgen
    
  6. Vous pouvez essayer la fonction à l'aide de la commande curl suivante :

    curl $(gcloud functions describe randomgen --format='value(httpsTrigger.url)')
    

    Un nombre est généré de manière aléatoire et renvoyé.

Déployer le second service Cloud Functions

Après avoir reçu une requête HTTP, cette fonction HTTP extrait le input du corps JSON, le multiplie par 2 et renvoie le résultat au format JSON.

  1. Créez un répertoire nommé multiply et remplacez les éléments par ce qui suit :

    mkdir ~/multiply
    cd ~/multiply
    
  2. Créez un fichier texte avec le nom de fichier main.py contenant le code Python suivant :

    import random, json
    from flask import jsonify
    
    def multiply(request):
        request_json = request.get_json()
        output = {"multiplied":2*request_json['input']}
        return jsonify(output)
  3. Pour être compatible avec Flask pour le traitement HTTP, créez un fichier texte pour le gestionnaire de packages pip. Attribuez-lui le nom de fichier requirements.txt et ajoutez les éléments suivants :

    flask>=1.0.2
    
  4. Déployer la fonction avec un déclencheur HTTP et autoriser les accès non authentifiés :

    gcloud functions deploy multiply \
    --runtime python37 \
    --trigger-http \
    --allow-unauthenticated
    

    Le déploiement de la fonction peut prendre quelques minutes. Vous pouvez également utiliser l'interface Cloud Functions dans Cloud Console pour déployer la fonction.

  5. Une fois la fonction déployée, vous pouvez confirmer la propriété httpsTrigger.url :

    gcloud functions describe multiply
    
  6. Vous pouvez essayer la fonction à l'aide de la commande curl suivante :

    curl $(gcloud functions describe multiply --format='value(httpsTrigger.url)') \
    -X POST \
    -H "content-type: application/json" \
    -d '{"input": 5}'
    

    Le nombre 10 doit être renvoyé.

Connecter les deux services Cloud Functions dans un workflow

Un workflow est constitué d'une série d'étapes décrites à l'aide de la syntaxe Workflows, qui peut être écrite au format YAML ou JSON. Il s'agit de la définition du workflow. Pour une explication détaillée, consultez la page de documentation de référence sur la syntaxe.

  1. Revenez à votre répertoire d'accueil :

    cd ~
    
  2. Créez un fichier texte avec le nom de fichier workflow.yaml avec le contenu suivant :

    - randomgen_function:
        call: http.get
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/randomgen
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/multiply
            body:
                input: ${randomgen_result.body.random}
        result: multiply_result
    - return_result:
        return: ${multiply_result}
    

    Cela a pour effet d'associer les deux fonctions HTTP et de renvoyer un résultat final.

  3. Une fois le workflow créé, vous pouvez le déployer afin qu'il soit prêt à être exécuté.

    gcloud workflows deploy WORKFLOW_NAME --source=workflow.yaml
    

    Remplacez WORKFLOW_NAME par le nom du workflow.

  4. Exécutez le workflow :

    gcloud workflows run WORKFLOW_NAME
    

    Il s'agit d'une exécution unique de la logique contenue dans la définition d'un workflow. Toutes les exécutions de workflow sont indépendantes, et le scaling rapide de Workflows permet d'effectuer un grand nombre d'exécutions simultanées.

    Une fois le workflow exécuté, le résultat devrait ressembler à ceci :

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

Connecter un service REST public dans le workflow

À l'aide de Google Cloud Console, mettez à jour le workflow existant et connectez une API REST publique (math.js) permettant d'évaluer des expressions mathématiques. par exemple, curl https://api.mathjs.org/v4/?'expr=log(56)'.

  1. Ouvrez la page "Workflows" de Google Cloud Console :
    Accéder à la page "Workflows"

  2. Sélectionnez le nom du workflow que vous souhaitez mettre à jour.

  3. Pour modifier la source du workflow, cliquez sur  Modifier, puis sur Suivant.

  4. Remplacez le code source dans l'éditeur de workflow par le contenu suivant :

    - randomgen_function:
        call: http.get
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/randomgen
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/multiply
            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}
    

    Cela a pour effet d'associer le service REST externe aux services Cloud Functions et de renvoyer un résultat final.

  5. Cliquez sur Déployer.

Déployer un service Cloud Run

Déployez un service Cloud Run qui, après avoir reçu une requête HTTP, extrait la valeur input du corps JSON, calcule sa valeur math.floor et renvoie le résultat.

  1. Créez un répertoire nommé floor et remplacez les éléments par ce qui suit :

    mkdir ~/floor
    cd ~/floor
    
  2. Créez un fichier texte avec le nom de fichier app.py contenant le code Python suivant :

    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. Dans le même répertoire, créez un Dockerfile avec le contenu suivant :

    # 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. Créez l'image du conteneur :

    export SERVICE_NAME=floor
    gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}
    
  5. Déployez l'image de conteneur dans Cloud Run, en veillant à ce qu'elle n'accepte que les appels authentifiés :

    gcloud run deploy ${SERVICE_NAME} \
    --image gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME} \
    --platform managed \
    --no-allow-unauthenticated
    

Lorsque l'URL du service s'affiche, cela signifie que le déploiement est terminé. Vous devrez spécifier cette URL lors de la mise à jour de la définition du workflow.

Connecter le service Cloud Run dans le workflow

  1. Ouvrez la page "Workflows" de Google Cloud Console :
    Accéder à la page "Workflows"

  2. Sélectionnez le nom du workflow que vous souhaitez mettre à jour.

  3. Pour modifier la source du workflow, cliquez sur  Modifier, puis sur Suivant.

  4. Remplacez le code source dans l'éditeur de workflow par le contenu suivant :

    - randomgen_function:
        call: http.get
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/randomgen
        result: randomgen_result
    - multiply_function:
        call: http.post
        args:
            url: https://REGION-PROJECT_ID.cloudfunctions.net/multiply
            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
    - return_result:
        return: ${floor_result}
    

    Remplacez CLOUD_RUN_SERVICE_URL par l'URL de votre service Cloud Run.

    Cela permet de connecter le service Cloud Run dans le workflow. Notez que la clé auth garantit qu'un jeton d'authentification est transmis dans l'appel au service Cloud Run. Pour en savoir plus, consultez la section sur l'authentification des workflows.

  5. Cliquez sur Déployer.

Exécuter le workflow final

  1. Mettez à jour le workflow en transmettant ce qui suit dans le compte de service :

    cd ~
    gcloud workflows deploy workflow \
    --source=workflow.yaml \
    --service-account=${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com
    
  2. Exécutez le workflow :

    gcloud workflows run WORKFLOW_NAME
    

    La sortie doit ressembler à ceci :

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

Félicitations ! Vous avez déployé et exécuté un workflow qui connecte une série de services.

Consultez la documentation de référence sur la syntaxe de workflows et la page Présentation de la bibliothèque standard pour créer des workflows plus complexes à l'aide d'expressions, de sauts conditionnels, de l'encodage/décodage en Base64, de sous-workflows, etc.

Nettoyer

Si vous avez créé un projet pour ce tutoriel, supprimez-le. Si vous avez utilisé un projet existant et que vous souhaitez le conserver sans les modifications du présent tutoriel, supprimez les ressources créées pour ce tutoriel.

Supprimer le projet

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

Pour supprimer le projet :

  1. Dans Cloud Console, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Supprimer les ressources du tutoriel

  1. Supprimez le service Cloud Run que vous avez déployé dans ce tutoriel :

    gcloud run services delete SERVICE_NAME

    SERVICE_NAME est le nom de service que vous avez choisi.

    Vous pouvez également supprimer des services Cloud Run à partir de Google Cloud Console.

  2. Supprimez les configurations gcloud par défaut que vous avez ajoutées lors de la configuration du tutoriel.

     gcloud config unset run/region
     gcloud config unset workflows/location
     gcloud config unset project
    

  3. Supprimez le workflow créé dans ce tutoriel :

    gcloud workflows delete WORKFLOW_NAME
    
  4. Supprimez l'image de conteneur nommée gcr.io/PROJECT_ID/SERVICE_NAME de Container Registry.

Étape suivante