Tutoriel Utiliser des workflows avec Cloud Run et Cloud Run Functions

Ce tutoriel explique comment utiliser Workflows pour associer une série de services. En connectant deux services HTTP publics à l'aide de Cloud Run 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 utiliser la Google Cloud CLI pour créer un workflow unique, en connectant un service à la fois :

  1. Déployez deux fonctions Cloud Run : 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

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Pour obtenir une estimation des coûts en fonction de votre utilisation prévue, utilisez le simulateur de coût.

Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai sans frais.

Avant de commencer

Les contraintes de sécurité définies par votre organisation peuvent vous empêcher d'effectuer les étapes suivantes. Pour en savoir plus sur la résolution de ce problème, consultez 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 sans frais pour exécuter, tester et déployer des charges de travail.
  2. Installez la Google Cloud CLI.

  3. Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.

  4. Pour initialiser la gcloud CLI, exécutez la commande suivante :

    gcloud init
  5. Créez ou sélectionnez un projet Google Cloud .

    Rôles requis pour sélectionner ou créer un projet

    • Sélectionnez un projet : la sélection d'un projet ne nécessite pas de rôle IAM spécifique. Vous pouvez sélectionner n'importe quel projet pour lequel un rôle vous a été attribué.
    • Créer un projet : pour créer un projet, vous devez disposer du rôle Créateur de projet (roles/resourcemanager.projectCreator), qui contient l'autorisation resourcemanager.projects.create. Découvrez comment attribuer des rôles.
    • Créez un projet Google Cloud  :

      gcloud projects create PROJECT_ID

      Remplacez PROJECT_ID par le nom du projet Google Cloud que vous créez.

    • Sélectionnez le projet Google Cloud que vous avez créé :

      gcloud config set project PROJECT_ID

      Remplacez PROJECT_ID par le nom de votre projet Google Cloud .

  6. Vérifiez que la facturation est activée pour votre projet Google Cloud .

  7. Activez les API Artifact Registry, Cloud Build, Cloud Run, Cloud Run Functions, Cloud Storage et Workflows :

    Rôles requis pour activer les API

    Pour activer les API, vous avez besoin du rôle IAM Administrateur Service Usage (roles/serviceusage.serviceUsageAdmin), qui contient l'autorisation serviceusage.services.enable. Découvrez comment attribuer des rôles.

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

  9. Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.

  10. Pour initialiser la gcloud CLI, exécutez la commande suivante :

    gcloud init
  11. Créez ou sélectionnez un projet Google Cloud .

    Rôles requis pour sélectionner ou créer un projet

    • Sélectionnez un projet : la sélection d'un projet ne nécessite pas de rôle IAM spécifique. Vous pouvez sélectionner n'importe quel projet pour lequel un rôle vous a été attribué.
    • Créer un projet : pour créer un projet, vous devez disposer du rôle Créateur de projet (roles/resourcemanager.projectCreator), qui contient l'autorisation resourcemanager.projects.create. Découvrez comment attribuer des rôles.
    • Créez un projet Google Cloud  :

      gcloud projects create PROJECT_ID

      Remplacez PROJECT_ID par le nom du projet Google Cloud que vous créez.

    • Sélectionnez le projet Google Cloud que vous avez créé :

      gcloud config set project PROJECT_ID

      Remplacez PROJECT_ID par le nom de votre projet Google Cloud .

  12. Vérifiez que la facturation est activée pour votre projet Google Cloud .

  13. Activez les API Artifact Registry, Cloud Build, Cloud Run, Cloud Run Functions, Cloud Storage et Workflows :

    Rôles requis pour activer les API

    Pour activer les API, vous avez besoin du rôle IAM Administrateur Service Usage (roles/serviceusage.serviceUsageAdmin), qui contient l'autorisation serviceusage.services.enable. Découvrez comment attribuer des rôles.

    gcloud services enable artifactregistry.googleapis.com cloudbuild.googleapis.com run.googleapis.com cloudfunctions.googleapis.com storage.googleapis.com workflows.googleapis.com
  14. Mettez à jour les composants de la Google Cloud CLI :
    gcloud components update
  15. Si vous exécutez des commandes dans Cloud Shell, vous êtes déjà authentifié auprès de la gcloud CLI. Dans le cas contraire, connectez-vous à l'aide de votre compte :
    gcloud auth login
  16. Définissez l'emplacement par défaut utilisé dans ce tutoriel :
    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}

    Remplacez REGION par l'emplacement Workflows compatible de votre choix.

  17. Si vous êtes le créateur du projet, vous disposez du rôle de base Propriétaire (roles/owner). Par défaut, ce rôle Identity and Access Management (IAM) inclut les autorisations nécessaires pour accéder à la plupart des ressources Google Cloud. Vous pouvez ignorer cette étape.

    Si vous n'êtes pas le créateur du projet, les autorisations requises doivent être accordées au compte principal approprié sur le projet. Par exemple, un compte principal peut être un compte Google (pour les utilisateurs finaux) ou un compte de service (pour les applications et les charges de travail de calcul). Pour en savoir plus, consultez la page Rôles et autorisations pour la destination de votre événement.

    Autorisations requises

    Pour obtenir les autorisations nécessaires pour suivre le tutoriel, demandez à votre administrateur de vous accorder les rôles IAM suivants sur votre projet :

    Pour en savoir plus sur l'attribution de rôles, consultez la page Gérer l'accès aux projets, aux dossiers et aux organisations.

    Vous pouvez également obtenir les autorisations requises via des rôles personnalisés ou d'autres rôles prédéfinis.

  18. Lorsque vous déployez votre workflow, vous l'associez à un compte de service spécifié. Créez un compte de service à utiliser avec Workflows :
    export SERVICE_ACCOUNT=workflows-sa
    gcloud iam service-accounts create ${SERVICE_ACCOUNT}
  19. Tous les services Cloud Run sont déployés en mode privé par défaut et ne peuvent être appelés que par les propriétaires de projet, les éditeurs de projet, les administrateurs Cloud Run et les demandeurs Cloud Run. Pour permettre au compte de service d'appeler un service Cloud Run authentifié, accordez le rôle run.invoker au compte de service Workflows :
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member "serviceAccount:${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com" \
        --role "roles/run.invoker"

