¡Lambda! Conecta tu Bucket S3 con una función Lambda.

Flavio AAndres
7 min readJun 15, 2020

--

No sé de qué hablar primero, los Buckets S3 y las funciones Lambda son uno de los servicios más usados de Amazon Web Services.

¿Cómo no? Por si solo el Bucket S3 es capaz de almacenar cualquier tipo de archivo, dejarlos en el olvido por años y recuperarlo en unos cuantos clicks, puedes montar toda una web estática dentro de él y más.

Las funciones Lambdas son en parte un sueño para developers, tú escribes el código que necesitas se ejecute en X tarea y después de desplegarlo, no te preocupas de más nada. Por cada función lambda corriendo en AWS tienes un sistema de monitoreo de todas las ejecuciones: número de Fallas, éxitos, tiempos de ejecución y consumo de memoria. ¿Cuánto tomaría implementar todo esto por si solo?

Lambdas y Buckets S3 Corriendo Juntos

¿Qué te parece que por cada archivo que subas a un Bucket, una función Lambda se ejecute?

Las posibilidades son gigantes, puedes procesar .csv de gran tamaño para enviarlos a bases de datos. Puedes Leer varios archivos .xlsx, unirlos y dejar el resultado en otro Bucket (o el mismo). Como también puedes subir Imágenes y automáticamente crear otra a partir de ellas con nuevas propiedades.

Esto último, es lo que vamos a hacer a continuación, crearemos un Bucket, Escribiremos un poco de código y los conectaremos para que juntos conviertan las imágenes a un tamaño más pequeño. Perfecto para thumbnails.

Para esto necesitamos tener 2 Buckets, llámalos como quieras, uno será el Bucket de entrada (donde guardaremos nuestros archivos originales) y el segundo será el Bucket de salida.

Puedes crearlo desde aws-cli usando:

el uso de la opción --region es opcional.

También puedes crear el Bucket desde la Interfaz web de AWS, entramos a la sección de los Buckets S3 y creamos el Bucket.

Podemos establecerle los permisos por defecto que vienen configurados para los Buckets, en este caso, no los haremos visible al público. Si quieres usarlas desde internet (Tu Sitio web) Debes dejar el Bucket con las opciones abiertas al público.

Ahora, La función Lambda

Te haré un breve resumen de lo que haremos para convertir la Imagen:
El Bucket S3 debería enviar un Evento por cada creación de una imagen en el Bucket. Este evento tendrá información de la imagen, no la imagen. Luego de esto, descargamos la imagen con la información del evento, la procesamos y guardamos.

La información que llega desde nuestro Bucket a la función Lambda es la siguiente:

Para ver el evento completo, revisa aquí.

Esta información está localizada en la variable event que viene como parámetro de nuestra función lambda.

Este objeto que nos entrega el BucketS3 contiene información del usuario IAM que agregó la imagen, información del Bucket e información del nuevo Objeto o Imagen creada en el Bucket.

Esta información del Bucket y la información de la imagen, nos servirá más adelante para descargar la imagen y luego procesarla con un nuevo tamaño a su Bucket destino.

Serverless para manejar nuestras funciones Lambda

Serverless Framework nos ofrece un entorno de desarrollo completo en donde podemos crear, testear, publicar y actualizar todas nuestras funciones lambda, así como su configuración de variables y entornos de producción.

Para instalar Serverless solo tenemos que correr npm install -g serverless, internamente él usa las credenciales ya configuradas en aws-cli o la aplicación de consola interactiva de AWS.

Creamos nuestra función lambda con el comando:

sls create --template aws-nodejs --path ServiceNamePath

sls es el alias ya establecido para serverless, este también puedes usarlo.

Una vez se haya creado el proyecto, iremos al archivo handler.js . Este no es más que una plantilla básica para una función Lambda.

Este archivo junto con serverless.yml contiene lo necesario para ejecutar una función lambda satisfactoriamente, como dije anteriormente el parámetro event es en nuestro caso todo el evento de una nueva imagen cargada en el Bucket S3.

Como dependencias de nuestro conversor de imágenes, necesitaremos el SDK de AWS para nodeJSy la librería sharp es quien realizará las operaciones con la imagen descargada. Puedes ejecutar npm install aws-sdk sharp.

Usuarios Windows: npm install — arch=x64 — platform=linux sharp aws-sdk

El paquete de aws-sdk lo usaremos para conectarnos a los Buckets S3 en Amazon y descargar la imagen que nos entregue el evento como también para subir la imagen generada por sharpcon las nuevas propiedades:

Lo primero que hacemos en nuestro código es extraer los datos que necesitaremos para descargar y subir la imagen, en este caso, el nombre del Bucket y la ruta.

