Desplegar funciones Lambdas usando Layers con Java
Published: 2023-01-22 20:54:45

El servicio de AWS Lambas ofrece una gran variedad de configuraciones, con el objetivo de minimizar costos, optimizar código y mejorar tiempos de respuesta. En esta ocasión se hará uso de Layers para centralizar las dependencias/libs (jars) en un solo lugar, y que todas las lambdas desplegadas puedan acceder a esa configuración donde se almacenan las dependencias.

## Layers o Capas AWS Lambda

AWS Lambda Layers es una característica de AWS Lambda que permite a los desarrolladores empaquetar y reutilizar código común en múltiples funciones. Esta característica se puede utilizar para compartir bibliotecas de código, tiempos de ejecución personalizados y otras dependencias entre funciones, lo que puede simplificar el proceso de desarrollo y reducir el tamaño de los paquetes de implementación.

Uno de los principales beneficios de utilizar Layers en Lambda es que permite a los desarrolladores separar el código de las dependencias, esto permite actualizar las dependencias en un solo lugar y no tener que hacerlo en cada función, esto también reduce el tamaño de los paquetes de implementación ya que las dependencias no se incluyen en cada función.

La imagen proporcionada por [DZone](https://dzone.com/articles/aws-lambda001-aws-layers) sobre Layers en Lambdas es super simple de entender. Con el uso de Lambda Layers podemos centralizar todas las dependencias en un solo lugar, y las definiciones de las funciones lambdas deben tener la capacidad de consumir dicho repositorio para realizar las tareas sin problemas, además de que el tamaño de las funciones van a ser muy ligeras.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1lqaxy2yz16n3n5y61fh.png)

## Ejercicio AWS Lambda Layers

Para mostrar el uso de Lambda Layers se usa un proyecto dummy en Java con dos lambdas para desplegar con la ayuda de _SAM CLI_.

> Nota: Este ejercicio se ha realizdo en un SO Linux (Mint).

**Configuración de Layers**

Para configurar un Layer se usa las plantillas de AWS CloudFormation con la extensión del framework SAM, el tipo de recurso a crear es `AWS::Serverless::LayerVersion`.

``` yaml
Resources:
  LabsLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: !Sub ${AWS::StackName}-LabsLayer
      Description: Layer libs for kc-labs-serverless
      ContentUri: kc-labs-app/dependencies
      CompatibleRuntimes:
        - java11
        - java8
      CompatibleArchitectures:
        - x86_64
      LicenseInfo: "MIT"
      RetentionPolicy: Retain
...
...
```
En las definiciones de las funciones lambdas se debe vincular el layer creado:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hzjjd4gpgwpp7tyvncy5.png)

> Nota: Se configura la propiedad Metadata para personalizar la construcción del empaquetado de las funciones lambdas.

**Librerías de proyecto en pom.xml**

Para este ejercicio se tienen algunas dependencias usadas en el proyecto de Lambdas.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w9dufxv3nuwswnzofnba.png)

**Makefile**

En la raiz del proyecto de Java se debe crear un archivo Makefile:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2yrtis92e4jijhyz1x3.png)

``` sh
build-lambda:
	cp -rf ./target/classes/* $(ARTIFACTS_DIR)/

build-LabsGreetingsGETHelloLambda: build-lambda

build-LabsGreetingGETNameLambda: build-lambda
```

Dentro de ese archivo se configura el comando para copiar las definiciones de nuestras clases, ahí estarán los _handlers/manejadores_ de entrada para las lambdas. En este caso se tiene dos lambdas, se debe configurar con el nombre lógico para cada lambda.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sea48nqen8x6sux0rakx.png)

**Construir proyecto**

Dentro de la raíz del proyecto Java se ejecutan los siguiente comandos.

Para construir el empaquetado del proyecto:

`mvn clean package`

Para obtener todas las dependencias (jars) usadas en el proyecto en una carpeta:

``` sh
mvn dependency:copy-dependencies -DoutputDirectory=dependencies/java/lib -Dmdep.prependGroupId=true -DexcludeScope=provided
```

> Nota: Verificar que la carpetas target y dependencies/java/lib hayan sido creadas.

> Nota: Verificar la ruta de la capa, para cada runtime es diferente: [Layer dependecies.](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-path)

Un directorio más atrás donde esta definido el archivo template.yaml ejecutar el comando:

`sam build`

Finalmente para desplegar usar el comando:

`sam deploy` o `sam deploy --guided` si es un primer despliegue.

**Resultados**

Una vez desplegado el stack se puede verificar las lambdas desde la consola de Lambda en la sección Code:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1sdhtwtik3iaetgljibd.png)

Se puede verificar que la lambda pesa muy poco, esto debido a que no se esta incluyendo las dependencias jars para cada lambda.

Se verifica la creación del layer:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z6bi4szjj8dkp7dsukr6.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8joffvb7t96dvxu2nugd.png)

Con la creación de este layer todas las lambdas tienen la posibilidad de acceder a este recurso para consumir las dependencias que se hayan subido.

## Conclusiones

- AWS Lambda Layers es una característica poderosa que permite a los desarrolladores reutilizar código y dependencias en múltiples funciones, lo que simplifica el proceso de desarrollo y reduce el tamaño de los paquetes de implementación. 

- Esta característica también permite actualizar las dependencias en un solo lugar y compartir código entre múltiples funciones, esto ayudaría a la escalabilidad de la aplicación debido a que se puede tener diferentes capas para cada responsabilidad y las lógicas de negocio aisladas del handler principal.

- Si la capa layer es bastante pesada es considerable usar un bucket de S3 y referenciar ese bucket en la creación del Layer.

## Referencias
- https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html
- https://dzone.com/articles/aws-lambda001-aws-layers
- https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html
- https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-layerversion.html