Uso de capas para funciones de Lambda en TypeScript - AWS Lambda

Uso de capas para funciones de Lambda en TypeScript

Una capa de Lambda es un archivo .zip que contiene código o datos adicionales. Las capas suelen contener dependencias de biblioteca, un tiempo de ejecución personalizado o archivos de configuración. La creación de una capa implica tres pasos generales:

  1. Empaquete el contenido de su capa. Esto significa crear un archivo de archivo. zip que contenga las dependencias que desea usar en sus funciones.

  2. Cree la capa en Lambda.

  3. Agregue la capa a sus funciones.

Este tema contiene los pasos y las instrucciones sobre cómo empaquetar y crear correctamente una capa de Lambda en Node.js con dependencias de bibliotecas externas. Además, en este tema se explica cómo usar la capa con una función escrita en TypeScript.

Requisitos previos

Para completar los pasos de esta sección, debe disponer de lo siguiente:

A lo largo de este tema, haremos referencia a la aplicación de ejemplo layer-nodejs en el repositorio de GitHub aws-lambda-developer-guide. Esta aplicación contiene scripts que empaquetará la biblioteca lodash en una capa de Lambda. El directorio layer contiene los scripts para generar la capa. La aplicación también contiene una función de ejemplo de TypeScript en el directorio function-ts que utiliza la dependencia de las capas. Tras crear una capa, puede transpilar, implementar e invocar la función correspondiente para comprobar que todo funciona. Este documento explica cómo crear, empaquetar, implementar y probar esta capa con la función de muestra de TypeScript.

Esta aplicación de ejemplo utiliza el tiempo de ejecución de Node.js 20. Si agrega dependencias adicionales a la capa, deben ser compatibles con Node.js 20.

Compatibilidad de la capa Node.js con el tiempo de ejecución de Lambda

Al empaquetar el código en una capa de Node.js, se especifica el tiempo de ejecución de Lambda con el que es compatible el código. Para evaluar la compatibilidad del código con un tiempo de ejecución, tenga en cuenta las versiones de Node.js, los sistemas operativos y las arquitecturas de conjunto de instrucciones para las que está diseñado el código.

Los tiempos de ejecución de Node.js de Lambda especifican su versión y sistema operativo de Node.js. En este documento, utilizará el tiempo de ejecución de Node.js 20, que se basa en AL2023. Para obtener más información acerca de las versiones de tiempo de ejecución, consulte Tiempos de ejecución admitidos. Cuando crea una función de Lambda, especifica la arquitectura del conjunto de instrucciones. En este documento, utilizará la arquitectura arm64. Para obtener más información acerca de las arquitecturas en Lambda, consulte Configuración y selección de la arquitectura del conjunto de instrucciones para una función de Lambda.

Cuando se utiliza el código incluido en un paquete, cada responsable del paquete define de forma independiente su compatibilidad. La mayoría del desarrollo de Node.js está diseñado para funcionar independientemente del sistema operativo y de la arquitectura del conjunto de instrucciones. Además, no es muy común romper las incompatibilidades con las nuevas versiones de Node.js. Espere dedicar más tiempo a evaluar la compatibilidad entre paquetes que a evaluar la compatibilidad de los paquetes con la versión, el sistema operativo o la arquitectura del conjunto de instrucciones de Node.js.

A veces, los paquetes de Node.js incluyen código compilado, por lo que es necesario tener en cuenta la compatibilidad entre el sistema operativo y la arquitectura del conjunto de instrucciones. Si necesita evaluar la compatibilidad del código de sus paquetes, tendrá que inspeccionar los paquetes y su documentación. Los paquetes de NPM pueden especificar su compatibilidad a través de los campos engines, os y cpu de su archivo de manifiesto package.json. Para obtener más información sobre los archivos package.json, consulte package.json en la documentación de NPM.

Rutas de capa para tiempos de ejecución de Node.js

Cuando agrega una capa a una función, Lambda carga el contenido en el entorno de ejecución. Si su capa empaqueta las dependencias en rutas de carpetas específicas, el entorno de ejecución de Node.js reconocerá los módulos y podrá hacer referencia a los módulos desde el código de su función.

