Distintas maneras de trabajar con AWS Lambda

Serverless es una de las palabras más de moda en los entornos tecnológicos y no en vano. Todos los gigantes del Cloud están desplegando servicios que nos permiten abstraernos de la infraestructura subyacente para poder desplegar nuestro código de forma rápida, potente y con una fácil integración con el resto de servicios de sus plataformas.

En concreto Amazon Web Services hace ya tiempo que ofrece su servicio AWS Lambda, que permite ejecutar código Java, Node.js, C# y Python (hasta el momento) sin servidores.

AWS Lambda trabaja supuestamente sin servidores y permite al desarrollador obviar conceptos como VPC, subredes, tablas de rutas y zonas de disponibilidad, o por lo menos, le permiten tener un conocimiento menos profundo de estos conceptos.

Nos centramos en este post en exponer las distintas formas de gestionar, tanto la parte de red como la integración continua, en entornos que usen este Servicio de AWS. Cada una de ellas tiene su parte positiva y negativa, lo veremos a continuación.

La realidad es que se puede trabajar de dos formas con AWS Lambda, definiendo los valores VPC y Subnet o sin definirlos.

Vamos a ver un ejemplo real de la consola de administración de AWS:

La captura anterior refleja los parámetros de configuración avanzada de una Lambda que, como se puede observar, está asignada a un VPC concreto. En el caso de la imagen anterior, la función corre dentro de nuestro segmento de red, consumiendo recursos de red.

Para garantizar la alta disponibilidad del servicio de Lambda, AWS recomienda asignar al menos dos subredes, fundamentalmente para que no haya dependencia de una única zona de AWS.

En este caso, al no tener un VPC configurado, la función se ejecuta en servidores que están en segmentos de red específicos de AWS y gestionados por ellos. De esta forma, la Lambda accede a nuestros VPC (segmentos de red privada) a través de Internet.

La forma que elijamos para trabajar condiciona notablemente la seguridad y gestión de la configuración del proyecto.

Lambdas e integración continua

La integración continua permite en los proyectos desarrollar versiones mejoradas de código a la vez que integramos el mismo con otros proveedores. Y, por supuesto, da un soporte a todos los posibles bugs e incidencias que puedan surgir en entornos productivos.

Se considera una buena práctica de seguridad tener entornos de trabajo diferenciados a nivel de red de forma que, por ejemplo, no podamos conectarnos desde un entorno de Desarrollo a uno de Producción.

Esto supone que debemos tener distintas subredes para cada entorno (VPCs) y, a ser posible que por seguridad, nuestras bases de datos no sean accesibles desde un entorno al otro. Es decir, que las lambdas del entorno de producción no puedan acceder a las de preproducción.

¿Qué conseguimos con esto? Evitar errores humanos fatales, como por ejemplo, que nos equivoquemos al definir un parámetro de la configuración y pongamos que el endpoint de la base de datos de preproducción es el de producción. En caso de haber segmentación de red, este error no tendría casi importancia.

Una de las soluciones que hemos encontrado para trabajar con integración continua y AWS  Lambda al mismo tiempo es el uso de alias y versiones en las funciones. Una misma función lambda puede tener varias versiones y alias. De esta forma, para una misma versión de código, poder desplegar en varios entornos usando los alias.

Hasta aquí todo suena bien. El problema es que si usamos esta funcionalidad de Lambda necesitamos una única lambda para todos los entornos y, por lo tanto, su configuración debe permitir el acceso a todos los entornos.

Lo correcto sería que la lambda estuviera definida en un VPC aislado (uno por entorno) incluyendo dentro de la configuración de la lambda los ids del VPC y subredes. El problema, entonces, es que esa lambda sólo accedería a los recursos de ese VPC y no se podrían utilizar los alias para desplegar en los entornos.

Segmentación de red y almacenamiento

Otro de los problemas que detectamos es el de la seguridad de red cuando se quiere gestionar la persistencia de datos, por ejemplo, con una base de datos. Si usamos, por ejemplo, AWS RDS hay que definir las subredes del VPC en que queremos que se cree la base de datos.

La forma más segura de hacer esto es definir redes privadas que no dispongan en sus tablas de rutas ninguna regla que enrute a través de un Internet Gateway, es decir, subredes que sean totalmente inaccesibles desde Internet.

Sin embargo, cuando usamos lambdas sin configurar los campos VPC y subred, para acceder a nuestras bases de datos, Lambda necesita que estas sean accesibles por Internet.

De nuevo, la solución pasa por particularizar la Lambda para que esté dentro del VPC. Esta configuración, aunque aumenta notablemente la seguridad de la Lambda y permitiría que todo el tráfico fuera interno al VPC (requerido para algunos clientes o proyectos), perdería la sencillez que supone definir una lambda y olvidarte de la infraestructura, pues una de las recomendaciones de AWS al respecto consiste en dimensionar la capacidad de red del VPC para que las lambdas puedan autoescalar sin problema.

Alta disponibilidad y seguridad

Por último, una de las ventajas que ofrece AWS Lambda como servicio gestionado por AWS es la capacidad de tener alta disponibilidad, es decir, no depende de que haya problemas en una zona de disponibilidad u otra, porque AWS Lambda es un servicio que reparte la carga entre múltiples zonas.

Esto no sería posible si desplegamos las funciones en nuestro propio VPC. Para seguir teniendo alta disponibilidad, después de recluir las Lambdas en nuestro segmento de red privado, deberíamos configurar una arquitectura como la siguiente:

Como se puede observar, para que no tengamos cuellos de botella o puntos débiles en nuestra arquitectura, habría que habilitar un Nat Gateway específico para cada zona de disponibilidad.

Esta arquitectura supone tener 3 subredes privadas, 3 públicas, 3 Nat Gateway, un Internet Gateway… no se trata de algo muy complejo, pero desde luego no es tan sencillo como la opción de trabajar con Lambda autogestionada.

Conclusiones

En definitiva, no es oro todo lo que reluce. En las arquitecturas Cloud hay que ser muy consciente de los niveles de seguridad y disponibilidad del proyecto.

Si el tráfico ha de ser privado a nivel de red y no podemos permitirnos que haya pérdida de servicio, es posible que tengamos que arremangarnos y bajar a nivel de VPC y dimensionamiento de red y, por lo tanto, perder muchos de los beneficios que promete el concepto de Serverless y en concreto el servicio de AWS Lambda.

Escribe un comentario