Pruebas eficaces en Terraform
Peter De Tender
2 de agosto de 2022
0 minutos de lecturaTerraform es una solución de infraestructura como código (IaC) que permite a los equipos de DevOps usar conceptos de programación para implementar automáticamente componentes de infraestructura locales o en la nube pública. Estos componentes pueden incluir máquinas virtuales, componentes de red, almacenamiento, aplicaciones o servicios de bases de datos.
Terraform proporciona HashiCorp Language (HCL), un lenguaje unificado y específico de dominio que simplifica la creación de plantillas para distintos proveedores de nube, como CloudFormation de Amazon AWS, ARM Templates y Bicep de Microsoft Azure, y Cloud Deployment Manager de Google para GCP.
Al igual que probar el código es una parte fundamental del desarrollo de software, probar una solución de IaC como Terraform es esencial. Cuando se integra correctamente, las pruebas de IaC pueden mitigar problemas importantes de administración de recursos y permiten a los equipos de DevOps validar la eficacia de las configuraciones.
Sin embargo, integrar estas pruebas en el proceso de DevOps puede ser un desafío. Surgen preguntas sobre qué deben incluir y qué pueden omitir, así como cuáles de los mecanismos disponibles son más eficaces.
Hay muchas maneras de probar las plantillas de Terraform. Lo más fácil es usar los comandos integrados de Terraform, como terraform validate o terraform plan. Estos comandos permiten escribir pruebas unitarias, de integración, de cumplimiento o de extremo a extremo, lo que se alinea bien con las prácticas tradicionales de pruebas de desarrollo de software. Como alternativa, podemos adoptar un enfoque más orientado a desarrolladores y realizar pruebas con Cloud Development Kit for Terraform (CDKTF).
En última instancia, los equipos de DevOps deben tener claros los objetivos del proceso de validación. Estos pueden incluir verificar la sintaxis de la plantilla y garantizar que se implemente correctamente. O bien, el objetivo puede ser desarrollar un escenario de pruebas más avanzado: realizar pruebas específicas para detectar problemas de seguridad o configuraciones incorrectas, y descubrir las implicaciones de seguridad al ejecutar implementaciones. La idea principal es determinar exactamente qué se debe probar y luego encontrar la combinación adecuada de soluciones de prueba.
Estrategias para probar Terraform
Exploremos algunas estrategias diferentes para probar Terraform.
Pruebas de desviación
Terraform valida tu infraestructura actual mediante el archivo de estado de Terraform. Cada vez que se realiza una implementación de Terraform, el estado final se escribe en un archivo de estado, que suele almacenarse en una ubicación compartida.
Sin embargo, si no todas las implementaciones en el entorno de destino se activan desde Terraform, puede haber una diferencia entre los recursos “reales” y lo que el archivo de estado de Terraform considera que está en funcionamiento. Si la implementación afecta a un recurso que Terraform ya administra, el comando integrado terraform plan resulta útil, ya que puede señalar cualquier cambio o diferencia entre lo que abarca su archivo de estado y el entorno de destino real. Si la implementación crea un recurso completamente nuevo, herramientas como driftctl y CloudQuery son útiles, ya que informan sobre todos los recursos que no están bajo el control de Terraform.
Pruebas unitarias
Las pruebas unitarias son uno de los tipos de pruebas más fáciles de realizar. Consisten en ejecutar una prueba específica y relativamente básica, normalmente sobre un objeto individual. A menudo, esto incluye verificar que la sintaxis de la plantilla sea correcta.
Para esto, podemos usar terraform validate. Si hay un error en la sintaxis de la plantilla, terraform validate devuelve un mensaje de error (aunque detectar correctamente un error de sintaxis en la plantilla no garantiza que la implementación se realice correctamente).
Para validar una implementación, podemos recurrir a otro comando integrado: terraform plan. Al ejecutar la fase plan, Terraform simula una implementación real, se comunica con el backend del proveedor e informa el resultado de la implementación mediante el comando terraform apply.
El resultado de ejecutar terraform plan destacará cualquier cambio detectado en el entorno existente. Esto podría incluir la creación, modificación o eliminación de recursos. Esta información puede ayudar al equipo de DevOps a identificar el impacto de ejecutar la implementación antes de hacerlo.
El siguiente paso es usar Terraform apply, que ejecuta la implementación real. Sin embargo, ten en cuenta que esta fase no siempre refleja por completo la situación. Si quitas un recurso de tu HCL de Terraform y luego usas terraform apply, se eliminará el recurso en IaaS. Esto sucede porque, aunque el recurso ya no está en HCL, sigue apareciendo en el estado de Terraform de la última implementación correcta. Terraform compara el estado de TF con la API de IaaS, detecta que el recurso ya no debería implementarse y lo elimina. Por eso, aún debes estar atento a las posibles dependencias o restricciones de tu entorno. En escenarios de nube como AWS o Azure, esto suele gestionarse mediante la gobernanza de políticas.
Análisis estático
Usar un linter también es útil. Un linter permite a los equipos de DevOps analizar el código para encontrar errores, bugs o bloques de código sospechosos. Esto ayuda a identificar problemas de sintaxis, pero también tiene usos más importantes, como detectar problemas de seguridad.
Hay varias herramientas de código abierto para analizar código de Terraform, con distintos mecanismos de análisis para diferentes plataformas de destino. GitHub ofrece una variedad de plantillas que usan tflint con distintos proveedores de nube.
Según la complejidad del caso de uso del análisis estático, el proceso puede considerarse una prueba unitaria sencilla o formar parte de un escenario de pruebas más complejo o avanzado. Por ejemplo, si la plantilla permite implementar una máquina virtual con una dirección IP pública asociada, la validación del linter podría detectar el objeto de dirección IP pública y generar un error. El linter también podría detectar contraseñas o cadenas de conexión codificadas directamente en el código.
Pruebas de integración
Aunque todas las pruebas unitarias se aprueben, ejecutar todos los planes de Terraform de manera secuencial no garantiza el éxito general. Por eso, las pruebas de integración son esenciales. En pocas palabras, consisten en ejecutar una combinación de pruebas unitarias. En Terraform, las pruebas unitarias suelen dirigirse a un solo módulo, mientras que las pruebas de integración validan varios módulos con dependencias amplias.
Supongamos que tenemos dos plantillas de Terraform independientes: una para crear una red virtual o nube privada virtual (VPC) y otra para implementar infraestructura de máquinas virtuales. Podríamos ejecutar cada una como una prueba unitaria individual, pero, en algún momento, querremos implementar correctamente las máquinas virtuales en los componentes implementados de la red virtual. Si alguno de los módulos se implementa en una región diferente, las pruebas unitarias seguirían aprobándose, pero las de integración fallarían.
Otra diferencia importante: las pruebas unitarias pueden ejecutarse sin conexión y sin implementar nada, mientras que las pruebas de integración requieren implementar recursos para validar el impacto y el éxito.
Una herramienta útil para las pruebas de integración es Terratest de Gruntwork. Se basa en el framework del lenguaje Go, que incluye pruebas de paquetes, y permite a los equipos de DevOps aplicar los mismos principios a escenarios de IaC.
Pruebas de cumplimiento
Al validar plantillas de Terraform, las implementaciones técnicas deben ajustarse a las normas de cumplimiento corporativas. Esto hace necesarias las pruebas de cumplimiento, que verifican los estándares de cumplimiento regionales, las convenciones de nomenclatura y los estándares de infraestructura, como tipos específicos de máquinas virtuales y la seguridad del almacenamiento en disco.
En la mayoría de los casos, la validación del cumplimiento forma parte (o debería formar parte) de la configuración del entorno de destino, junto con la integración de las políticas de Azure o del centro de cumplimiento de AWS. Sin embargo, estas políticas solo se validan durante una implementación real, que fallará si no se ajusta a ellas.
Al integrar las pruebas de cumplimiento en el proceso de DevOps de Terraform, las pruebas se ejecutan antes de las implementaciones y ayudan a garantizar que estas se realicen correctamente. Una solución es Terraform-compliance, una herramienta externa que valida el cumplimiento de una organización con las plantillas de Terraform.
Pruebas de extremo a extremo
En última instancia, los equipos de DevOps intentarán combinar todos los métodos de prueba en un solo escenario. Lo ideal es probar todas las plantillas, implementar todos los módulos y validar los resultados, tanto si son exitosos como si fallan.
Suena ideal, pero las pruebas de extremo a extremo presentan desafíos. La duración de las pruebas crea un cuello de botella: recibir un resultado puede tardar mucho más que con las pruebas unitarias, que se ejecutan rápidamente y ofrecen resultados inmediatos.
Pruebas unitarias con CDKTF
Hasta ahora, nuestros ejemplos suponen que usamos HashiCorp Language nativo para los archivos de plantilla. Sin embargo, Terraform también ofrece un enfoque de IaC más orientado a desarrolladores con CDKTF - Cloud Development Kit for Terraform.
Con CDKTF, los equipos de DevOps pueden implementar infraestructura usando cualquier lenguaje de programación tradicional, como Python, C#, Go y Java. Todos los proveedores y módulos de Terraform son compatibles con este kit. La principal ventaja es que el equipo no tiene que aprender HCL y puede aprovechar sus conocimientos del lenguaje de programación que ya usa.
CDKTF implica un enfoque diferente para escribir plantillas y ejecutar implementaciones, por lo que las pruebas unitarias se ejecutan de otra manera. La documentación actualizada sobre las pruebas de CDKTF está disponible en el sitio web de Terraform.
Herramientas de seguridad de Snyk
Probar tu IaC es fundamental para mantener tu entorno en buen estado. Además de evaluar distintas metodologías de prueba, es importante destacar los aspectos de seguridad. Snyk ofrece herramientas útiles para esto:
Snyk Infrastructure as Code ayuda a integrar la seguridad en todos los aspectos de la escritura de IaC y realiza análisis de seguridad del código de una manera similar al análisis tradicional del código fuente de las aplicaciones.
driftctl, la herramienta de pruebas de desviación mencionada anteriormente, es desarrollada por Snyk y está disponible como motor de detección de desviaciones de código abierto.
Snyk IaC incluye un amplio conjunto de reglas de seguridad predefinidas, basadas en estándares de la industria, mejores prácticas de proveedores de nube e investigaciones sobre modelos de amenazas de Snyk. También podemos crear reglas personalizadas con Snyk IaC mediante el framework Open Policy Agent (OPA) y el lenguaje de consulta Rego.
Más información sobre la seguridad para Terraform
Probar plantillas es una parte fundamental del proceso de creación. Además de sus beneficios funcionales, las pruebas nos ayudan a optimizar la seguridad en las implementaciones de Terraform. Si quieres obtener más información sobre cómo integrar la seguridad en tus plantillas de implementación de Terraform, visita Snyk, que ofrece herramientas de validación de seguridad para tus pipelines de DevOps y automatización, incluido Terraform.
Protege la infraestructura desde el origen
Snyk automatiza la seguridad y el cumplimiento de IaC en los flujos de trabajo, y detecta recursos con desviaciones de configuración y recursos faltantes.



