Antes de empezar a desarrollar nuestra primera función usando AWS Lambda hay unos conceptos básicos que debemos entender. Podríamos solo saltar al código, entrar a la consola de AWS y probar nuestra función sin entender nada, pero dentro del mundo del desarrollo de software las cosas no son tan simples, siempre tenemos que resolver algún problema y nos apoyamos en la tecnología para hacerlo, por lo que muchas veces no entender la base de las cosas nos puede perjudicar. Entonces, ¿que debemos saber antes de crear nuestra primera función Lambda?
  1. ¿Que es Serverless Computing?
  2. ¿Que es AWS Lambda? Pero para no hacer este Post muy extenso y cansado vamos a asumir que sabes lo básico de Amazon Web Services y que has trabajado con la nube y algún lenguaje de programación como Python o Nodejs.

¿Que es Serverless Computing?

Traducido literal al español Serverless Computing es computación sin servidor, y no quiere decir que nuestra aplicación no corra sin ningún servidor, todo servicio que nos da la nube tiene una capa física en su nivel más bajo, en este caso Serverless Computing quiere decir que nosotros, como desarrolladores no vamos a administrar ningún recurso de infraestructura para nuestra aplicación, todos los recursos que requiere nuestro código para ser ejecutado serán administrados por el proveedor, por lo que nosotros nos enfocamos solo en desarrollar bien nuestro código.

¿Que es AWS Lambda?

Según la definición que nos da Amazon Web Services, AWS Lambda es:

...un servicio informático sin servidor y basado en eventos que le permite ejecutar código para prácticamente cualquier tipo de aplicación o servicio backend sin necesidad de aprovisionar o administrar servidores.

Dentro de esta definición hay algunas cosas que debemos notar, como lo son:
  1. Lambda es basado en eventos, esto quiere decir que los recursos necesarios para ejecutar nuestra función se van a aprovisionar solo cuando esta sea invocada desde algún otro lugar, por lo que AWS solo nos va a cobrar por el tiempo que se ejecute nuestra función.
  2. Permite ejecutar código para prácticamente cualquier tipo de aplicación, una función Lambda la podemos integrar con diferentes servicios para usarla en base a nuestras necesidades, algunos ejemplos de esto son:
    • API Gateway para ejecutar nuestra función desde una API.
    • Trigger de una tabla de DynamoDB.
    • Trigger de un bucket de S3.
    • Un Cron Job con Cloudwatch para ejecutar nuestra función cada cierto tiempo.
  3. No hay necesidad de aprovisionar o administrar servidores, al ser Lambda un servicio administrado por AWS toda la infraestructura en la que funcionará nuestra función es administrada por ellos, entre las ventajas que nos da esto es:
    • Nuestra función escala en base a la demanda y se ajusta a miles de peticiones por segundo sin problemas.
    • No nos debemos preocupar por el sistema operativo sobre el que corre o si las versiones del lenguaje son las correctas al momento de migrar al servidor.
    • Si nuestra función no se ejecuta no nos cobrarán.

Limitantes de AWS Lambda

Luego de ver que es Lambda debemos saber que tenemos ciertas limitantes que debemos tomar en cuenta para decidir si nuestro proyecto es apto para utilizar esta tecnología o tenemos que ver alguna forma más tradicional de tener nuestra aplicación en la nube. Entre las principales están:
  • El tiempo máximo de ejecución de nuestra función es de 15 minutos, si por alguna razón nuestro código tarda más de ese tiempo la ejecución de la función se detiene sin importar la acción que esté realizando.
  • Si vamos a realizar una RestAPI debemos saber que nuestra función se va a llamar desde otro servicio llamado API Gateway que tiene un timeout de 30 segundos, por lo que, aunque la función tenga un máximo de ejecución de 15 minutos nuestra API nos responderá con timeout luego de 30 segundos.
  • Debemos adaptar nuestro desarrollo a la estructura, es algo sencillo pero se debe tomar en cuenta.
  • Hacer pruebas locales no es tan fácil como la forma tradicional con aplicaciones que desarrolamos normalmente (en el caso de Nodejs no es lo mismo realizar un backend con estos servicios de AWS que realizarlo con Express).
  • Debido a que las implementaciones Serverles de funciones como servicio son especificas de cada proveedor de nube es complicado moverse entre distintos proveedores, tendríamos que modificar nuestro código para migrar de AWS a Azure o GCP, por ejemplo.

