Agregando Dependencias de Python a Funciones AWS Lambda con CDK

Las funciones Lambda se ejecutan típicamente en entornos creados a partir de los runtimes por defecto proporcionados por AWS (como python3.13 o ruby3.4).

Estos runtimes vienen precargados con muchos módulos populares, como boto3 (el SDK de Python para AWS), por lo que a menudo no necesitas instalar dependencias adicionales para tareas rutinarias.

Sin embargo, eventualmente puedes necesitar un módulo que no esté incluido en los runtimes por defecto. Tienes varias opciones para resolver esto:

Ambas opciones resolverán tu problema, pero son excesivas si solo necesitas un par de módulos. Si ya estás gestionando tus proyectos usando una solución de Infrastructure as Code (IaC) como CDK, puedes usar la opción bundling en su lugar.

Escenario de Ejemplo

Imagina que estás desplegando una función Lambda definida en un archivo llamado cool_stuff.py, ubicado en una carpeta llamada lambdas en el nivel base de tu proyecto. En la definición de tu stack, tienes el siguiente código:

const awesomeLambda = new lambda.Function(this, 'awesomeLambda', {
  runtime: lambda.Runtime.PYTHON_3_13,
  code: lambda.Code.fromAsset('lambdas'),
  handler: 'cool_stuff.handler',
  timeout: cdk.Duration.seconds(30),
})

Esto crea una función Lambda usando el asset especificado (tu archivo en lambdas/cool_stuff.py), usa Python 3.13 como runtime, y establece el timeout a 30 segundos. Supongamos que el archivo contiene código como este:

import pymysql

...

def handler(event, context):
    ...

Ejecutar esta Lambda fallará porque ninguno de los runtimes por defecto incluye el módulo pymysql. Afortunadamente, hay una solución fácil.

La Solución

Primero, crea un archivo requirements.txt junto a tu función:

Carpeta Lambda después de la creación

Luego, agrega las dependencias al archivo requirements.txt. En nuestro caso, es una sola línea:

pymysql==1.1.1

Ahora puedes actualizar tu stack para usar requirements.txt. Pasa argumentos adicionales a la función fromAsset con instrucciones de bundling para asegurar que tu Lambda incluya las dependencias requeridas:

const awesomeLambda = new lambda.Function(this, "awesomeLambda", {
  runtime: lambda.Runtime.PYTHON_3_13,
  code: lambda.Code.fromAsset("lambdas", {
    bundling: {
      image: lambda.Runtime.PYTHON_3_13.bundlingImage,
      command: [
        "bash",
        "-c",
        "pip install --no-cache -r requirements.txt -t /asset-output && cp -au . /asset-output",
      ],
    },
  }),
  handler: "cool_stuff.handler",
  timeout: cdk.Duration.seconds(30),
});

Esto construye tu asset ejecutando un comando en un contenedor Docker y usa eso como base para el runtime de la función. Cuando despliegues esta versión de la función Lambda, mostrará las dependencias junto a tu función en el panel del explorador:

Explorador Lambda con dependencias

Este enfoque te permite agregar dependencias de Python a tus Lambdas fácilmente sin salir de tu proyecto CDK y sin usar capas u otras características.

¿Necesito requirements.txt?

No, no es estrictamente necesario tener un archivo requirements.txt. Puedes instalar dependencias directamente en la sección command de la definición de bundling:

const awesomeLambda = new lambda.Function(this, "awesomeLambda", {
  runtime: lambda.Runtime.PYTHON_3_13,
  code: lambda.Code.fromAsset("lambdas", {
    bundling: {
      image: lambda.Runtime.PYTHON_3_13.bundlingImage,
      command: [
        "bash",
        "-c",
        "pip install --no-cache pymysql -t /asset-output && cp -au . /asset-output",
      ],
    },
  }),
  handler: "cool_stuff.handler",
  timeout: cdk.Duration.seconds(30),
});

Sin embargo, aún recomiendo usar un archivo de requirements porque a menudo necesitarás instalar más de un módulo a la vez, ¡y tener un archivo de requirements dedicado tiende a ser la solución más limpia!

¡Espero que esto te sea útil!


Una Pequeña Actualización: CDK ahora incluye un nuevo construct llamado PythonFunction que simplifica significativamente esta tarea. Aún está en alpha, pero vale la pena echarle un vistazo.

Juan Luis Orozco Villalobos

¡Hola! Soy Juan, un ingeniero de software y consultor que vive en Budapest. Me especializo en computación en la nube e IA/ML, y me encanta ayudar a otros a aprender sobre tecnología e ingeniería