Crear layers para Lambdas python desde la consola de AWS
¿Aún atascas tu zip con librerías?
Cargar librerías en el zip del código puede provocar que nuestra función Lambda pese tanto que no nos permita hacer el deploy o, en su defecto, que no nos muestre el editor de código fuente, lo cuál es útil (pero no recomendable) para cuando hay que hacer ajustes rápidos en el código sin necesidad de volver a deployar la función completa. Hay que recordar que las funciones Lambda están pensadas para microservicios.
Otra práctica común al hablar de microservicios es tener varias funciones en el mismo repo; al tratarse del mismo código vamos a necesitar las mismas librerías en todas nuestras funciones, eso nos obliga a que, cuando se agregue una nueva librería y haya que actualizar el código de una Lambda ya deployada, tengamos que actualizar no sólo el código, sino también las librerías a pesar de que el cambio haya sido sólo de unas cuantas líneas de código.
Una solución es usar layers, pues se crean una sola vez y pueden ser compartidos por cualquier cantidad de funciones compatibles, además tiene un sistema de versiones, el cual nos permite cambiar entre versiones del mismo layer por si hay que hacer un rollback.
Una herramienta que resulta muy útil a la hora de crear layers es el CloudShell, el cuál nos permite usar un shell de una instancia Amazon Linux 2, la misma que se utiliza en Lambda, por lo tanto nos resuelve posibles problemas de compatibilidad.
- Abrir el CloudShell
- Instalar python
- Entorno virtual
- Creación de carpetas para layers
- Instalar librerías
- Zippear y descargar las librerías
- Crear el layer
- Agregar el layer a la función
- Pro tip
- Actualizar un layer
- Paso final
Abrir el CloudShell
Una vez deployado el código, si lo probamos y truena debido a falta de librerías.
Hay que abrir en otra pestaña el CloudShell que se encuentra en un botón arriba a la derecha.
Instalar python
Cuando la consola termine de cargar hay que instalar la versión de python que necesitemos. Hay que recordar que todo lo que instalamos en esta consola es temporal, por lo tanto al reiniciar la consola hay que volver a instalar python.
Python 3.8
- Hay que ejecutar los siguientes comandos:
sudo amazon-linux-extras enable python3.8
sudo yum install python3.8
- Nos va a pedir una confirmación, escribimos y y presionamos enter.
- Una vez finalizada la instalación, confirmamos que se instaló correctamente con el siguiente comando:
python3.8 --version
Python 3.9
- Hay que ejecutar los siguientes comandos:
sudo yum -y groupinstall "Development Tools"
sudo yum -y install openssl-devel bzip2-devel libffi-devel
sudo wget https://www.python.org/ftp/python/3.9.10/Python-3.9.10.tgz
sudo tar xvf Python-3.9.10.tgz
cd Python-*/
./configure --enable-optimizations
sudo make altinstall
- Una vez finalizada la instalación, confirmamos que se instaló correctamente con el siguiente comando:
python3.9 --version
Entorno virtual
- Ya con la versión correcta de python instalada, hay que crear un entorno virtual en el directorio raíz, se puede ir a raíz con el siguiente comando:
cd ~
- Para crear el entorno, se usa alguno de los siguientes comandos dependiendo de la versión de python instalada, donde env es el nombre del entorno virtual:
python3.8 -m venv env
python3.9 -m venv env
- Con el entorno creado, hay que activarlo con el siguiente comando:
source env/bin/activate
- Para verificar que se activó correctamente el entorno, ejecutamos el siguiente comando y nos debe mostrar la versión de python instalada:
python --version
Creación de carpetas para layers
Antes de poder instalar las librerías hay que crear las carpetas para que Lambda las entienda.
Python 3.8
mkdir -p python/lib/python3.8/site-packages
cd python/lib/python3.8/site-packages
Python 3.9
mkdir -p python/lib/python3.9/site-packages
cd python/lib/python3.9/site-packages
Instalar librerías
Dentro de la carpeta site-packages se pueden instalar las librerías necesarias con el siguiente comando:
pip install <nombre_de_la_librería> -t .
Zippear y descargar las librerías
- Una vez instaladas todas las librerías necesarias en la carpeta site-packages, hay que ir a raíz y generar el zip con el contenido de la carpeta python, con los siguientes comandos:
cd ~
zip -r python.zip python/*
- Para saber la ruta en el que estamos, que debe ser algo como /home/cloudshell-user, ejecutamos el siguiente comando y el resultado lo copiamos:
pwd
- En el menú de Actions, seleccionamos la opción Download file, nos va a pedir la ruta del archivo que obtuvimos en el paso anterior más el nombre del archivo zip que vamos a descargar.
Crear el layer
- Ya teniendo el zip descargado, hay que ir a la sección Capas dentro del servicio de Lambda, si no aparecen las secciones, se pueden mostrar presionando el menú hamburguesa del lado izquierdo de la pantalla.
- Oprimimos el botón Crear una capa.
- Recomiendo crear una capa de prueba antes de crear la definitiva ya que no siempre jalan a la primera y a veces hay que instalar librerías que no habíamos considerado y repetir el proceso una y otra vez hasta que nuestra función corra. Nos va a pedir un nombre, el zip (si es demasiado grande vamos a tener que subirlo a través de S3), la arquitectura y la versión de python.
Nota: A pesar de que nos deja escoger más de un runtime, no es recomendable meter más de uno por capa, ya que tendríamos que duplicar las librerías para cada versión, es decir, tendríamos en la carpeta python/lib dos carpetas, una para python3.8 y otra para python3.9 y si queremos meter alguna librería muy pesada, como por ejemplo pandas, un sólo layer con dos pandas excede el tamaño permitido.
Nota: Es posible separar en varios layers las librerías si es que pesan demasiado para un sólo layer, sin embargo, la función también tiene un límite de tamaño permitido de 262144000 bytes.
Agregar el layer a la función
- En la sección Código de nuestra función Lambda, hasta abajo está la sección de layers o Capas, oprimimos el botón de Añadir una capa.
- Seleccionamos Capas personalizadas y en el selector nos va a mostrar las capas compatibles con nuestro runtime, hay que seleccionar una capa y la versión más alta.
Pro tip
Se puede descargar un layer ya creado y sólo instalar las librerías faltantes.
- En el layer, oprimir el botón Descargar.
- En el CloudShell, en el menú Actions, seleccionar la opción Upload file y subir el zip del layer descargado.
- Activar el entorno virtual, si es que no está activado ya y verificar que sea la versión de python que necesitamos.
source env/bin/activate
python --version
- Descomprimir el zip subido.
unzip <archivo>.zip
- Ir a la carpeta site-packages e instalar las librerías faltantes.
- Crear el zip y descargarlo
Actualizar un layer
- Para actualizar un layer, una vez teniendo el zip ya descargado, hay que ir al layer que vamos a actualizar y vamos a Crear una versión.
- Subimos el zip y escogemos la misma configuración de arquitectura y runtime.
Es importante seleccionar la misma arquitectura y runtime de la Lambda, si no el layer no estará disponible.
- Al finalizar la actualización del layer, hay que ir a la Lambda y en la sección Capas oprimir el botón Editar.
- En la Versión de la capa, seleccionar la más reciente y guardar.
Paso final
Si todas las librerías fueron instaladas correctamente, la Lambda se debería ejecutar sin errores de importación de módulos.
Luego de asegurarnos que la Lambda corre, ahora sí podemos generar una versión definitiva del layer, la cuál vamos a poder utilizar en todas las funciones que requieran ese set de librerías.