¿Como puedo crear mi primera función?

Existen distintas maneras de crear funciones Lambda, la más sencilla es hacerlo desde la consola de AWS, esto nos creará una función individual.
  1. Debemos ingresar a la consola de administración de AWS Lambda https://us-east-2.console.aws.amazon.com/lambda
Consola de AWS Lambda
  1. Hacemos click en el botón de Crear Función (Create Function en inglés).
Boton crear funcion
  1. En la página de crear función debemos llenar los campos
    • Function Name, para este ejemplo el nombre de nuestra función será LambdaTest.
    • Runtime, este es el lenguaje en el que vamos a desarrollar nuestra función, para este ejemplo usaremos Python 3.9.
Pagina de crear funcion rellenada
Podemos observar que en la parte superior de la consola nos muestra las opciones: - Author from scratch: Nos permite crear funciones desde cero, empezaremos con el template de Hello World que provee AWS. - Use a blueprint: Nos permite crear una función basada en distintos casos de uso con el código base ya implementado. - Container image: En esta opción podemos cargar un Runtime personalizado para poder utilizar el lenguaje que necesitemos y que no se encuentre dentro de los que nos provee AWS. - Browse serverless app repository: Esta opción nos permite crear una aplicación completa basada en funciones Lambda (tiene más de una función y puede tener distintos recursos, no solo funciones Lambda). En la parte inferior del sitio podemos ver una sección expandible con el texto Change default execution role.
change default execution role
AWS nos muestra esta sección debido a que las funciones necesitan tener permisos para poder ejecutarse y para poder acceder a otros servicios (por ejemplo obtener registros de una tabla en DynamoDB, ejecutar otras funciones Lambda, cargar archivos a un bucket de S3, etc), si no le asignamos permisos, por defecto AWS nos creará un rol con los permisos mínimos para ejecutar nuestra función. En esta parte tenemos tres opciones:
  • Create a new role with basic Lambda permissions: Es la opción por defecto, que nos permite crear un rol con los permisos básicos para ejecutar la función.
  • Use an existing role: Nos permite seleccionar un rol ya existente.
  • Create a new role from AWS policy templates: Nos permite crear un rol basado en plantillas que tienen definidos permisos para realizar acciones en otros servicios en AWS.
Por el momento dejaremos seleccionada la primera opción para que AWS nos ayude a crear un rol con los permisos básicos para ejecutar nuestra función.
  1. Hacemos click en el botón Create Function.
Al terminar de crear la función nos mostrará la página principal de nuestra función:
LambdaTest creada
Antes de probar nuestra función o seguir desarrollandola debemos entender el código que está en el editor que nos muestra AWS (es bastante sencillo), el código es:
import json def lambda_handler(event, context): # TODO implement return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') }
Podemos observar que es un import y una función que retorna un json, pero lo más importante acá es la definición de esa función ya que esa función es la que se va a ejecutar cuando se invoque a nuestra lambda, en esta debemos notar ciertas cosas:
  • El nombre de la función debe estar definido en la sección RuntimeSettings (esta se encuentra abajo del editor), acá podemos ver que hay un apartado llamado Handler el cual está conformado por file_name.function_name, que para nuestro ejemplo es lambda_function.lambda_handler. Si lo necesitamos podemos modificar esas configuraciones, pero también debemos modificar el nombre del archivo y el nombre de la función en base a nuestros cambios.
  • Los parámetros que recibe la función son dos:
    1. event: este contiene los datos de entrada de nuestra función, puede variar dependiendo del trigger que invoque a la lambda
    2. context: este corresponde al contexto sobre el cual se está ejecutando la función, son datos sobre el entorno de ejecución.
