Recientemente encontré una herramienta útil que puede hacer tu vida más fácil al escribir infraestructura como código usando CDK.
Quería Pruebas
Noté que el comando cdk init
crea una carpeta de pruebas por defecto, y empecé a leer sobre cómo escribir pruebas efectivas para tu IaC.
En realidad es bastante fácil, y después de que le agarras el hilo, puede ser muy entretenido. Me gusta hacer TDD cuando trabajo en mis proyectos, así que parecía una buena opción para el código de infraestructura que he estado escribiendo últimamente.
Todo estuvo bien, hasta que empecé a preguntarme…
¿Tal vez no Necesito Pruebas?
No podía deshacerme de la sensación de que las pruebas que estaba escribiendo eran un poco redundantes. No sé si hay una palabra mejor para ello, pero sentía que estaba escribiendo una especificación para una especificación.
Tu CDK es un documento que especifica la estructura y estado que quieres para tu sistema: qué recursos, su configuración, y cómo están todos conectados. El stack mismo es la especificación, entonces ¿por qué estoy escribiendo una especificación para código que ya es bastante declarativo?
No te equivoques, estamos usando TypeScript (o Python, o C#, o cualquiera de los lenguajes CDK soportados), pero escribir IaC usando CDK sigue siendo completamente declarativo: Estamos definiendo la estructura y estado que queremos para nuestro sistema, y CloudFormation se encargará de los pasos necesarios para alcanzarlo—simplemente no nos importa cómo sucede.
Entonces, ¿cuáles son las alternativas?
cdk-nag entra al campo de juego.
Configurando cdk-nag
cdk-nag es un proyecto genial con una premisa simple: ¡Lo instalas, lo configuras, y luego empieza a regañarte sin parar en tus proyectos CDK!
El proceso es bastante simple—lo primero que necesitas hacer es agregar la dependencia al package.json
de tu proyecto:
{
...
"devDependencies": {
...
},
"dependencies": {
...
"cdk-nag": "^2.36.54",
}
}
Al momento de escribir esto, esa era la última versión—asegúrate de revisar la versión más actual y usar esa en su lugar. Luego solo ejecuta npm install
.
Después de esto, necesitas configurarlo en tu proyecto. Ve al archivo en la carpeta bin de tu proyecto—los míos usualmente se llaman main.ts
. En el último experimento en la nube en el que trabajamos se veía así:
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { InventoryStockAlarmStack } from '../lib/inventory_stock_alarm-stack';
const app = new cdk.App();
new InventoryStockAlarmStack(app, 'InventoryStockAlarmStack', {
targetEmail: 'jl.orozco.villa@gmail.com',
productUrl: 'https://www.mediamarkt.hu/hu/product/_nintendo-switch-2-mario-kart-world-1482762.html',
availabilityString: 'Online elérhető',
});
Ahora solo necesitas importar la lista de verificaciones que necesitas (usaremos AwsSolutionsChecks
) y la clase Aspects
. El último paso involucra agregar las verificaciones de soluciones como un nuevo aspecto a tu app, justo así:
#!/usr/bin/env node
import * as cdk from 'aws-cdk-lib';
import { InventoryStockAlarmStack } from '../lib/inventory_stock_alarm-stack';
import { AwsSolutionsChecks } from 'cdk-nag'; // <- Cosas Nuevas
import { Aspects } from 'aws-cdk-lib'; // <- Cosas Nuevas
const app = new cdk.App();
new InventoryStockAlarmStack(app, 'InventoryStockAlarmStack', {
targetEmail: 'jl.orozco.villa@gmail.com',
productUrl: 'https://www.mediamarkt.hu/hu/product/_nintendo-switch-2-mario-kart-world-1482762.html',
availabilityString: 'Online elérhető',
});
Aspects.of(app).add(new AwsSolutionsChecks()) // <- Cosas Nuevas
Puedes usar diferentes paquetes de reglas pre-hechos en tu app, o incluso crear los tuyos propios.
Lo maravilloso es que ahora, cada vez que sintetices o trates de desplegar tu app, obtendrás una serie de avisos diciéndote cómo tu stack se desvía del conjunto de reglas aplicado:
Es implacable, y me hace sentir como un idiota absoluto, que es probablemente la razón principal por la que me encanta. El aprendizaje y crecimiento usualmente sucede fuera de tu zona de confort, así que obtener un recordatorio constante de las cosas que aún necesitan trabajo en tu proyecto es una gran forma de empujarte hacia mejorar escribiendo código de infraestructura.
Bien, ¿Qué Pasa con las Pruebas Entonces?
Creo que aún tienen un lugar en tus stacks. Lo pensé, y leí un montón de opiniones diferentes online sobre qué necesita ser probado, y llegué a la conclusión de que deberías escribir pruebas para:
- Cualquier lógica o comportamiento imperativo que tengas en tu código. No todo en tu stack es verdaderamente declarativo, y si estás procesando alguna forma de datos para alterar la estructura de tu stack—por ejemplo, recibiendo props del stack que son de alguna manera procesados o dictan el número de cualquier recurso—es una buena idea escribir pruebas para verificar que tu código se comporte como debería.
- Cualquier configuración importante que sea crítica para el comportamiento apropiado del sistema (tablas de rutas, Zonas Hospedadas Route53, VPC peering)—es un buen candidato para pruebas. Se trata mucho más de protegerse contra cambios futuros con efectos secundarios no intencionados que de verificar el comportamiento actual. Piensa en ellas como un arnés de seguridad contra cambios que rompan cosas hechos en el futuro.
Así que sí, solo estaba escribiendo el tipo equivocado de prueba—siguen siendo bastante útiles cuando se enfocan en las cosas que realmente necesitan ser probadas.
Concluyendo
cdk-nag es una herramienta muy útil para asegurar que tus stacks sigan las mejores prácticas, y puede ser una gran herramienta para ayudarte a escribir soluciones más seguras y mejor diseñadas, ¡especialmente cuando estás empezando!
Dale una oportunidad, pero no la sigas ciegamente. Especialmente al principio, puede ser fácil sentirse abrumado con el número de quejas que puede generar, pero parte de crecer como diseñador e ingeniero viene de saber qué principios aplican a lo que estás tratando de hacer. Recuerda que solo está destinado a ser una guía para construir una mejor solución, no una entidad con la palabra final.
¡Espero que esto te sea útil!