Pic-à-quoi : Atelier 5 : Nettoyage après suppression de l'image

1. Présentation

Dans cet atelier de programmation, vous allez créer un service Cloud Run, le récupérateur de mémoire d'images, qui sera déclenché par Eventarc, un nouveau service permettant de recevoir des événements dans Cloud Run. Lorsqu'une image est supprimée du bucket "photos", le service reçoit un événement d'Eventarc. Ensuite, il supprime l'image du bucket des vignettes et la supprime également de la collection d'images Firestore.

d93345bfc235f81e.png

Points abordés

  • Cloud Run
  • Cloud Storage
  • Cloud Firestore
  • Eventarc

2. Préparation

Configuration de l'environnement au rythme de chacun

  1. Connectez-vous à la console Google Cloud, 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.)

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • Le nom du projet est le nom à afficher pour les participants au projet. Il s'agit d'une chaîne de caractères qui n'est pas utilisée par les API Google, et que vous pouvez modifier à tout moment.
  • L'ID du projet doit être unique sur l'ensemble des projets Google Cloud et doit être immuable (vous ne pouvez pas le modifier une fois que vous l'avez défini). Cloud Console génère automatiquement une chaîne unique dont la composition importe peu, en général. Dans la plupart des ateliers de programmation, vous devrez référencer l'ID du projet (généralement identifié comme PROJECT_ID), donc s'il ne vous convient pas, générez-en un autre au hasard ou définissez le vôtre, puis vérifiez s'il est disponible. Il est ensuite "gelé" une fois le projet créé.
  • La troisième valeur est le numéro de projet, utilisé par certaines API. 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 sans frais. Pour arrêter les ressources afin d'éviter qu'elles ne vous soient facturées après ce tutoriel, suivez les instructions de nettoyage indiquées à la fin de l'atelier. 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 :

bce75f34b2c53987.png

Le provisionnement et la connexion à l'environnement prennent quelques instants seulement. Une fois l'opération terminée, le résultat devrait ressembler à ceci :

f6ef2b5f13479f3a.png

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 d'Eventarc

Eventarc facilite la connexion des services Cloud Run à des événements provenant de diverses sources. Il gère pour vous l'ingestion, la diffusion, la sécurité, l'autorisation et la gestion des erreurs des événements.

776ed63706ca9683.png

Vous pouvez dessiner des événements à partir de sources Google Cloud et d'applications personnalisées publiées sur Cloud Pub/Sub, puis les transmettre aux récepteurs Google Cloud Run.

Les événements provenant de nombreuses sources Google Cloud sont transmis au moyen de Cloud Audit Logs. La latence et la disponibilité de la diffusion d'événements à partir de ces sources sont liées à celles de Cloud Audit Logs. Chaque fois qu'un événement d'une source Google Cloud est déclenché, une entrée de journal Cloud Audit Log correspondante est créée.

Les applications personnalisées qui publient des messages dans Cloud Pub/Sub peuvent publier des messages dans un sujet Pub/Sub qu'elles spécifient dans n'importe quel format.

Les déclencheurs d'événements constituent le mécanisme de filtrage qui permet de spécifier les événements à distribuer à quel récepteur.

Tous les événements sont diffusés au format CloudEvents v1.0 pour assurer l'interopérabilité entre les services.

4. Avant de commencer

Activer les API

Vous aurez besoin du service Eventarc pour déclencher le service Cloud Run. Assurez-vous qu'elle est activée:

gcloud services enable eventarc.googleapis.com

L'opération doit s'afficher pour se terminer correctement:

Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.

Configurer des comptes de service

Le compte de service Compute par défaut sera utilisé dans les déclencheurs. Attribuez le rôle eventarc.eventReceiver au compte de service Compute par défaut:

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

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

Accordez le rôle pubsub.publisher au compte de service Cloud Storage. Cette opération est nécessaire pour le déclencheur Cloud Storage 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

Si vous avez activé le compte de service Pub/Sub au plus tard le 8 avril 2021, accordez le rôle iam.serviceAccountTokenCreator au compte de service Pub/Sub:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
  --role roles/iam.serviceAccountTokenCreator

5. Cloner le code

Clonez le code (si vous ne l'avez pas déjà fait dans l'atelier de programmation précédent) :

git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop

Vous pouvez ensuite accéder au répertoire contenant le service:

cd serverless-photosharing-workshop/services/garbage-collector/nodejs

La mise en page des fichiers du service est la suivante:

services
 |
 ├── garbage-collector
      |
      ├── nodejs
           |
           ├── index.js
           ├── package.json

Dans le dossier, vous avez trois fichiers:

  • index.js contient le code Node.js
  • package.json définit les dépendances de la bibliothèque.

6. Explorer le code

Dépendances

Le fichier package.json définit les dépendances de bibliothèque nécessaires:

{
  "name": "garbage_collector_service",
  "version": "0.0.1",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "cloudevents": "^4.0.1",
    "express": "^4.17.1",
    "@google/events": "^3.1.0",
    "@google-cloud/firestore": "^4.9.9",
    "@google-cloud/storage": "^5.8.3"
  }
}