Para su ejecución la función necesita recibir estos dos parámetros, es la estructura básica de la función, y dependiendo de cual sea el evento desde el que se llame es la respuesta que debemos dar, eso lo podemos encontrar en la documentación de AWS Lambda. Para este ejercicio no usaremos ningún evento que invoque nuestra función, ya que el objetivo es aprender a crear funciones y entender como usarlas.

¿Cómo pruebo mi función?

Para hacer pruebas necesitamos definir un evento, que es el que se va a recibir en el parametro event. Para esto nos dirigimos a la tab Test
AWS Lambda Test
Dentro de este vemos distintas opciones que nos ayudarán a crear eventos de prueba para nuestra función, y esto basado en nuestras necesidades. Lo primero es seleccionar la acción a realizar, nosotros vamos a seleccionar Create new event, luego ingresamos el nombre, como LambdaTestEvent. Dentro de las opciones para compartir el evento (Event sharing settings) lo dejamos por defecto. Ahora lo más importante, ¡El evento! Podemos ver que actualmente hay una plantilla seleccionada, esta es la plantilla de hello-world, y este es un ejemplo de como podemos definir nuestro evento, como se observa el evento es un objeto en formato JSON. Dentro de las platillas que nos da AWS para nuestras pruebas podemos ver que hay muchas para distintas integraciones que podemos hacer de sus servicios con las funciones lambda. Para el ejemplo actual vamos a dejar tal y como está el evento, podemos modificarlo por otro JSON válido pero no hará diferencia en la ejecución de la función. Luego presionamos el botón Save, este guardará el evento que creamos para que en futuras ocasiones podamos utilizar el mismo para probar nuestra función. Si queremos usar el evento una sola vez solo presionamos el botón Test. Si todo funcionó correctamente deberíamos ver una pantalla así, con la opción de editar nuestro evento habilitada.
AWS Lambda test creado
Si regresamos a la tab Code y presionamos el botón Test vemos que se abre una nueva pestaña en el editor con el output de la ejecución.
Lambda probada desde Code
Si presionaste el botón Test desde la tab Test, el output de la función se mostrará como alerta en la parte superior (siempre dentro de la misma tab), de la siguiente forma:
Lambda probada desde Test
En cualquiera de los casos la información es la misma. Dentro de esta podemos ver:
  • Response que es lo que retorno nuestra función (podemos ver el JSON que está en el return.
  • Function Logs que contiene, además de información que muestra AWS por defecto, cualquier cosa que imprimamos a consola (un console.log(), print(), etc).

Cosas a tomar en cuenta

Cuando se está desarrollando una aplicación con esta tecnología, o una función debemos tomar en cuenta varias cosas:
  1. El SDK de AWS viene incluido por defecto en cualquier función en cualquier lenguaje. Se puede consultar la documentación del SDK en cada lenguaje en la documentación oficial
  2. No debemos subir variables de entorno a la función, esto ya que podemos asignar un Rol directamente a la función con los permisos necesarios y esta obtendrá claves de acceso de IAM con cada ejecución. (más información aquí)
  3. Perfectamente podemos editar el código de nuestra función en el editor de AWS, pero desde aca no podemos instalar librerías.
  4. El peso máximo que debe tener nuestra función (tomando en cuenta todo lo que debamos subir como los node_modules) es de 10MB como máximo, si se supera ese peso ya no podras editar el código en línea, y se deberá utilizar otro método para cargar el código.
  5. Podemos definir muchas funciones y usar muchos archivos dentro de una Lambda, pero siempre el punto de inicio será el mismo.
  6. Este es muy importante, ya que no podemos escribir archivos dentro de la lambda en tiempo de ejecución, para esto debemos trabajar de otra forma, como tener el contenido en memoria y escribirlo en un bucket de S3, usar un EFS o buscar otra forma de manejar archivos (siempre esto va a depender de nuestras necesidades).
  7. Cuando se utilizan las funciones lambda como backend para una APIRest se debe tomar en cuenta que API Gateway tiene un timeout de 30 segundos, por lo que la función no podrá devolver nada después de ese tiempo, aunque estas tenga un tiempo de ejecución de hasta 15 minutos.