Créer une orchestration basée sur des événements avec Eventarc et Workflows

1. Présentation

cb762f29e9183a3f.png 1c05e3d0c2bd2b45.png A03f943ca09ac4c.png

Eventarc permet de connecter facilement des services Cloud Run à des événements provenant de sources multiples. Il vous permet de créer des architectures basées sur des événements dans lesquelles des microservices sont faiblement couplés et distribués. Il se charge de l'ingestion, de la distribution, de la sécurité, des autorisations et de la gestion des erreurs pour vous.

Workflows est une plate-forme d'orchestration entièrement gérée qui exécute des services dans l'ordre que vous avez défini. Ces workflows peuvent combiner des services hébergés sur Cloud Run ou Cloud Functions, des services Google Cloud tels que Cloud Vision AI et BigQuery, et n'importe quelle API HTTP.

Dans cet atelier de programmation, vous allez créer une orchestration de microservices basée sur des événements pour traiter les images. Vous allez utiliser des workflows pour orchestrer l'ordre, les entrées et les sorties de quatre fonctions de traitement d'image Cloud Functions. Vous activerez ensuite l'orchestration pour répondre aux événements Cloud Storage de manière faiblement couplée avec Eventarc.

Au final, vous vous retrouverez avec une architecture sans serveur flexible et structurée pour traiter des images.

e372ceed8c26c5fb.png

Ce que vous allez apprendre

  • Présentation d'Eventarc et des workflows
  • Déployer des services Cloud Functions
  • Orchestration de services à l'aide de workflows
  • Faire en sorte que les workflows répondent aux événements Cloud Storage avec Eventarc

2. Prérequis

Utiliser des crédits

cae48e4b2e19921d.png

Dans la boîte de dialogue qui s'affiche, acceptez les conditions d'utilisation en cliquant sur le bouton "Accepter et continuer" :

27d87930a0daf2f8.png

Après avoir accepté les conditions d'utilisation, vous serez redirigé vers une page récapitulative de facturation comprenant un panneau semblable à celui-ci situé dans l'angle inférieur droit:

2076ea7aa9bf3f65.png

Enfin, lorsque vous créez votre premier projet, une boîte de dialogue vous permet d'attribuer un compte de facturation à celui-ci. Sélectionnez le compte de facturation associé à vos crédits gratuits, puis cliquez sur le bouton "Créer" :

dd3b0e795843296.png

En résumé, vous disposez à présent d'un compte de facturation et d'un projet, qui sont associés, de sorte que toutes les activités effectuées dans l'atelier de programmation d'aujourd'hui seront financées par vos crédits gratuits**.**

Configuration de l'environnement au rythme de chacun

  1. Connectez-vous à Google Cloud Console, puis créez un projet ou réutilisez un projet existant. Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.

b35bf95b8bf3d5d8.png

A99b7ace416376c4.png

bd84a6d3003637c5.png

  • Le nom du projet est le nom à afficher pour les participants à ce projet. Il s'agit d'une chaîne de caractères qui n'est pas utilisée par les API Google. Vous pouvez la modifier à tout moment.
  • L'ID du projet doit être unique parmi tous les projets Google Cloud et doit être immuable (il ne peut pas être modifié une fois défini). Cloud Console génère automatiquement une chaîne unique. vous n'avez généralement pas besoin de vous en occuper. Dans la plupart des ateliers de programmation, vous devrez référencer l'ID du projet. De plus, il est généralement identifié comme PROJECT_ID. Si vous n'aimez pas cet outil, générez-en un autre au hasard, ou essayez le vôtre et vérifiez si est disponible. Ensuite, elle est "gelée" après la création du projet.
  • Le numéro de projet, utilisé par certaines API, est troisième. Pour en savoir plus sur ces trois valeurs, consultez la documentation.
  1. Vous devez ensuite activer la facturation dans Cloud Console afin d'utiliser les ressources/API Cloud. L'exécution de cet atelier de programmation est très peu coûteuse, voire gratuite. Pour arrêter les ressources afin d'éviter toute facturation en dehors de ce tutoriel, suivez les instructions de nettoyage indiquées à la fin de l'atelier de programmation. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit de 300 USD.

Démarrer Cloud Shell

Vous pouvez utiliser Google Cloud à distance depuis votre ordinateur portable. Dans cet atelier de programmation, vous allez utiliser Google Cloud Shell, un environnement de ligne de commande fonctionnant dans le cloud.