Recuerda actualizar tu OUTPUT_BUCKET_NAME con el nombre del Bucket en donde guardarás tus nuevas imágenes.

Una vez tenemos los parámetros listos le solicitamos la imagen al servicio de AWS S3, con:
s3.getObject(params).promise();

Lo que nos retornará getObject(params) es un objeto con la información y la imagen enbase64; Esta es la imagen que fue subida y que será redimensionada para ser subida al Bucket Destino.

sharp(originalImage.Body).resize(400)

Puedes encontrar más información acerca de sharp aquí . No solo puedes cambiar el tamaño con .resize(width) también puedes agregarle textos, filtros, efectos en blanco y negro y algunas otras cosas más… Seguro te servirá en algún interesante proyecto.

Una vez tenemos la imagen con las nuevas propiedades que queremos, procedemos a guardar la imagen en el Bucket destino usando de nuevo la instancia de S3 que nos entrega el AWS-SDK .

Estamos listos para desplegar la función en AWS

Una vez escrito el código que se ejecutará cada vez que se cargue imágenes en nuestro Bucket estamos listos para enviarla a AWS, y allá conectarla con el Bucket al que cargaremos las fotos.

Antes de eso, revisemos el archivo serverless.yml el cual contiene toda la información de despliegue, es decir, las configuraciones que tendrá cuando ya esté corriendo sobre servidores de Amazon.

Si quieres cambiar el nombre de la función antes de ser subida a AWS, puedes ir al archivo .ymly actualizarlo en la sección functions. El nombre por defecto es hello.

Puedes actualizar Hello, por el nombre que quieras darle a tu función lambda una vez subida

Para desplegar la función primero debes tener autenticado tu usuario IAM, si no lo tienes, simplemente escribe aws configure y escribe tus credenciales para poder desplegar la función. El usuario IAM que autentiques, deberá tener permisos de creación de Lambdas/Buckets y Cloud Formation.

Ejecutamos el comando serverless deploy dentro de la carpeta del proyecto y espera unos minutos. Serverless comprimirá tu código en un archivo .zip y lo subirá a AWS con las configuraciones que le diste en el archivo serverless.yml

Hora de conectar Lambda & S3

Lo que nos resta por hacer es ir a nuestra consola de AWS, en la sección de Lambdas: Aquí.

Al abrir nuestra Función Lambda nos encontramos en el Panel o Dashboard de nuestro nuevo servicio.

Para conectar nuestro Bucket a esta función, damos click en agregar desencadenador y nos mostrará un menú para escoger el servicio, en este caso elegimos el servicio de S3

Como ves, hay muchas formas de activar una Función Lambda dentro de AWS, en este caso, la vamos a ejecutar cada vez que se cree un nuevo recurso en nuestro Bucket S3, para configurarlo, elegimos lo siguiente:

Bucket: El nombre de nuestro Bucket S3.
Tipos de evento: Podemos elegir solo POST o la opción de Todos los eventos de creación (incluye PUT & POST).
Prefijo: Si queremos activar evento solo en determinados prefijos/rutas de los archivos. Ejemplo: Un prefijo original/ solo activaría eventos en los archivos agregados dentro de la carpeta original/.
Sufijo: Este parámetro opcional, nos servirá para delimitar ciertos formatos de archivos. Por ejemplo, si quieres decidir puntualmente que formatos de imagen transformar y cuales excluir.

Una vez hayamos activado del desencadenador de nuestra Función Lambda, veremos algo como esto:

Al activar el Desencadenador también estás agregando permisos y roles de ejecución al Bucket S3 y también a la función Lambda, todo esto para comunicarse entre ellos dentro de AWS.

Listo! Buckets S3 y Lambda conectados y listos para funcionar

Resultado de imagen en bucket original a bucket destino

Después de esto, ya debería estar funcionando tu conversor de imágenes ejecutado por una función lambda en AWS. Cada vez que subas una nueva imagen, una función lambda es ejecutada para crear su versión tumbnail de 400Px de ancho.

Si estás teniendo problemas con permisos al acceder a tus Buckets cuando vas a guardar o descargar tus imágenes, ve a la pestaña permisos, y Click en el nombre del rol (Sí, el de azul).

Verifica que tenga los permisos para acceder a los Buckets y si no es el caso, ve a “Asociar Políticas” y le agregas la que está marcada en la imagen.

Espero te haya gustado el artículo. Estaré subiendo uno cada semana, usando diferentes servicios de AWS para Activar funciones Lambda.

Twitter: @FlavioAandres

--

--

Flavio AAndres

I like to experiment with all. Backend developer at @condorlabs.io. NodeJS/AWS/Serverless/+