1. Descripción general
En este codelab, crearás un nuevo servicio de Cloud Run, un recolector de elementos no utilizados de imágenes, que se activará con Eventarc, un servicio nuevo para recibir eventos en Cloud Run. Cuando se borra una imagen del bucket de imágenes, el servicio recibe un evento de Eventarc. Luego, borra la imagen del bucket de miniaturas y también la quita de la colección de imágenes de Firestore.

Qué aprenderás
- Cloud Run
- Cloud Storage
- Cloud Firestore
- Eventarc
2. Configuración y requisitos
Configuración del entorno de autoaprendizaje
- Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.



- El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una string de caracteres que no se utiliza en las API de Google y se puede actualizar en cualquier momento.
- El ID del proyecto debe ser único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). Cloud Console genera automáticamente una string única, que, por lo general, no importa cuál sea. En la mayoría de los codelabs, debes hacer referencia al ID del proyecto (suele ser
PROJECT_ID). Por lo tanto, si no te gusta, genera otro aleatorio o prueba con uno propio y comprueba si está disponible. Después de crear el proyecto, este ID se “congela” y no se puede cambiar. - Además, hay un tercer valor, el Número de proyecto, que usan algunas API. Obtén más información sobre estos tres valores en la documentación.
- A continuación, deberás habilitar la facturación en Cloud Console para usar las API o los recursos de Cloud. Ejecutar este codelab no debería costar mucho, tal vez nada. Si quieres cerrar los recursos para no se te facture más allá de este instructivo, sigue las instrucciones de “limpieza” que se encuentran al final del codelab. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de USD 300.
Inicia Cloud Shell
Si bien Google Cloud y Spanner se pueden operar de manera remota desde tu laptop, en este codelab usarás Google Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.
En GCP Console, haga clic en el ícono de Cloud Shell en la barra de herramientas superior derecha:

El aprovisionamiento y la conexión al entorno deberían tomar solo unos minutos. Cuando termine el proceso, debería ver algo como lo siguiente:

Esta máquina virtual está cargada con todas las herramientas de desarrollo que necesitarás. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Puedes realizar todo tu trabajo en este lab usando simplemente un navegador.
3. Introducción a Eventarc
Eventarc facilita la conexión de servicios de Cloud Run con eventos de diversas fuentes. Se encarga de la transferencia, la entrega, la seguridad, la autorización y el manejo de errores de eventos por ti.

