Chaos Engineering con AWS Fault Injection Simulator
Tags: cdk, aws, sre
Published: 2023-10-05 16:35:39

Un incidente de producción es un evento que puede provocar la interrupción total o degradar un servicio y tiene dos características muy relevantes: la primera es que es impredecible; puedes tratar con ML predecir la probabilidad de que ocurra un incidente pero nunca tendrá la garantía exacta de cuando va ocurrir y segundo, un incidente no es un evento que solo afecte a un componente de tu infraestructura, normalmente es producto de un fallo en cascada que mientras más compleja es la arquitectura, más complicado es de identificar y remediar. Cuando una organización sufre un evento de producción dependiendo de la gravedad puede tener un impacto económico negativo, verse afectada su imagen o peor aún, la total pérdida de la confianza de sus clientes lo que lo podría llevar a una quiebra. 

Como ingenieros ¿qué podemos hacer en estos casos? Hay tres cosas que podemos intentar: la primera es, prevenir, es decir diseñar arquitecturas altamente resilientes, en segundo lugar, también debemos prepararnos para que cuando ocurran poder responder lo más rápido posible y por último aprender de cada incidente para repetir lo primero y lo segundo. 

Ahora te pido que te hagas esta pregunta,¿Cómo podemos probar que nuestra infraestructura es resiliente a fallos? o ¿Realmente estamos preparados ante un eventual incidente? La respuesta es Chaos Engineering. Es una práctica que busca a través de inyectar fallas deliberadas a nuestro sistema (no simuladas) la información que nos permita detectar debilidades en nuestras soluciones para corregirlas o mitigar su impacto. Si quieres saber más al respecto puedes ir a este link y leer su origen. https://principlesofchaos.org/

¿Cómo lo implementamos? Lo haremos con AWS Fault Injection Simulator. Es una herramienta manejada, es decir, no tienes que aprovisionar ningún servidor sino diseñar los experimentos y dirigirlos a tu infraestructura objetivo. AWS FIS soporta las soluciones de infraestructura más importantes para el hosting de aplicaciones como EC2, ECS, EBS, EKS e incluso VPC para provocar fallos a nivel de red. Puedes leer más aquí https://aws.amazon.com/es/fis/?nc1=h_ls. 

Acá es donde se pone super divertido, vamos a crear nuestro primer. Todo el código de infraestructura e instrucciones puedes obtenerlas en este repositorio: http://github.com:davejfranco/fisdemo 

### El escenario:


![Arquitectura Demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b3r7alm290p3jdi49zxe.png)

Tenemos una infraestructura compuesta por un cluster de ECS que incluye dos nodos EC2 distribuidos en dos zonas de disponibilidad distinta; a esto llamamos nuestro estado estable. Lo siguiente que hacemos es formular una hipótesis basada en una suposición. Si nuestro cluster tiene alta disponibilidad la pérdida de uno de los nodos no debe ocasionar ningún problema.

**Probemos si esto es cierto.** 

La infraestructura está desplegada con CDK así que lo primero es crearla. Vamos al directorio infra.

`cd infra && cdk deploy`. Si nunca has desplegado nada seguramente vas a necesitar hacer `cdk bootstrap` 

![El resultado del despliegue](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rcqf3978hlhe7mudko68.png)

Esto nos dará el endpoint de nuestro LoadBalancer para que podamos probar haciendo request y poder observar su comportamiento. Un requisito de Chaos Engineering es tener buena visibilidad de nuestro servicio para que podamos entender qué ocurre. En el repositorio tengo un script que ejecuta un GET request de forma constante durante unos segundos e imprime el http code.

`../fis/testEndpoint.sh http://FisDem-LB8A1-LuvyHxArqt49-260398987.us-east-1.elb.amazonaws.com`

Debería ver esto antes de la prueba. 

![request exitosos](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qis55bp1nd4vefe1oxxp.png)

