Hace poco me vi en la necesidad de levantar una infraestructura de AWS usando su CDK debido a la sencillez de la API y la rapidez con la que se pueden definir y desplegar diferentes servicios.
Mi infraestructura contaba, entre otras cosas, con una serie de Lambdas conectadas a una base de datos de DynamoDB y, por lo pequeño del proyecto, decidí definir el código de las Lambdas en el mismo repositorio en donde realicé la configuración de mi infraestructura.
Cuando empecé a desarrollar la lógica de negocio de mi proyecto en las Lambdas, me encontré con que el CDK no cuenta con una forma per se de permitirte levantar un servicio local en tu máquina para poder hacer debug del código en las Lambdas.
Normalmente a lo que te lleva en un primer momento el flujo es a hacer debug sobre Cloudwatch, sin embargo, para ello debes de realizar un despliegue cada vez que necesitas revisar un log o solucionar un error en la etapa de desarrollo. Naturalemente no es efectivo trabajar de esta forma.
Aquí es donde entra SAM o Serverless Application Model. En pocas palabras es un framework de AWS para crear aplicaciones serverless usando IaC a través de su CLI y, aunque tenemos a la mano otras herramientas como localStack, me parecio interesante probar con SAM por ser una herramienta nativa de AWS que se integra facilmente con el CDK como lo veremos mas adelante.
¿Como funciona SAM?
Para poder levantar nuestros servicios definidos con el CDK necesitamos generar un archivo .yml
en donde estarán descritos, en un formato YAML, todos los servicios y configuraciones que nuestra aplicación necesita.
Recordemos que cloudformation trabaja usando los servicios definidos a traves de YAML y SAM es por definicion una extensión de cloudformation.
Usando este archivo .yml
SAM sabrá qué lambdas y servicios debe de levantar y bajo que configuraciones, permisos y conexiones a otros servicios debe contemplar.
Sin embargo, la historia no termina aquí ya que en este punto aparece un elemento fundamental para el funcionamiento de SAM el cual es Docker.
Docker le permite a SAM emular un entorno igual al que usa AWS para correr tus lambdas en sus servicios. Este entorno cuenta con librerías, un sistema operativo y configuraciones especificas del runtime que hayas seleccionado.
Si bien, podrias prescindir de Docker sin embargo tendrías que configurar tu mismo el entorno en local para poder correr el código de tus lambdas lo cual te llevaría a configuraciones complejas que Docker hace por ti.
En este punto podríamos enumerar los requisitos que necesitas para poder usar SAM:
- AWS CLI
- SAM CLI
- Docker CLI
Troubleshooting de Docker
A veces sucede que nos acostumbramos a usar Docker Desktop, sin embargo es posible que al correr SAM este no pueda conectarse a Docker aún teniendo este último en ejecución arrojandonos un mensaje así:
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
Para solventar este error debemos de revisar que la variable de entorno $DOCKER_HOST este disponible en nuestro sistema y, en caso de no tenerla disponible, definirla así en tu archivo de configuraciones del sistema:
export DOCKER_HOST=unix:///home/{user}/.docker/desktop/docker.sock
Si estás en un sistema Linux como Ubuntu puedes conocer tu usuario con el comando whoami
. No olvides guardar el archivo y ejecutar:
source ~/.bashrc
o si usas zsh
source ~/.zshrc
Instalando SAM
Para instalar SAM solo basta con seguir las instrucciones en la documentacion. Aquí te mostrare las indicaciones para un OS Linux sin embargo en la documentacion referida encontrarás los pasos necesarios para tu sistema operativo.
Descarga el ZIP que encontrarás aqui en el apartado de Linux.
Una vez descargado descomprimelo usando
unzip aws-sam-cli-linux-x86_64.zip -d sam-installation
.Ejecuta como sudo el archivo install
sudo ./sam-installation/install
Por último verifica la instalación con
sam --version
Generando el archivo YML
Para generar nuestro archivo YAML es muy sencillo. Una vez definidos nuestros servicios usando el CDK debemos ir a nuestra terminal y ejecutar el comando:
cdk synth
Esto nos devolverá toda nuestra infraestructura en formato YAML sin embargo necesitamos almacenar esta información en un archivo en la raíz de nuestro proyecto por lo tanto el comando para esto debe de ser este:
cdk synth --no-staging > template.yaml
El flag --no-staging le dice al CDK que no copie los assets necesarios para el despliegue ya que para nuestro caso no los necesitamos.
Levantando nuestro servidor en local
Nuestra plantilla de cloudformation ahora está en un archivo en la raíz de nuestro proyecto llamado template.yml
para que SAM logre levantar el servidor basta con correr el comando:
sam local start-api
El comando anterior nos permite simular el comportamiento del servicio de AWS API Gateway lo cual nos abre un canal de comunicación HTTP para probar nuestros endpoints los cuales estan conectados a las lambdas usando, en una primera instancia el CDK de AWS, pero que SAM lee a través del template.yml
.
Indicaciones finales
Si has seguido los pasos hasta aquí es posible que te encuentres con la situación de que al realizar cambios sobre tu lambda y probarlas en tu local no veas reflejados los cambios.
Esto sucede porque al correr el comando sam local start-api
este genera un archivo llamado .aws-sam
y si lo revisas te encontrarás en la carpeta build un archivo template.yaml
al explorarlo te darás cuenta que las lambdas tienen una propiedad llamada Metadata
y esta a su vez contiene una propiedad llamada aws:asset:path
que te dirije a la carpeta cdk.out
y si revisas en esta carpeta el archivo que ahí se especifica veras que el código que ésta contiene no tiene tus últimos cambios.
Para solventar esto debemos crear un pequeño script que nos permita hacer un rebuild
de nuestro codigo actualizado para que SAM pueda leerlo. Este script luciría así:
#!/bin/bash
pkill -f "sam local start-api"
rm -rf .aws-sam
rm -rf cdk.out
cdk synth --no-staging > template.yaml
sam build
sam local start-api
Para nuestro caso lo podemos colocar en la raíz del proyecto y crear en nuestro package.json
un script dev
que lo ejecute cada vez que levantemos nuestro entorno de desarrollo.
Esto seria todo. Recuerda siempre tener Docker levantado para que el proceso sea exitoso.
Top comments (0)