Serverless compose
Seguimos hablando de arquitectura serverless, estaba vez una nueva herramienta se lanzó recientemente, que realmente está muy interesante y que a las personas que trabajamos con estructuras mono-repo será de mucha ayuda, para dar un poco de contexto, cuando hablamos de microservicio ya he hablado bastante sobre el tema de las dependencias y como cada servicio debe ser totalmente independiente, sin embargo, cuando se despliega se puede requerir algún valor de otro microservicio, esto sencillamente porque un servicio necesita encontrar a otro, lo cual puede llegar a generar algunas 'dependencias' a la hora de realizar despliegues, en el caso de serverless framework, existen algunas estrategias apalancadas sobre cloudformation, el inconveniente con esto, es que este es un universo entero, y esto puede hacer un poco complicado como referenciar alguna salida de un servicio a otro, por eso llega al juego serverless compose Ver Figura 1, el cual es básicamente un orquestador de proyectos realizados para serverless con la finalidad de facilitar su despliegue a producción, en diferentes tecnologías ya existen un montón de orquestadores similares, para no ir muy lejos podemos referenciar uno muy conocido que es docker-compose este artículo lo dedicaremos a hablar un poco sobre esta nueva tool
CloudFormation en serverless
Una de las cosas interesantes que hace serverless framework es utilizar por debajo todo el stack de CloudFormation, generando una abstracción para que el desarrollador no tenga esa complejidad, este beneficio nos lleva a que en cierto momento del despliegue vamos a necesitar exportar algunas variables que otros servicios requieren, por ejemplo tenemos los siguientes archivos
este es el ejemplo perfecto para la necesidad de usar compose, en el ejemplo anterior tenemos dos archivos de dos proyectos en el mismo repo, shared/serverless.yml el cual consiste en la creación de un layer, es decir, una capa compartida entre diferentes lambdas, si ven, al final del código se hace un export de ese layer, aquí se utiliza CloudFormation, luego en user/serverless.yml en el layer se utiliza la siguiente instrucción
${cf:libs-dev.SharedLibsExport}
esta instrucción importa del CloudFormation la variable que se exportó en el layer, esto puede volverse tan complejo como se quiera, por ejemplo traer esta variable por diferentes ambientes, y una validación que no se tiene en cuenta, es que necesariamente el invocarla, no garantiza que existe, entonces después del despliegue esto puede generar error, por esto manejar la importación de variables se vuelve complejo, porque la creación y el uso de las variables no están sincronizadas, para esa sincronización utilizaremos serverless-compose
Serverless Compose
serverless-compose esta herramienta nos ayudará a realizar múltiples despliegues utilizando la estrategia mono-repo, solamente referenciando un archivo centralizado el cual agrupa las referencias a los demás proyectos, el ejemplo anterior lo mejoraríamos de la siguiente forma
de estos archivos el que cambio fue el del usuario, ahora se usa la instrucción
layers:
-${param:my-layer}
esta instrucción viene del siguiente archivo que agregamos a la raíz y llamaremos serverless-compose.yml
services:
shared-layer:
path: src/shared/libs
user:
path: src/user
params:
my-layer: ${shared-layer.SharedLibsExport}
dependsOn:
- shared-layer
este archivo tiene todas las configuraciones compartidas, adicional para que sea compatible serverless con servelress-compose, se tiene que usar la versión > v3.15.0, este archivo serverless-compose.yml tiene las siguientes instrucciones
- services inicia la configuración y abre el espacio para agregar el nombre de los servicios, este es irrelevante y puede ser cualquier nombre
- path es la ubicación del proyecto, o donde se puede encontrar el archivo serverless.yml
- params, son todos los valores que se exportan usando CloudFormation, y que se usaran como valores dependientes entre servicios
- dependsOn le indica a serverless que ese servicio depende de 1 o más servicios que primero deben ser desplegados
- config es un parámetro opcional el cual es usado si el archivo de serverless tiene un nombre diferente, ejemplo serverless.api.yml
para ejecutar el compose nos ubicamos en donde se encuentra el archivo y ejecutamos
sls deploy --stage dev
con esto se realiza el despliegue de la siguiente forma
si ven shared-layer se despliega de primero, esto debido a la dependencia, y seguidamente se despliega el servicio que es dependiente, hay otros comandos interesantes los cuales se pueden encontrar en la documentación, por ejemplo uno que me gusta mucho es
serverless logs
cuando se desea bajar el stack igualmente se ejecuta el comando
sls remove
y también los remueve en orden de dependencias, primero los no dependientes, luego los dependientes, este enfoque definitivamente es muy interesante y otorga una solución bastante usable para estos problemas de variables y referencias entre servicios, finalmente les dejo el repositorio con todo el código usado
Conclusiones
Orquestar servicios siempre será una necesidad, esta herramienta es totalmente amigable para integrarse con entornos de ci-cd, y permite compartir dependencias de despliegue de una forma sencilla, el roadmap de serverless-compose apunta a tener otros beneficios interesantes, uno de ellos el despliegue multi región. En conclusión, este tool es algo me parece, es un gran acierto, que además suple las necesidades de los devs y ops