**Vamos a la consola de AWS y en el buscador escribimos FIS**

![FIS Console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u0k4dztyd37zrkdpj1by.png)

En la parte izquierda tenemos `experiment templates` que es donde creamos nuestro experimento, debajo podemos ver todos los experimentos que hemos ejecutado hasta ahora y una sección llamada “Spotlight” donde nos publican novedades de la herramienta.

**Hacemos click en `create experiment template`**


![Creación de plantilla](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8d1ygw9wmo9lbwg8jfe4.png)

Necesitamos darle una descripción y opcionalmente un nombre. Luego vamos a la sección de Action donde podemos escoger qué servicio vamos a probar, en este caso vamos terminar una instancia así que seleccionamos EC2, pero podrás ver todos los servicios que soporta, seleccionamos luego en el type ´aws:ec2:terminate-instances´. Le damos “Save”. 

Luego bajamos a la sección de Target donde definimos nuestra infraestructura objetivo; dependiendo de qué servicios escojas esto cambia pero acá podemos directamente seleccionar un InstanceID o un tag que le permita a FIS encontrar la infraestructura; es mejor usar tags porque esto hace el experimento reusable para futuras ocasiones. Luego de seleccionar el tag, definimos cuántas instancias vamos a terminar, esto puede ser un número fijo, un porcentaje o todos (Si alguna vez pruebas esto en producción, asegurate que tienes la capacidad de regenerar el servicio automáticamente). En mi caso seleccioné uno solo.

![definir infra objetivo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lefr1irmge2itgybg8re.png)

Vamos a necesitar darle permisos a FIS para que ejecute la prueba, cuando crear un experimento te sugiere crear un IAM Role, por suerte con el despliegue CDK que hicimos anteriormente está incluido el rol con los permisos necesarios. Finalmente tenemos una condición de stop que permite detener el experimento si una alarma de cloudwatch se activa; esto es útil si estamos probando en un ambiente productivo y queremos detener la prueba para no afectar aún más la disponibilidad del servicio objetivo, además podemos colectar logs de lo ocurrido de forma que nos sirva de reporte. 


![FIS IAM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tlt71rjv3pzhz93uoc8d.png)

**Hacemos click en ´Create experiment template´**. Veremos una pantalla siguiente para ejecutar la prueba que también te pedirá una confirmación.

Mientras se ejecuta el experimento, vamos a correr el script que nos permitirá observar el comportamiento de nuestro servicio. Veremos por un tiempo unos errores 5xx producto de que el 50% de los request están yendo a una instancia que está siendo terminada y no es sino hasta que el ALB detecte que este server no está saludable que lo sacará de circulación. Esta intermitencia puede o no ser significativa dependiendo de la criticidad del servicio que estamos probando; no es lo mismo un demo a un servicio a un app que lleva la posición en tiempo real de un avión en un vuelo comercial. 


![Experiment result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bki6wqx2yshf40xb7ivd.png)

¿Qué podemos hacer para remediar esto? Podemos reducir el tiempo que toma al ALB detectar la instancia defectuosa, también podemos incrementar la cantidad de nodos a más de 2, esto hará que el porcentaje de request fallidos se reduzca a medida que tenemos más servidores para balancear.

**Esto es una nueva hipótesis que tendríamos que probar.**

### Conclusión

**Chaos Engineering** es una práctica que nos permite detectar debilidades en nuestra arquitectura mediante la introducción deliberada de fallos. Los pre-requisitos son: una infraestructura estable y tener un sistema de monitoreo que nos permita visualizar el comportamiento de nuestra infraestructura durante la prueba.

Ya que llegaste aquí, también puedes ver este mismo artículo en mi canal de youtube en donde modifico los valores y ejecutó la prueba nuevamente. 

{% youtube https://youtu.be/wmhdrsgOlm0?si=WhyyD4zjIfpmsIYL  %}

Nos leemos pronto cracks!