Para asegurarse de que los módulos se recogen, empaquételos en el archivo .zip de la capa, en una de las siguientes rutas de carpeta. Estos archivos se almacenan en /opt y las rutas de las carpetas se cargan en la variable de entorno PATH.

  • nodejs/node_modules

  • nodejs/nodeX/node_modules

Por ejemplo, el archivo .zip de capa resultante que cree en este tutorial tiene la siguiente estructura de directorios:

layer_content.zip └ nodejs └ node20 └ node_modules └ lodash └ <other potential dependencies> └ ...

Colocará la biblioteca lodash en el directorio nodejs/node20/node_modules. Esto garantiza que Lambda pueda localizar la biblioteca durante las invocaciones de funciones.

Empaquetado del contenido de la capa

En este ejemplo, empaqueta la biblioteca lodash en un archivo .zip de capa. Siga los pasos que se indican a continuación para instalar y empaquetar el contenido de la capa.

Instalación y empaquetado del contenido de la capa
  1. Clone el repositorio de aws-lambda-developer-guide de GitHub, que contiene el código de muestra que necesita en el directorio sample-apps/layer-nodejs.

    git clone https://github.com/awsdocs/aws-lambda-developer-guide.git
  2. Navegue hasta el directorio layer de la aplicación de ejemplo layer-nodejs. Este directorio contiene los scripts que usa para crear y empaquetar la capa correctamente.

    cd aws-lambda-developer-guide/sample-apps/layer-nodejs/layer
  3. Asegúrese de que el archivo package.json enumere lodash. Este archivo define las dependencias que desea incluir en la capa. Puede actualizar este archivo para incluir cualquier dependencia que desee en su capa.

    nota

    El archivo package.json que se utiliza en este paso no se almacena ni se utiliza con las dependencias después de cargarlas en una capa de Lambda. Solo se usa en el proceso de empaquetado de capas y no especifica un comando de ejecución ni una compatibilidad como lo haría el archivo en una aplicación de Node.js o en un paquete publicado.

  4. Asegúrese de tener permiso del intérprete de comandos para ejecutar los scripts del directorio layer.

    chmod 744 1-install.sh && chmod 744 2-package.sh
  5. Ejecute el script 1-install.sh mediante el siguiente comando:

    ./1-install.sh

    Este script ejecuta npm install, que lee el archivo package.json y descarga las dependencias definidas en él.

    ejemplo 1-install.sh
    npm install .
  6. Ejecute el script 2-package.sh mediante el siguiente comando:

    ./2-package.sh

    Este script copia el contenido del directorio node_modules a un nuevo directorio denominado nodejs/node20. Luego, comprime el contenido del directorio nodejs en un archivo llamado layer_content.zip. Este es el archivo .zip para su capa. Puede descomprimir el archivo y comprobar que contiene la estructura de archivos correcta, como se muestra en la sección Rutas de capa para tiempos de ejecución de Node.js.

    ejemplo 2-package.sh
    mkdir -p nodejs/node20 cp -r node_modules nodejs/node20/ zip -r layer_content.zip nodejs

Creación de la capa

Seleccione el archivo layer_content.zip que generó en la sección anterior y cárguelo como una capa de Lambda. Puede cargar una capa mediante la AWS Management Console o la API de Lambda en la AWS Command Line Interface (AWS CLI). Al cargar el archivo .zip de la capa, en el siguiente comando de AWS CLI PublishLayerVersion, especifique nodejs20.x como tiempo de ejecución compatible y arm64 como arquitectura compatible.

aws lambda publish-layer-version --layer-name nodejs-lodash-layer \ --zip-file fileb://layer_content.zip \ --compatible-runtimes nodejs20.x \ --compatible-architectures "arm64"

En la respuesta, anote el LayerVersionArn, que tiene este aspecto: arn:aws:lambda:us-east-1:123456789012:layer:nodejs-lodash-layer:1. Necesitará este nombre de recurso de Amazon (ARN) en el siguiente paso de este tutorial cuando agregue la capa a la función.

Adición de la capa a la función