Nous dépendons de la bibliothèque Cloud Storage pour supprimer des images dans Cloud Storage. Nous déclarons une dépendance à Cloud Firestore pour supprimer également les métadonnées d'image que nous avions stockées précédemment. De plus, nous dépendons du SDK CloudEvents et des bibliothèques Google Events pour lire les événements CloudEvents envoyés par Eventarc. Express est un framework Web JavaScript / Node. Bluebird est utilisé pour gérer les promesses.

index.js

Examinons de plus près notre code index.js:

const express = require('express');
const {Storage} = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');
const { HTTP } = require("cloudevents");
const {toStorageObjectData} = require('@google/events/cloud/storage/v1/StorageObjectData');

Nous avons besoin des différentes dépendances nécessaires à l'exécution de notre programme: Express est le framework Web Node que nous allons utiliser, Bluebird est une bibliothèque permettant de gérer les promesses JavaScript, Storage et Firestore sont destinés à travailler respectivement avec Google Cloud Storage (nos buckets d'images) et le datastore Cloud Firestore. En outre, nous demandons à CloudEvent de lire le CloudEvent envoyé par Eventarc StoreObjectData depuis la bibliothèque Google Events pour lire le corps de l'événement Cloud Storage de l'événement CloudEvent.

const app = express();
app.use(express.json());

app.post('/', async (req, res) => {
    try {
        const cloudEvent = HTTP.toEvent({ headers: req.headers, body: req.body });
        console.log(cloudEvent);


        /* ... */

    } catch (err) {
        console.log(`Error: ${err}`);
        res.status(500).send(err);
    }
});

Ci-dessus, nous avons la structure de notre gestionnaire de nœuds: notre application répond aux requêtes HTTP POST. Il lit l'événement CloudEvent à partir de la requête HTTP et gère les erreurs en cas de problème. Voyons maintenant le contenu de cette structure.

L'étape suivante consiste à récupérer et à analyser le corps CloudEvent, puis à récupérer le nom de l'objet:

const storageObjectData = toStorageObjectData(cloudEvent.data);
console.log(storageObjectData);

const objectName = storageObjectData.name;

Une fois que nous connaissons le nom de l'image, nous pouvons la supprimer du bucket des vignettes:

try {
    await storage.bucket(bucketThumbnails).file(objectName).delete();
    console.log(`Deleted '${objectName}' from bucket '${bucketThumbnails}'.`);
}
catch(err) {
    console.log(`Failed to delete '${objectName}' from bucket '${bucketThumbnails}': ${err}.`);
}

Pour terminer, supprimez également les métadonnées d'image de la collection Firestore:

try {
    const pictureStore = new Firestore().collection('pictures');
    const docRef = pictureStore.doc(objectName);
    await docRef.delete();

    console.log(`Deleted '${objectName}' from Firestore collection 'pictures'`);
}
catch(err) {
    console.log(`Failed to delete '${objectName}' from Firestore: ${err}.`);
}

res.status(200).send(`Processed '${objectName}'.`);

Il est maintenant temps de faire en sorte que notre script Node écoute les requêtes entrantes. Vérifiez également que les variables d'environnement requises sont définies:

app.listen(PORT, () => {
    if (!bucketThumbnails) throw new Error("BUCKET_THUMBNAILS not set");
    console.log(`Started service on port ${PORT}`);
});