Dans Google Cloud Console, cliquez sur l'icône Cloud Shell dans la barre d'outils supérieure:

55efc1aaa7a4d3ad.png

Le provisionnement de l'environnement et la connexion ne devraient pas prendre plus de quelques minutes. Une fois l'opération terminée, le résultat devrait ressembler à ceci:

7ffe5cbb04455448.png

Cette machine virtuelle contient tous les outils de développement nécessaires. Il s'agit d'un répertoire d'accueil persistant de 5 Go qui s'exécute sur Google Cloud, ce qui améliore considérablement les performances et l'authentification du réseau. Vous pouvez travailler simplement dans un atelier à l'aide d'un simple navigateur.

Configurer gcloud

Dans Cloud Shell, définissez votre ID de projet et la région dans laquelle vous souhaitez déployer votre application. Enregistrez-les sous la forme de variables PROJECT_ID et REGION. Consultez les emplacements Cloud Functions pour connaître les régions disponibles.

PROJECT_ID=[YOUR-PROJECT-ID]
REGION=[YOUR-REGION]
gcloud config set core/project $PROJECT_ID
gcloud config set functions/region $REGION

Activer les services

Activez tous les services nécessaires:

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  cloudfunctions.googleapis.com \
  eventarc.googleapis.com \
  vision.googleapis.com \
  workflows.googleapis.com \
  workflowexecutions.googleapis.com

Obtenir le code source

Le code source de l'application se trouve dans le dossier processing-pipelines du dépôt eventarc-samples.

Clonez le dépôt :

git clone https://github.com/GoogleCloudPlatform/eventarc-samples.git

Accédez au dossier eventarc-samples/processing-pipelines:

cd eventarc-samples/processing-pipelines

3. Présentation de l'architecture

L'architecture de l'application est la suivante:

6aa6fbc7721jj6b6.png

  1. Une image est enregistrée dans un bucket d'entrée qui génère un événement de création Cloud Storage.
  2. L'événement de création Cloud Storage est lu par Eventarc via un déclencheur Cloud Storage, puis transmis à Workflows en tant qu'événement CloudEvent.
  3. À la première étape du workflow, un filtre, un service Cloud Functions, utilise l'API Vision pour déterminer si l'image est sécurisée. Si l'image ne présente aucun risque, les étapes suivantes passent au workflow.
  4. Lors de la deuxième étape du workflow, un étiqueteur, un service Cloud Functions, extrait les étiquettes de l'image avec l'API Vision et les enregistre dans le bucket de sortie.
  5. À la troisième étape, Resizer, un autre service de Cloud Function, redimensionne l'image à l'aide de ImageSharp et enregistre l'image redimensionnée dans le bucket de sortie.
  6. À la dernière étape, un repère, un autre service de fonction Cloud, ajoute un filigrane de Labeler à l'image redimensionnée à l'aide de ImageSharp, puis enregistre l'image dans le bucket de sortie.

L'application est déclenchée par un événement Cloud Storage, donc basé sur l'événement. Le traitement des images s'effectue dans un workflow, ce qui signifie qu'il s'agit d'une orchestration. En fin de compte, il s'agit d'une orchestration basée sur des événements pour une architecture sans serveur flexible, mais structurée qui permet de traiter des images.

4. Créer des buckets

Créez un bucket d'entrée pour que les utilisateurs puissent importer les images, et un bucket de sortie pour le pipeline de traitement des images afin de les enregistrer.

Exécutez la commande suivante dans Cloud Shell :

BUCKET1=$PROJECT_ID-images-input
BUCKET2=$PROJECT_ID-images-output
gsutil mb -l $REGION gs://$BUCKET1
gsutil mb -l $REGION gs://$BUCKET2

5. Déployer le service de filtres

Commençons par déployer le premier service. Ce service Cloud Functions reçoit les informations sur le bucket et le fichier, détermine si l'image est sécurisée avec l'API Vision et renvoie le résultat.

Dans le dossier processing-pipelines de premier niveau, déployez le service:

SERVICE_NAME=filter
gcloud functions deploy $SERVICE_NAME \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --entry-point Filter.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v3/filter/csharp

Une fois la fonction déployée, définissez l'URL de service dans une variable. Nous en avons besoin plus tard:

FILTER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')

6. Déployer le service d'étiqueteurs