Implemente una función de Lambda de ejemplo que utiliza la biblioteca lodash en su código de función y, a continuación, adjunte la capa. Para crear una función de Lambda mediante el código de función escrito en TypeScript, debe transpilar TypeScript a JavaScript para que lo utilice el tiempo de ejecución de Node.js. Para obtener más información acerca de este proceso, consulte Definir el controlador de funciones de Lambda en Typescript. Para una mejor compatibilidad, use tsc para transpilar el módulo de TypeScript cuando distribuya las dependencias con capas. Si agrupa las dependencias, considere la propiedad de usar esbuild. Para obtener más información sobre la agrupación con esbuild, consulte Implementar código de TypeScript transpilado en Lambda con archivos .zip.

Para implementar la función, necesita un rol de ejecución. Para obtener más información, consulte Definición de permisos de funciones de Lambda con un rol de ejecución. Si no dispone de un rol de ejecución existente, siga los pasos de la sección desplegable. De no ser así, vaya a la siguiente sección para implementar la función.

Para crear un rol de ejecución
  1. Abra la página Roles en la consola de IAM.

  2. Elija Crear rol.

  3. Cree un rol con las propiedades siguientes.

    • Trusted entity (Entidad de confianza).Lambda:.

    • Permisos: AWSLambdaBasicExecutionRole.

    • Nombre de rol: lambda-role.

    La política AWSLambdaBasicExecutionRole tiene permisos que la función necesita para escribir registros a Registros de CloudWatch.

El código de la función de ejemplo usa el método _.findLastIndex lodash para leer una matriz de objetos. Compara los objetos con un criterio para encontrar el índice de una coincidencia. A continuación, devuelve el índice y el valor del objeto en la respuesta de Lambda.

import { Handler } from 'aws-lambda'; import * as _ from 'lodash'; type User = { user: string; active: boolean; } type UserResult = { statusCode: number; body: string; } const users: User[] = [ { 'user': 'Carlos', 'active': true }, { 'user': 'Gil-dong', 'active': false }, { 'user': 'Pat', 'active': false } ]; export const handler: Handler<any, UserResult> = async (): Promise<UserResult> => { let out = _.findLastIndex(users, (user: User) => { return user.user == 'Pat'; }); const response = { statusCode: 200, body: JSON.stringify(out + ", " + users[out].user), }; return response; };
Implementación de la función de Lambda
  1. Vaya al directorio function-ts/ de la aplicación de muestra layer-nodejs. Si se encuentra actualmente en el directorio layer/ de la aplicación de muestra layer-nodejs, ejecute el siguiente comando:

    cd ../function-ts
  2. Instale las dependencias de desarrollo que se enumeran en package.json con el siguiente comando:

    npm install
  3. Ejecute la tarea build definida en package.json para transpilar y empaquetar el código de la función en un archivo .zip. Utilice el siguiente comando:

    npm run build
  4. Implemente la función. En el siguiente comando de AWS CLI, sustituya el parámetro --role por el ARN del rol de ejecución:

    aws lambda create-function --function-name nodejs_function_with_layer \ --runtime nodejs20.x \ --architectures "arm64" \ --handler index.handler \ --role arn:aws:iam::123456789012:role/lambda-role \ --zip-file fileb://dist/index.zip
  5. Adjunte la capa a la función. En el siguiente comando de AWS CLI, sustituya el parámetro --layers por el ARN de la versión de capa que indicó anteriormente:

    aws lambda update-function-configuration --function-name nodejs_function_with_layer \ --cli-binary-format raw-in-base64-out \ --layers "arn:aws:lambda:us-east-1:123456789012:layer:nodejs-lodash-layer:1"
  6. Invoque la función para comprobar que funciona con el siguiente comando de la AWS CLI:

    aws lambda invoke --function-name nodejs_function_with_layer \ --cli-binary-format raw-in-base64-out \ --payload '{}' response.json

    Debería ver un resultado con un aspecto similar al siguiente:

    { "StatusCode": 200, "ExecutedVersion": "$LATEST" }

    El archivo de salida response.json contiene detalles sobre la respuesta.

A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS.

Eliminación de la capa de Lambda
  1. Abra la página de Capas de la consola de Lambda.

  2. Seleccione la capa que ha creado.

  3. Elija Eliminar; luego, vuelva a elegir Eliminar.

Cómo eliminar la función de Lambda
  1. Abra la página de Funciones en la consola de Lambda.

  2. Seleccione la función que ha creado.

  3. Elija Acciones, Eliminar.

  4. Escriba delete en el campo de entrada de texto y seleccione Delete (Eliminar).