7. Tester en local

Testez le code localement pour vous assurer qu'il fonctionne avant de le déployer dans le cloud.

Dans le dossier garbage-collector/nodejs, installez les dépendances npm et démarrez le serveur:

export BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT

npm install; npm start

Si tout s'est déroulé comme prévu, le serveur doit démarrer sur le port 8080:

Started service on port 8080

Appuyez sur CTRL-C pour quitter.

8. Compiler et déployer sur Cloud Run

Avant le déploiement sur Cloud Run, définissez la région Cloud Run sur l'une des régions et la plate-forme compatibles sur managed:

REGION=europe-west1
gcloud config set run/region $REGION
gcloud config set run/platform managed

Vous pouvez vérifier que la configuration est définie:

gcloud config list

...
[run]
platform = managed
region = europe-west1

Au lieu de créer et de publier l'image de conteneur manuellement à l'aide de Cloud Build, vous pouvez également compter sur Cloud Run pour créer l'image de conteneur pour vous à l'aide des packs de création Google Cloud.

Exécutez la commande suivante pour créer l'image de conteneur à l'aide de Buildpacks Google Cloud, puis déployer l'image de conteneur dans Cloud Run:

SERVICE_NAME=garbage-collector-service

gcloud run deploy $SERVICE_NAME \
    --source . \
    --no-allow-unauthenticated \
    --update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS

Notez l'indicateur –-source. Cela indique à Cloud Run d'utiliser des buildpacks Google Cloud pour créer l'image de conteneur sans Dockerfile.. L'option --no-allow-unauthenticated fait du service Cloud Run un service interne qui ne sera déclenché que par des comptes de service spécifiques. Par la suite, vous créerez un déclencheur avec le compte de service Compute par défaut doté du rôle run.invoker pour appeler des services Cloud Run internes.

9. Créer un déclencheur

Dans Eventarc, un déclencheur définit le service qui doit recevoir le type d'événements. Dans ce cas, vous souhaitez que le service reçoive des événements lorsqu'un fichier est supprimé dans un bucket.

Définissez l'emplacement du déclencheur dans la même région que le bucket d'images importées:

gcloud config set eventarc/location eu

Créez un déclencheur AuditLog pour filtrer les événements storage.objects.delete et l'envoyer au service Cloud Run:

BUCKET_IMAGES=uploaded-pictures-$GOOGLE_CLOUD_PROJECT

gcloud eventarc triggers create trigger-$SERVICE_NAME \
  --destination-run-service=$SERVICE_NAME \
  --destination-run-region=$REGION \
  --event-filters="type=google.cloud.storage.object.v1.deleted" \
  --event-filters="bucket=$BUCKET_IMAGES" \
  --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com

Vous pouvez vérifier que le déclencheur a bien été créé à l'aide de la commande suivante:

gcloud eventarc triggers list

10. Tester le service

Pour vérifier que le service fonctionne, accédez au bucket uploaded-pictures et supprimez l'une des images. Dans les journaux du service, vous devriez voir qu'il a supprimé l'image pertinente dans le bucket thumbnails ainsi que son document de la collection Firestore pictures.

519abf90e7ea4d12.png

11. Nettoyer (facultatif)

Si vous n'avez pas l'intention de suivre les autres ateliers de la série, vous pouvez nettoyer les ressources pour réduire les coûts et utiliser globalement le cloud comme il se doit. Vous pouvez nettoyer les ressources individuellement comme suit.

Supprimez le service :

gcloud run services delete $SERVICE_NAME -q

Supprimez le déclencheur Eventarc :

gcloud eventarc triggers delete trigger-$SERVICE_NAME -q

Vous pouvez également supprimer l'intégralité du projet:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

12. Félicitations !

Félicitations ! Vous avez créé un service Cloud Run, le récupérateur de mémoire d'images, qui est déclenché par Eventarc, un nouveau service permettant de recevoir des événements dans Cloud Run. Lorsqu'une image est supprimée du bucket "photos", le service reçoit un événement d'Eventarc. Ensuite, il supprime l'image du bucket des vignettes et la supprime également de la collection d'images Firestore.

Points abordés

  • Cloud Run
  • Cloud Storage
  • Cloud Firestore
  • Eventarc