Le deuxième service Cloud Functions reçoit les informations sur le bucket et le fichier, extrait les libellés de l'image avec l'API Vision et enregistre les libellés dans le bucket de sortie.

Dans le dossier processing-pipelines de premier niveau, déployez le service:

SERVICE_NAME=labeler
gcloud functions deploy $SERVICE_NAME \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --set-env-vars BUCKET=$BUCKET2 \
  --entry-point Labeler.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v2/labeler/csharp

Une fois la fonction déployée, définissez l'URL de service dans une variable. Nous en avons besoin plus tard:

LABELER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')

7. Déployer le service de redimensionnement

Ce service Cloud Functions reçoit les informations sur le bucket et le fichier, redimensionne l'image à l'aide de ImageSharp et enregistre l'image dans le bucket de sortie.

Dans le dossier processing-pipelines de premier niveau, déployez le service:

SERVICE_NAME=resizer
gcloud functions deploy $SERVICE_NAME \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --set-env-vars BUCKET=$BUCKET2 \
  --entry-point Resizer.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v2/resizer/csharp

Une fois la fonction déployée, définissez l'URL de service dans une variable. Nous en avons besoin plus tard:

RESIZER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')

8. Déployer le service de filigrane

Ce service Cloud Functions reçoit les informations sur le bucket, le fichier et les libellés, lit le fichier, ajoute les libellés au filigrane à l'image à l'aide de ImageSharp et enregistre l'image dans le bucket de sortie.

Dans le dossier processing-pipelines de premier niveau, déployez le service:

SERVICE_NAME=watermarker
gcloud functions deploy $SERVICE_NAME \
  --allow-unauthenticated \
  --runtime dotnet3 \
  --trigger-http \
  --region=$REGION \
  --set-env-vars BUCKET=$BUCKET2 \
  --entry-point Watermarker.Function \
  --set-build-env-vars GOOGLE_BUILDABLE=image-v2/watermarker/csharp

Une fois la fonction déployée, définissez l'URL de service dans une variable. Nous en avons besoin plus tard:

WATERMARKER_URL=$(gcloud functions describe $SERVICE_NAME --format 'value(httpsTrigger.url)')

À ce stade, les quatre fonctions Cloud doivent être déployées et exécutées:

5D7D4061e04c91bb.png

9. Définir et déployer le workflow

Utilisez les workflows pour regrouper les services de filtrage, d'étiquetage, de redimensionnement et de filigrane dans un workflow. Les workflows orchestrent l'appel de ces services dans l'ordre et avec les paramètres que nous définissons.

Définir

Workflows reçoit un événement CloudEvent en tant que paramètre. Il provient d'Eventarc une fois le déclencheur créé. Au cours des deux premières étapes, Workflows consigne l'événement et extrait les informations de bucket et de fichier de l'événement:

main:
  params: [event]
  steps:
  - log_event:
      call: sys.log
      args:
          text: ${event}
          severity: INFO
  - extract_bucket_and_file:
      assign:
      - bucket: ${event.data.bucket}
      - file: ${event.data.name}

À l'étape filter, Workflows appelle le service de filtrage que nous avons déployé précédemment. Il consigne ensuite les valeurs et vérifie la sécurité du fichier:

  - filter:
      call: http.post
      args:
        url: FILTER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${bucket}
            file: ${file}
      result: filterResponse
  - log_safety:
      call: sys.log
      args:
          text: ${filterResponse.body.safe}
          severity: INFO
  - check_safety:
      switch:
        - condition: ${filterResponse.body.safe == true}
          next: label
      next: end

À l'étape label, Workflows appelle le service d'étiqueteur et enregistre la réponse (les trois étiquettes principales):

  - label:
      call: http.post
      args:
        url: LABELER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${bucket}
            file: ${file}
      result: labelResponse

À l'étape resize, Workflows appelle le service de redimensionnement et capture la réponse (le bucket et le fichier de l'image redimensionnée):

  - resize:
      call: http.post
      args:
        url: RESIZER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${bucket}
            file: ${file}
      result: resizeResponse