Déployer la première fonction Cloud Run 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 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. Pour permettre une dépendance sur Flask pour le traitement HTTP, créez un fichier texte pour le gestionnaire de paquets pip. Attribuez-lui le nom de fichier requirements.txt et ajoutez les éléments suivants :

    flask>=1.0.2
    functions-framework==3.0.0
  4. Déployez la fonction avec un déclencheur HTTP et autorisez les accès non authentifiés :

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

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

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

    gcloud functions describe randomgen-function \
        --gen2 \
        --format="value(serviceConfig.uri)"
  6. Enregistrez l'URL. Vous devrez l'ajouter à votre fichier source Workflows dans les exercices suivants.

  7. Vous pouvez essayer la fonction à l'aide de la commande curl suivante :

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

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

Déployer la deuxième fonction Cloud Run 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. Revenez à votre répertoire d'accueil :

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

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

    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. Pour permettre une dépendance sur Flask pour le traitement HTTP, créez un fichier texte pour le gestionnaire de paquets pip. Attribuez-lui le nom de fichier requirements.txt et ajoutez les éléments suivants :

    flask>=1.0.2
    functions-framework==3.0.0
  5. Déployez la fonction avec un déclencheur HTTP et autorisez les accès non authentifiés :

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

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

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

    gcloud functions describe multiply-function \
        --gen2\
        --format="value(serviceConfig.uri)"
  7. Enregistrez l'URL. Vous devrez l'ajouter à votre fichier source Workflows dans les exercices suivants.

  8. Vous pouvez essayer la fonction à l'aide de la commande curl suivante :

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

    Le nombre 10 doit être renvoyé.

Connecter les deux fonctions Cloud Run 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 portant le nom de fichier workflow.yaml avec le contenu suivant :

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

    Ce fichier source associe les deux fonctions HTTP et renvoie 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 \
        --service-account=${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com

    Remplacez WORKFLOW_NAME par le nom que vous souhaitez donner à votre 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

Mettez à jour votre workflow existant et connectez une API REST publique (math.js) capable d'évaluer des expressions mathématiques. Exemple : curl https://api.mathjs.org/v4/?'expr=log(56)'.

Notez que dans la mesure où vous avez déployé votre workflow, vous pouvez également le modifier sur la page Workflows de la console Google Cloud .

  1. Modifiez le fichier source de votre workflow et remplacez-le par le contenu suivant :

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

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

  2. Déployez le workflow modifié :

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

Déployer un service Cloud Run

Déployez un service Cloud Run qui, après avoir reçu une requête HTTP, extrait le paramètre 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 un dépôt standard Artifact Registry dans lequel vous pouvez stocker votre image de conteneur Docker :

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

    Remplacez REPOSITORY par un nom unique pour le dépôt.

  5. Créez l'image de conteneur :

    export SERVICE_NAME=floor
    gcloud builds submit --tag ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}
  6. 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 ${REGION}-docker.pkg.dev/PROJECT_ID/REPOSITORY/${SERVICE_NAME}:latest \
        --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

Mettez à jour votre workflow existant et spécifiez l'URL du service Cloud Run.

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

    cd ~
  2. Modifiez le fichier source de votre workflow et remplacez-le par le contenu suivant :

    - 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}
    
    • Remplacez RANDOMGEN_FUNCTION_URL par l'URL de votre fonction randomgen.
    • Remplacez MULTIPLY_FUNCTION_URL par l'URL de votre fonction multiply.
    • 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 plus d'informations, consultez la page Effectuer des requêtes authentifiées à partir d'un workflow.

  3. Déployez le workflow modifié :

    gcloud workflows deploy WORKFLOW_NAME \
        --source=workflow.yaml \
        --service-account=${SERVICE_ACCOUNT}@PROJECT_ID.iam.gserviceaccount.com
  4. Exécutez le workflow final :

    gcloud workflows run WORKFLOW_NAME

    La sortie doit ressembler à ceci :

    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
    

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 ou du décodage en Base64, de sous-workflows, etc.

Effectuer un nettoyage

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 apportées lors 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 la console Google Cloud , 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

Étapes suivantes