À propos de cet atelier de programmation
1. Introduction
Vous pouvez utiliser Workflows pour créer des workflows sans serveur qui associent une série de tâches sans serveur dans l'ordre que vous définissez. Vous pouvez combiner la puissance des API Google Cloud, des produits sans serveur tels que Cloud Functions et Cloud Run, et des appels d'API externes pour créer des applications sans serveur flexibles.
Workflows ne nécessite aucune gestion d'infrastructure et s'adapte facilement à la demande, y compris le scaling réduit à zéro. Avec son modèle de paiement à l'utilisation, vous ne payez que pour la durée d'exécution.
Dans cet atelier de programmation, vous allez apprendre à connecter différents services Google Cloud et API HTTP externes à Workflows. Plus précisément, vous allez connecter deux services Cloud Functions publics, un service Cloud Run privé et une API HTTP publique externe dans un workflow.
Points abordés
- Principes de base des workflows
- Connecter des fonctions Cloud publiques à des workflows
- Connecter des services Cloud Run privés à Workflows
- Connecter des API HTTP externes à Workflows
2. Préparation
Configuration de l'environnement d'auto-formation
- Connectez-vous à Cloud Console, puis créez un projet ou réutilisez un projet existant. (Si vous n'avez pas encore de compte Gmail ou G Suite, vous devez en créer un.)
Mémorisez l'ID du projet. Il s'agit d'un nom unique permettant de différencier chaque projet Google Cloud (le nom ci-dessus est déjà pris ; vous devez en trouver un autre). Il sera désigné par le nom PROJECT_ID
tout au long de cet atelier de programmation.
- Vous devez ensuite activer la facturation dans Cloud Console pour pouvoir utiliser les ressources Google Cloud.
L'exécution de cet atelier de programmation est très peu coûteuse, voire gratuite. Veillez à suivre les instructions de la section "Nettoyer" qui indique comment désactiver les ressources afin d'éviter les frais une fois ce tutoriel terminé. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai gratuit pour bénéficier d'un crédit de 300 $.
Démarrer Cloud Shell
Bien que Google Cloud puisse être utilisé à distance depuis votre ordinateur portable, nous allons nous servir de Google Cloud Shell pour cet atelier de programmation, un environnement de ligne de commande exécuté dans le cloud.
Depuis la console GCP, cliquez sur l'icône Cloud Shell de la barre d'outils située dans l'angle supérieur droit :
Le provisionnement et la connexion à l'environnement prennent quelques instants seulement. Une fois l'opération terminée, le résultat devrait ressembler à ceci :
Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Vous pouvez réaliser toutes les activités de cet atelier dans un simple navigateur.
3. Présentation de Workflows
Principes de base
Un workflow se compose d'une série d'étapes décrites à l'aide de la syntaxe Workflows basée sur YAML. Il s'agit de la définition du workflow. Pour obtenir une explication détaillée de la syntaxe YAML Workflows, consultez la page Documentation de référence sur la syntaxe.
Lorsqu'un workflow est créé, il est déployé, ce qui le rend prêt à être exécuté. 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 produit prend en charge un grand nombre d'exécutions simultanées.
Activer les services
Dans cet atelier de programmation, vous allez connecter des fonctions Cloud et des services Cloud Run à des workflows. Vous utiliserez également Cloud Build et Cloud Storage lors de la création de services.
Activez tous les services nécessaires :
gcloud services enable \ cloudfunctions.googleapis.com \ run.googleapis.com \ workflows.googleapis.com \ cloudbuild.googleapis.com \ storage.googleapis.com
À l'étape suivante, vous allez connecter deux fonctions Cloud dans un workflow.
4. Déployer la première fonction Cloud
La première fonction est un générateur de nombres aléatoires en Python.
Créez un répertoire pour le code de la fonction et accédez-y:
mkdir ~/randomgen cd ~/randomgen
Créez un fichier main.py
dans le répertoire avec le contenu suivant:
import random, json from flask import jsonify def randomgen(request): randomNum = random.randint(1,100) output = {"random":randomNum} return jsonify(output)
Lorsqu'elle reçoit une requête HTTP, cette fonction génère un nombre aléatoire compris entre 1 et 100, puis renvoie le résultat au format JSON à l'appelant.
La fonction s'appuie sur Flask pour le traitement HTTP. Nous devons l'ajouter en tant que dépendance. Dans Python, les dépendances sont gérées avec pip et exprimées dans un fichier de métadonnées appelé requirements.txt
.
Créez un fichier requirements.txt
dans le même répertoire avec le contenu suivant:
flask>=1.0.2
Déployez la fonction avec un déclencheur HTTP et autorisez les requêtes non authentifiées avec cette commande:
gcloud functions deploy randomgen \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
Une fois la fonction déployée, vous pouvez voir l'URL de la fonction sous la propriété url
affichée dans la console ou affichée avec la commande gcloud functions describe
.
Vous pouvez également accéder à l'URL de la fonction à l'aide de la commande curl
suivante:
curl $(gcloud functions describe randomgen --format='value(url)')
La fonction est prête pour le workflow.
5. Déployer la deuxième fonction Cloud
La deuxième fonction est un multiplicateur. Il multiplie l'entrée reçue par 2.
Créez un répertoire pour le code de la fonction et accédez-y:
mkdir ~/multiply cd ~/multiply
Créez un fichier main.py
dans le répertoire avec le contenu 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)
Lorsqu'elle reçoit une requête HTTP, cette fonction extrait le input
du corps JSON, le multiplie par 2 et renvoie le résultat au format JSON à l'appelant.
Créez le même fichier requirements.txt
dans le même répertoire avec le contenu suivant:
flask>=1.0.2
Déployez la fonction avec un déclencheur HTTP et autorisez les requêtes non authentifiées avec cette commande:
gcloud functions deploy multiply \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
Une fois la fonction déployée, vous pouvez également accéder à son URL à l'aide de la commande curl
suivante:
curl $(gcloud functions describe multiply --format='value(url)') \ -X POST \ -H "content-type: application/json" \ -d '{"input": 5}'
La fonction est prête pour le workflow.
6. Connecter deux fonctions Cloud
Dans le premier workflow, associez les deux fonctions.
Créez un fichier workflow.yaml
avec le contenu suivant :
- 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}
Dans ce workflow, vous obtenez un nombre aléatoire à partir de la première fonction et vous le transmettez à la deuxième fonction. Le résultat correspond au nombre aléatoire multiplié.
Déployez le premier workflow:
gcloud workflows deploy workflow --source=workflow.yaml
Exécutez le premier workflow:
gcloud workflows execute workflow
Une fois le workflow exécuté, vous pouvez afficher le résultat en transmettant l'ID d'exécution indiqué à l'étape précédente:
gcloud workflows executions describe <your-execution-id> --workflow workflow
Le résultat inclura result
et state
:
result: '{"body":{"multiplied":108},"code":200 ... } ... state: SUCCEEDED
7. Connecter une API HTTP externe
Ensuite, vous allez connecter math.js en tant que service externe dans le workflow.
Dans math.js, vous pouvez évaluer des expressions mathématiques comme suit:
curl https://api.mathjs.org/v4/?'expr=log(56)'
Cette fois, vous allez utiliser Cloud Console pour mettre à jour notre workflow. Recherchez Workflows
dans la console Google Cloud:
Recherchez votre workflow, puis cliquez sur l'onglet Definition
:
Modifiez la définition du workflow et incluez un appel à 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}
Le workflow alimente désormais la sortie de la fonction de multiplication dans un appel de fonction de journalisation dans math.js
.
L'UI vous guidera pour modifier et déployer le workflow. Une fois le déploiement terminé, cliquez sur Execute
pour exécuter le workflow. Les détails de l'exécution s'affichent:
Notez le code d'état 200
et un body
avec la sortie de la fonction de journalisation.
Vous venez d'intégrer un service externe à votre workflow. Super !
8. Déployer un service Cloud Run
Dans la dernière partie, finalisez le workflow avec un appel à un service Cloud Run privé. Cela signifie que le workflow doit être authentifié pour appeler le service Cloud Run.
Le service Cloud Run renvoie le math.floor
du nombre transmis.
Créez un répertoire pour le code de service et accédez-y:
mkdir ~/floor cd ~/floor
Créez un fichier app.py
dans le répertoire avec le contenu 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)))
Cloud Run déploie des conteneurs. Vous avez donc besoin d'un Dockerfile
et votre conteneur doit se lier aux variables d'environnement 0.0.0.0
et PORT
. C'est pourquoi le code ci-dessus est utilisé.
Lorsqu'elle reçoit une requête HTTP, cette fonction extrait le input
du corps JSON, appelle math.floor et renvoie le résultat à l'appelant.
Dans le même répertoire, créez le Dockerfile
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
Créez le conteneur :
export SERVICE_NAME=floor gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/${SERVICE_NAME}
Une fois le conteneur créé, déployez-le dans Cloud Run. Notez l'indicateur no-allow-unauthenticated
. Cela garantit que le service 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
Une fois déployé, le service est prêt pour le workflow.
9. Connecter le service Cloud Run
Avant de pouvoir configurer Workflows pour appeler le service Cloud Run privé, vous devez créer un compte de service à utiliser avec Workflows:
export SERVICE_ACCOUNT=workflows-sa gcloud iam service-accounts create ${SERVICE_ACCOUNT}
Attribuez le rôle run.invoker
au compte de service. Cela permettra au compte de service d'appeler des services Cloud Run authentifiés:
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \ --member "serviceAccount:${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \ --role "roles/run.invoker"
Mettez à jour la définition du workflow dans workflow.yaml
pour inclure le service Cloud Run. Notez que vous incluez également le champ auth
pour vous assurer que Workflows transmet le jeton d'authentification dans ses appels au service 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}
Mettez à jour le workflow. Cette fois, en transmettant le compte de service:
gcloud workflows deploy workflow \ --source=workflow.yaml \ --service-account=${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com
Exécutez le workflow :
gcloud workflows execute workflow
Au bout de quelques secondes, vous pouvez consulter l'exécution du workflow pour voir le résultat:
gcloud workflows executions describe <your-execution-id> --workflow workflow
La sortie inclut un entier result
et state
:
result: '{"body":"5","code":200 ... } ... state: SUCCEEDED
10. Félicitations !
Bravo ! Vous avez terminé cet atelier de programmation.
Points abordés
- Principes de base des workflows
- Connecter des fonctions Cloud publiques à des workflows
- Connecter des services Cloud Run privés à Workflows
- Connecter des API HTTP externes à Workflows