À l'étape watermark, Workflows appelle le service de filigrane avec l'image et les libellés redimensionnés et capture le résultat (l'image redimensionnée et en filigrane):

  - watermark:
      call: http.post
      args:
        url: WATERMARKER_URL # TODO: Replace
        auth:
          type: OIDC
        body:
            bucket: ${resizeResponse.body.bucket}
            file: ${resizeResponse.body.file}
            labels: ${labelResponse.body.labels}
      result: watermarkResponse

À l'étape final, les workflows renvoient le code d'état HTTP des services d'étiquetage, de redimensionnement et des filigranes:

  - final:
      return:
        label: ${labelResponse.code}
        resize: ${resizeResponse.code}
        watermark: ${watermarkResponse.code}

Deploy

Avant de déployer le workflow, assurez-vous de remplacer manuellement l'URL du service par une URLsed:

Dans le dossier racine processing-pipelines, accédez au dossier image-v3 qui contient le fichier workflows.yaml:

cd image-v3/

Exécutez sed pour remplacer les URL fictives par les URL réelles des services déployés:

sed -i -e "s|FILTER_URL|${FILTER_URL}|" workflow.yaml
sed -i -e "s|LABELER_URL|${LABELER_URL}|" workflow.yaml
sed -i -e "s|RESIZER_URL|${RESIZER_URL}|" workflow.yaml
sed -i -e "s|WATERMARKER_URL|${WATERMARKER_URL}|" workflow.yaml

Déployez le workflow:

WORKFLOW_NAME=image-processing
gcloud workflows deploy $WORKFLOW_NAME \
    --source=workflow.yaml \
    --location=$REGION

Le workflow devrait être déployé dans la console dans quelques secondes:

92cf4e758bdc3dde.png

10. Create trigger

Maintenant que le workflow est déployé, la dernière étape consiste à le connecter à des événements Cloud Storage avec un déclencheur Eventarc.

Configuration unique

Le compte de service Compute par défaut sera utilisé pour le déclencheur. Assurez-vous qu'il dispose du rôle eventarc.eventReceiver:

PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
    --role roles/eventarc.eventReceiver

Attribuez le rôle pubsub.publisher au compte de service Cloud Storage. C'est nécessaire pour le déclencheur Cloud Storage d'Eventarc:

SERVICE_ACCOUNT="$(gsutil kms serviceaccount -p $PROJECT_NUMBER)"

gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
    --member serviceAccount:$SERVICE_ACCOUNT \
    --role roles/pubsub.publisher

Créer

Exécutez la commande suivante pour créer un déclencheur. Ce déclencheur filtre les nouveaux événements de création de fichiers à partir du bucket Cloud Storage d'entrée et les transmet au workflow que nous avons défini précédemment:

TRIGGER_NAME=trigger-$WORKFLOW_NAME
gcloud eventarc triggers create $TRIGGER_NAME \
  --location=$REGION \
  --destination-workflow=$WORKFLOW_NAME \
  --destination-workflow-location=$REGION \
  --event-filters="type=google.cloud.storage.object.v1.finalized" \
  --event-filters="bucket=$BUCKET1" \
  --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com

Vous pouvez constater que le déclencheur est créé et prêt dans la section Eventarc de Cloud Console:

14330c4fa2476b0.png

11. Tester le pipeline

Le pipeline de traitement des images est prêt à recevoir des événements de Cloud Storage. Pour tester le pipeline, importez une image dans le bucket d'entrée:

gsutil cp beach.jpg gs://$BUCKET1

Dès que vous importez la photo, vous devez constater que l'exécution des workflows est active:

36d07cb63c39e7d9.png

Après une minute environ, l'exécution devrait s'exécuter. Vous pouvez également consulter l'entrée et la sortie du workflow:

229200c79d989c25.png

Si vous répertoriez le contenu du bucket de sortie, vous devriez voir l'image redimensionnée, et l'image et les libellés redimensionnés et en filigrane:

gsutil ls gs://$BUCKET2

gs://$PROJECT_ID-images-output/beach-400x400-watermark.jpeg
gs://$PROJECT_ID-images-output/beach-400x400.png
gs://$PROJECT_ID-images-output/beach-labels.txt

Pour vérifier, vous pouvez ouvrir l'image redimensionnée et en filigrane pour voir le résultat:

75f3c0019ca842ce.jpeg

12. Félicitations

Félicitations, vous avez terminé cet atelier de programmation !

Points abordés

  • Présentation d'Eventarc et des workflows
  • Déployer des services Cloud Functions
  • Orchestration de services à l'aide de workflows
  • Faire en sorte que les workflows répondent aux événements Cloud Storage avec Eventarc