Puedes extraer eventos de fuentes de Google Cloud y aplicaciones personalizadas que publican en Cloud Pub/Sub, y entregarlos a receptores de Google Cloud Run.
Los eventos de una amplia variedad de fuentes de Google Cloud se entregan a través de los registros de auditoría de Cloud. La latencia y la disponibilidad de la entrega de eventos desde estas fuentes están vinculadas a las de los Registros de auditoría de Cloud. Cada vez que se activa un evento de una fuente de Google Cloud, se crea una entrada correspondiente en el registro de auditoría de Cloud.
Las aplicaciones personalizadas que publican en Cloud Pub/Sub pueden publicar mensajes en un tema de Pub/Sub que especifican en cualquier formato.
Los activadores de eventos son el mecanismo de filtrado para especificar qué eventos se deben entregar a qué receptor.
Todos los eventos se entregan en el formato CloudEvents v1.0 para la interoperabilidad entre servicios.
4. Antes de comenzar
Habilita las APIs
Necesitarás el servicio de Eventarc para activar el servicio de Cloud Run. Asegúrate de que esté habilitada:
gcloud services enable eventarc.googleapis.com
Deberías ver que la operación finaliza correctamente:
Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.
Configurar cuentas de servicio
La cuenta de servicio de procesamiento predeterminada se usará en los activadores. Otorga el rol eventarc.eventReceiver a la cuenta de servicio de Compute predeterminada:
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
Otorga el rol pubsub.publisher a la cuenta de servicio de Cloud Storage. Esto es necesario para el activador de Eventarc en Cloud Storage:
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 habilitaste la cuenta de servicio de Pub/Sub el 8 de abril de 2021 o antes de esa fecha, otorga el rol iam.serviceAccountTokenCreator a la cuenta de servicio de 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. Clona el código
Clona el código si aún no lo hiciste en el codelab anterior:
git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop
Luego, puedes ir al directorio que contiene el servicio:
cd serverless-photosharing-workshop/services/garbage-collector/nodejs
Tendrás el siguiente diseño de archivos para el servicio:
services
|
├── garbage-collector
|
├── nodejs
|
├── index.js
├── package.json
Dentro de la carpeta, tienes 3 archivos:
index.jscontiene el código de Node.jspackage.jsondefine las dependencias de la biblioteca
6. Cómo explorar el código
Dependencias
El archivo package.json define las dependencias de biblioteca necesarias:
{
"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"
}
}
Dependemos de la biblioteca de Cloud Storage para borrar imágenes dentro de Cloud Storage. Declaramos una dependencia en Cloud Firestore para borrar también los metadatos de las fotos que almacenamos anteriormente. Además, dependemos de las bibliotecas de Google Events y del SDK de CloudEvents para leer los CloudEvents que envía Eventarc. Express es un framework web de JavaScript / Node. Bluebird se usa para controlar las promesas.
index.js
Analicemos con más detalle nuestro código 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');
Necesitamos las diversas dependencias necesarias para que se ejecute nuestro programa: Express es el framework web de Node que usaremos, Bluebird es una biblioteca para controlar las promesas de JavaScript, y Storage y Firestore son para trabajar, respectivamente, con Google Cloud Storage (nuestros buckets de imágenes) y el almacén de datos de Cloud Firestore. Además, requerimos que CloudEvent lea el CloudEvent que envía Eventarc StoreObjectData desde la biblioteca de Google Events para leer el cuerpo del evento de Cloud Storage del 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);
}
});
Arriba, tenemos la estructura de nuestro controlador de Node: nuestra app responde a las solicitudes HTTP POST. Lee el CloudEvent de la solicitud HTTP y controlamos los errores en caso de que algo salga mal. Ahora veamos qué hay dentro de esta estructura.
El siguiente paso es recuperar y analizar el cuerpo de CloudEvent, y recuperar el nombre del objeto:
const storageObjectData = toStorageObjectData(cloudEvent.data);
console.log(storageObjectData);
const objectName = storageObjectData.name;
Una vez que conocemos el nombre de la imagen, podemos borrarla del bucket de miniaturas:
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}.`);
}
Como último paso, borra también los metadatos de la imagen de la colección de 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}'.`);
Ahora es el momento de hacer que nuestra secuencia de comandos de Node escuche las solicitudes entrantes. También verifica que estén configuradas las variables de entorno necesarias:
app.listen(PORT, () => {
if (!bucketThumbnails) throw new Error("BUCKET_THUMBNAILS not set");
console.log(`Started service on port ${PORT}`);
});
7. Realiza pruebas locales
Prueba el código de forma local para asegurarte de que funcione antes de implementarlo en la nube.
Dentro de la carpeta garbage-collector/nodejs, instala las dependencias de npm y, luego, inicia el servidor:
export BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT npm install; npm start
Si todo salió bien, debería iniciar el servidor en el puerto 8080:
Started service on port 8080
Usa CTRL-C para salir.
8. Compila e implementa en Cloud Run
Antes de implementar en Cloud Run, configura la región de Cloud Run en una de las regiones compatibles y la plataforma en managed:
REGION=europe-west1 gcloud config set run/region $REGION gcloud config set run/platform managed
Puedes verificar que la configuración esté establecida:
gcloud config list ... [run] platform = managed region = europe-west1
En lugar de compilar y publicar la imagen de contenedor con Cloud Build de forma manual, también puedes confiar en Cloud Run para que compile la imagen de contenedor por ti con los paquetes de compilación de Google Cloud.
Ejecuta el siguiente comando para compilar la imagen del contenedor con los paquetes de compilación de Google Cloud y, luego, implementarla en Cloud Run:
SERVICE_NAME=garbage-collector-service
gcloud run deploy $SERVICE_NAME \
--source . \
--no-allow-unauthenticated \
--update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS
Observa la marca –-source. Esto indica a Cloud Run que use los buildpacks de Google Cloud para compilar la imagen de contenedor sin un Dockerfile.. La marca --no-allow-unauthenticated convierte al servicio de Cloud Run en un servicio interno que solo se activará con cuentas de servicio específicas. Más adelante, crearás un activador con la cuenta de servicio de Compute predeterminada que tiene el rol run.invoker para llamar a los servicios internos de Cloud Run.
9. Crea un activador
En Eventarc, un objeto Trigger define qué servicio debe recibir qué tipo de eventos. En este caso, deseas que el servicio reciba eventos cuando se borre un archivo en un bucket.
Establece la ubicación del activador en la misma región que el bucket de imágenes subidas:
gcloud config set eventarc/location eu
Crea un activador de AuditLog para filtrar los eventos de storage.objects.delete y enviarlos al servicio de 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
Puedes verificar que se haya creado el activador con este comando:
gcloud eventarc triggers list
10. Prueba el servicio
Para probar si el servicio funciona, ve al bucket uploaded-pictures y borra una de las imágenes. En los registros del servicio, deberías ver que se borró la imagen pertinente del bucket thumbnails y también se borró su documento de la colección pictures de Firestore.

11. Limpieza (opcional)
Si no quieres continuar con los otros labs de la serie, puedes limpiar los recursos para ahorrar costos y ser un buen ciudadano de la nube. Puedes limpiar los recursos de forma individual de la siguiente manera.
Borra el servicio:
gcloud run services delete $SERVICE_NAME -q
Borrar el activador de Eventarc:
gcloud eventarc triggers delete trigger-$SERVICE_NAME -q
Como alternativa, puedes borrar todo el proyecto:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
12. ¡Felicitaciones!
¡Felicitaciones! Creaste un servicio de Cloud Run, un recolector de elementos no utilizados de imágenes, que se activa con Eventarc, un nuevo servicio para recibir eventos en Cloud Run. Cuando se borra una imagen del bucket de imágenes, el servicio recibe un evento de Eventarc. Luego, borra la imagen del bucket de miniaturas y también la quita de la colección de imágenes de Firestore.
Temas abordados
- Cloud Run
- Cloud Storage
- Cloud Firestore
- Eventarc