¿Cómo cargar módulos npm en AWS Lambda?

147

He creado varias funciones de Lambda usando el editor basado en la web. Hasta aquí todo bien. Ahora me gustaría comenzar a extender aquellos con módulos (como Q para promesas). No puedo entender cómo llevar los módulos a Lambda para que puedan ser consumidos por mis funciones.

He leído todo esto, pero parece implicar configurar un EC2 y ejecutar funciones Lambda desde allí. Hay un mecanismo para cargar un zip cuando se crea una función, pero parece implicar el envío de funciones desarrolladas localmente. Como estoy trabajando en el editor basado en la web, eso parece un flujo de trabajo extraño.

¿Cómo puedo simplemente implementar algunos módulos para usar en mis funciones de Lambda?

Fook
fuente
77
Todo se explica en los documentos aquí: docs.aws.amazon.com/lambda/latest/dg/…
arcseldon el

Respuestas:

198

No puede cargar módulos NPM sin cargar un .ziparchivo, pero en realidad puede reducir este proceso a dos líneas de comando rápidas.

Así es cómo:

  1. Coloque sus archivos de funciones Lambda en un directorio separado. Esto se debe a que instala npmpaquetes localmente para Lambda y desea poder aislar y probar lo que cargará en Lambda.

  2. Instale sus paquetes NPM localmente npm install packageNamemientras está en su directorio Lambda separado que creó en el paso 1.

  3. Asegúrese de que su función funcione cuando se ejecuta localmente: node lambdaFunc.js(simplemente puede comentar las dos export.handlerlíneas en su código para adaptar su código para que se ejecute con Node localmente).

  4. Vaya al directorio de Lambda y comprima el contenido , asegúrese de no incluir el directorio en sí.

    zip -r lambdaFunc.zip .
    
  5. Si tiene aws-cliinstalado, lo que le sugiero que tenga si quiere hacer su vida más fácil, ahora puede ingresar este comando:

    aws lambda update-function-code --function-name lambdaFunc \
    --zip-file fileb://~/path/to/your/lambdaFunc.zip
    

    (no hay citas alrededor de la parte lambdaFunc anterior en caso de que te preguntes como lo hice)

  6. Ahora puede hacer clic en prueba en la consola Lambda.

  7. Sugiero agregar un alias corto para los dos comandos anteriores. Esto es lo que tengo en el mío para el comando de actualización Lambda mucho más largo:

    alias up="aws lambda update-function-code --function-name lambdaFunc \
    --zip-file fileb://~/path/to/your/lambdaFunc.zip"
    
JohnAllen
fuente
11
Es posible que deba indicar explícitamente la región a la que se dirige: aws lambda update-function-code --function-name lambdaFunc --region eu-west-1 --zip-file fileb://~/path/to/your/lambdaFunc.zip
GreensterRox
2
Si bien parece mucho más trabajo, pasar por esto, es realmente una forma mucho mejor de construir estas expresiones lambda ... ¡muchas gracias!
Mike Perrenoud
9
Tuve que usar --zip-file fileb://versus --zip-file file://mientras usaba estos pasos
McLovin
3
Asegúrese de comprimir solo el contenido del directorio y de que lo haga desde la CLI (el uso del comando 'comprimir' del buscador de Mac NO funcionará ).
Yarin
3
Esto fue súper útil ... faltaron al menos dos cosas para que esto funcionara para mí ... 1) fue en --zip-file fileb:lugar de filepara mí. 2) en MacOS parece ser con 3 barras, por ejemplo, comofileb:///Users/wio/Documents
Tobi
31

Se .ziprequiere un archivo para incluir módulos npm en Lambda. Y realmente no debería usar el editor web Lambda para nada, ya que con cualquier código de producción, debe desarrollar localmente, comprometerse con git, etc.

MI FLUJO:

1) Mis funciones Lambda suelen ser utilidades auxiliares para un proyecto más grande, por lo que creo un directorio / aws / lambdas dentro de ese para alojarlas.

2) Cada directorio lambda individual contiene un archivo index.js que contiene el código de función, un archivo package.json que define las dependencias y un subdirectorio / node_modules . (Lambda no utiliza el archivo package.json, es solo para que podamos ejecutar el npm installcomando localmente ).

package.json:

{
  "name": "my_lambda",
  "dependencies": {
    "svg2png": "^4.1.1"
  }
}

3) .gitignore todos los directorios node_modules y archivos .zip para que los archivos generados a partir de las instalaciones npm y la compresión no abarroten nuestro repositorio.

.gitignore:

# Ignore node_modules
**/node_modules

# Ignore any zip files
*.zip

4) Ejecuto npm installdesde el directorio para instalar módulos, y desarrollo / pruebo la función localmente.

5) Comprimo el directorio lambda y lo subo a través de la consola.

( IMPORTANTE: ¡No utilice la utilidad 'comprimir' de Mac del Finder para comprimir el archivo! Debe ejecutar zip desde la CLI desde la raíz del directorio; consulte aquí )

zip -r ../yourfilename.zip * 

NOTA:

Puede tener problemas si instala los módulos de nodo localmente en su Mac, ya que algunos módulos específicos de la plataforma pueden fallar cuando se implementan en el entorno basado en Linux de Lambda. (Ver https://stackoverflow.com/a/29994851/165673 )

La solución es compilar los módulos en una instancia EC2 iniciada desde la AMI que corresponde con el tiempo de ejecución de Lambda Node.js que está utilizando (consulte esta lista de tiempos de ejecución de Lambda y sus respectivas AMI ).


Consulte también AWS Lambda Deployment Package en Node.js - AWS Lambda

Yarin
fuente
9

Espero que esto ayude, con el marco Serverless puedes hacer algo como esto:

  1. Agregue estas cosas en su archivo serverless.yml:

plugins: - serverless-webpack custom: webpackIncludeModules: forceInclude: - <your package name> (for example: node-fetch) 2. Luego cree su función Lambda, impleméntela serverless deploy, el paquete que se incluye en serverless.yml estará allí para usted.

Para obtener más información sobre serverless: https://serverless.com/framework/docs/providers/aws/guide/quick-start/

Toai
fuente
primero necesitas instalarloserverless plugin install --name pluginName
Liad Livnat
1

El módulo npm debe agruparse dentro de su paquete nodejs y cargarse en AWS Lambda Layers como zip, luego deberá consultar su módulo / js como se muestra a continuación y utilizar los métodos disponibles. const mymodule = require ('/ opt / nodejs / MyLogger');

Sunil Chauraha
fuente