Presentar la infraestructura como código en un formato de texto reproducible es una buena práctica sencilla para sistemas que no requieren complicaciones. Esta práctica ha sido denominada - , y hasta ahora, para llevarla a cabo, especialmente en AWS, hay dos herramientas populares: y .

Comparando la experiencia de trabajo con Terraform y CloudFormation
Antes de unirme a (también conocido como ) trabajé y durante unos tres años utilicé Terraform. En mi nuevo puesto también utilicé Terraform a fondo, pero luego la empresa impulsó la transición a todo lo relacionado con Amazon, incluyendo CloudFormation. Me esforcé por desarrollar las mejores prácticas tanto para uno como para el otro, y usé ambas herramientas en flujos de trabajo organizacionales muy complejos. Más tarde, tras considerar cuidadosamente las implicaciones de la transición de Terraform a CloudFormation, concluí que Terraform probablemente es la mejor opción para la organización.
Terraform es Horrible
Versión Beta del Software
Terraform ni siquiera ha lanzado la versión 1.0, y esta es una razón válida para no usarlo. Desde que lo probé por primera vez, ha cambiado mucho, pero en ese entonces terraform apply solía fallar a menudo después de varias actualizaciones o simplemente después de un par de años de uso. Diría que "ahora todo es diferente", pero... así parece que todos dicen, ¿no? Hay cambios que no son compatibles con versiones anteriores, aunque sean adecuados, y hasta hay una sensación de que la sintaxis y abstracciones de los recursos ahora son lo correcto. La herramienta aparenta haber mejorado de verdad, pero... :-0
Por otro lado, AWS ha hecho un buen trabajo manteniendo la compatibilidad con versiones anteriores. Probablemente porque sus servicios se testean cuidadosamente internamente antes de ser publicados con un nuevo nombre. Así que decir que "han hecho un buen esfuerzo" es quedarse corto. Mantener la compatibilidad con versiones anteriores de la API para un sistema tan diverso y complicado como AWS es increíblemente difícil. Cualquiera que haya tenido que mantener APIs públicas tan ampliamente utilizadas debe entender lo complicado que es hacerlo a lo largo de tantos años. Sin embargo, el comportamiento de CloudFormation, hasta donde recuerdo, no ha cambiado en absoluto a lo largo de los años.
Conóceme, pie... este es un proyectil
Hasta donde sé, eliminar un recurso externo No se puede importar un stack de CloudFormation desde su propio stack CF. La situación es similar con Terraform. Permite importar recursos existentes a su stack. La función, se podría decir, es asombrosa, pero con gran poder viene una gran responsabilidad. Una vez que se añade un recurso al stack, no se puede eliminar o modificar mientras se trabaja con ese stack. Una vez, esto tuvo consecuencias. En el sitio de Twitch, alguien, sin mala intención, importó accidentalmente un grupo de seguridad de AWS a su propio stack de Terraform. Ejecutó algunos comandos y… el grupo de seguridad (junto con el tráfico entrante) desapareció.
Terraform El Grande
Recuperación de estados incompletos
A veces CloudFormation no puede transitar completamente de un estado a otro. En este caso, intentará volver al anterior. Lamentablemente, esto no siempre es factible. Volver a lo que resultó puede ser muy estresante: nunca sabes si CloudFormation estará contento de que lo estén manipulando —aunque sea para repararlo. No sabe exactamente si podrá volver al estado anterior y por defecto se queda esperando un milagro durante horas.
Por el contrario, Terraform tiende a recuperarse de transiciones fallidas de manera más elegante y ofrece una amplia gama de herramientas de depuración.
Cambios más claros en los estados del documento
«Está bien, balanceador de carga, estás cambiando. ¿Pero cómo?»
—dijo el ingeniero preocupado, listo para presionar el botón de "aceptar".
A veces necesito hacer algunas manipulaciones con el balanceador de carga en el stack de CloudFormation —por ejemplo, añadir un número de puerto o cambiar el grupo de seguridad. CloudFormation muestra los cambios de manera poco clara. Yo, como en un nerviosismo extremo, reviso el archivo yaml diez veces para asegurarme de que no he borrado nada importante ni añadido nada innecesario.
Terraform en este aspecto es mucho más transparente. A veces incluso es demasiado transparente (es decir: molesto). Afortunadamente, la última versión incluye una mejor visualización de los cambios —ahora es evidente lo que se está modificando.
Flexibilidad
Escriba software desde el final.
Hablando claramente, la característica más importante de un software de larga duración es su capacidad para adaptarse a los cambios. Cualquier software que desarrolles, hazlo de atrás hacia adelante. A menudo me he equivocado al tomar un servicio 'sencillo' y luego intentar integrar todo en un único stack de CloudFormation o Terraform. Y, por supuesto, después de meses, descubrí que no había entendido bien, ¡y el servicio en realidad no era simple! Así que necesitaba de alguna manera dividir un gran stack en partes más pequeñas. Cuando trabajas con CloudFormation, esto solo es posible recreando el stack existente, algo que no hago con mis bases de datos. Sin embargo, Terraform me permitió descomponer el stack en partes más manejables y comprensibles.
Módulos en git
Compartir código de Terraform entre numerosos stacks es mucho más fácil que con el código de CloudFormation. Con Terraform, puedes colocar tu código en un repositorio git y acceder a él utilizando control de versiones semántico. Cualquiera que tenga acceso a ese repositorio puede reutilizar el código compartido. El equivalente en CloudFormation es S3, pero no tiene las mismas ventajas y no hay razón para abandonar git a favor de S3.
La organización creció y la capacidad de compartir stacks comunes alcanzó un nivel crítico. Con Terraform, todo esto es fácil y natural, mientras que CloudFormation te hará saltar a través de aros antes de lograr algo parecido.
Operaciones como código
«Vamos a hacer un script y listo».
— ingeniero tres años antes de inventar el 'bicicleta' Terraform.
Cuando se trata de desarrollo de software, Go o un programa en Java no son solo código.

Código como código
También existe la infraestructura sobre la que se ejecuta.

Infrastructure as Code
Pero, ¿de dónde viene? ¿Cómo se monitorea? ¿Dónde reside tu código? ¿Los desarrolladores necesitan permiso para acceder?

Operaciones como código
Ser desarrollador de software no es solo escribir código.
No solo AWS: seguramente estás utilizando servicios de otros proveedores. SignalFx, PagerDuty o Github. Quizás tengas un servidor Jenkins interno para CI/CD o un panel de control interno de Grafana para monitoreo. Infra como código se elige por diversas razones, y cada una es igualmente importante para todo lo relacionado con el software.
Cuando trabajaba en Twitch, acelerábamos servicios dentro de sistemas embebidos mixtos y sistemas de AWS de Amazon. Estampábamos y manteníamos múltiples microservicios, aumentando los costos operativos. Las discusiones eran más o menos así:
- Yo: Vaya, hay demasiados movimientos para acelerar un solo microservicio. Tendré que usar esta cosa para crear una cuenta de AWS (estábamos yendo hacia 2 cuentas en microservicio), luego esta otra para configurar alertas, otra más para el repositorio de código, y esta para la lista de correos electrónicos, y esta…
- Líder: Lo escribiremos como un script y listo.
- Yo: De acuerdo, pero el propio script cambiará. Necesitaremos una forma de verificar que todas estas cosas embebidas de Amazon están actualizadas.
- Líder: Suena bien. Y para eso escribiremos un script.
- Yo: ¡Excelente! Seguramente el script también necesitará parámetros. ¿Los aceptará?
- Líder: Sí, los aceptará, ¡¿qué otra opción hay?!
- Yo: El proceso puede cambiar, se perderá la retrocompatibilidad. Necesitaremos algún tipo de control semántico de versiones.
- Líder: ¡Buena idea!
- Yo: Las herramientas se pueden cambiar manualmente, dentro de la interfaz de usuario. Necesitaremos una forma de verificar y corregir esto.
… 3 años después:
- Líder: Y así nació Terraform.
La moraleja de la historia es que incluso si estás completamente sumergido en todo lo de Amazon, aún estás utilizando algo que no es de AWS, y estos servicios tienen un estado que utiliza un lenguaje para la configuración, para sincronizar ese estado.
CloudFormation lambda vs módulos de git de Terraform
lambda es la solución de CloudFormation para la lógica del usuario. Con lambda puedes o . Este enfoque presenta complejidades adicionales que no existen en el control semántico de versiones de los módulos git en Terraform. Para mí, el problema más urgente fue gestionar permisos para todas estas lambdas personalizadas (lo que implica decenas de cuentas de AWS). Otro problema importante fue el tipo "¿qué fue primero, el huevo o la gallina?", que estaba relacionado con el código lambda. Esta función en sí misma es infraestructura y código, y también necesita monitoreo y actualizaciones. El último clavo en el ataúd fue la dificultad en la actualización semántica de los cambios en el código lambda; además, había que asegurarse de que las acciones de la pila no cambiaran entre ejecuciones sin un comando directo.
Recuerdo que una vez quise crear un despliegue canario para el entorno de Elastic Beanstalk con un equilibrador de carga clásico. Lo más fácil sería hacer un segundo despliegue de EB junto al entorno de producción, dando un paso más: combinando el grupo de escalado automático del despliegue canario con el despliegue de producción en el equilibrador de carga. Y dado que Terraform usa , esto requerirá 4 líneas adicionales de código en Terraform. Cuando pregunté si no existía una solución comparable en CloudFormation, me señalaron un repositorio completo en git con un pipeline de despliegue y más: y todo esto— por lo que podríamos hacer 4 miserables líneas de código en Terraform.
Detecta mejor la deriva
Asegúrate de que la realidad se alinea con las expectativas.
— es una función muy poderosa de operaciones como código, porque ayuda a asegurar que la realidad se alinea con las expectativas. Está disponible tanto en CloudFormation como en Terraform. Pero a medida que aumenta el tamaño del stack, la búsqueda de deriva en CloudFormation genera más falsos positivos.
Con Terraform tienes ganchos de ciclo de vida mucho más avanzados para la detección de deriva. Por ejemplo, introduces el comando directamente en la definición de la tarea de ECS, si deseas ignorar cambios en la definición de una tarea específica, sin ignorar los cambios en todo el despliegue de ECS.
CDK y el futuro de CloudFormation
CloudFormation es difícil de gestionar en grandes escalas interinfraestructura. Muchas de estas dificultades son reconocidas, y la herramienta necesita cosas como , una estructura para definir la infraestructura de nube en código y llevarla a través de AWS CloudFormation. Será interesante ver qué le depara el futuro a aws-cdk, pero le resultará difícil competir con otras ventajas de Terraform; para poner a CloudFormation al día, se requerirán cambios globales.
Para que Terraform no decepcione
Esto es 'infraestructura como CÓDIGO', no 'como texto'.
Mi primera impresión de Terraform fue bastante negativa. Creo que simplemente no entendí el enfoque. Casi todos los ingenieros, al principio, lo perciben involuntariamente como un formato de texto que debe transformarse en la infraestructura deseada. NO HAY QUE HACER ESO.
Las verdades fundamentales sobre un buen desarrollo de software también se aplican a Terraform.
He visto cómo muchas prácticas, que se adoptan para crear buen código, se ignoran en Terraform. Has estudiado durante años para ser un buen programador. No renuncies a esa experiencia solo porque trabajas con Terraform. Las verdades fundamentales del buen desarrollo de software también se aplican a Terraform.
¿Cómo puedes no documentar el código?
He encontrado enormes pilas de Terraform completamente sin documentación. ¿Cómo es posible escribir código en páginas — completamente sin documentación? Agrega documentación que explique tu código Terraform (con énfasis en la palabra 'código'), por qué es tan importante esta sección, y qué haces.
¿Cómo puedes desplegar servicios que solían ser una gran función main()?
Me he encontrado con pilas de Terraform muy complejas, presentadas como un único módulo. ¿Por qué no desplegamos el software de esa manera? ¿Por qué descomponemos grandes funciones en partes más pequeñas? Las mismas respuestas son válidas para Terraform. Si tu módulo es demasiado grande, debes dividirlo en módulos más pequeños.
¿Acaso tu empresa no utiliza bibliotecas?
He visto a ingenieros que, lanzando un nuevo proyecto con Terraform, simplemente copiaban y pegaban enormes trozos de otros proyectos en los suyos, y luego los ajustaban hasta que empezaban a funcionar. ¿Así trabajarías tú en tu empresa con código ''en producción''? No usamos bibliotecas sin razón. Sí, pero, ¿qué haríamos sin bibliotecas compartidas en general?!
¿No usas PEP8 o gofmt?
La mayoría de los lenguajes tienen un esquema de formato estándar y aceptado. En Python es PEP8. En Go — gofmt. Terraform tiene el suyo: terraform fmt. ¡Úsalo con gusto!
¿Vas a usar React sin saber JavaScript?
Los módulos de Terraform pueden simplificar alguna parte de la infraestructura complicada que estás creando, pero eso no significa que no debas entenderla en absoluto. ¿Quieres usar Terraform correctamente sin comprender los recursos? Estás condenado: el tiempo pasará, y no dominarás Terraform.
¿Estás codificando con singletons, o inyectando dependencias?
La inyección de dependencias es considerada la mejor práctica para el desarrollo de software, preferida por los singletons. ¿Cómo puede esto ser útil en Terraform? He encontrado módulos de Terraform que dependen de un estado remoto. En lugar de escribir módulos que extraen del estado remoto, escribe un módulo que acepte parámetros. Luego, pasa esos parámetros al módulo.
¿Tus bibliotecas hacen diez cosas bien, o una — excelente?
Las bibliotecas funcionan mejor cuando están enfocadas en una sola tarea, que realizan de manera excepcional. En lugar de escribir grandes módulos de Terraform que intentan hacer todo a la vez, divídelos en partes que hagan bien una cosa específica. Luego, combínalas según sea necesario.
¿Cómo realizas cambios en las bibliotecas sin romper la compatibilidad?
Un módulo de Terraform, al igual que cualquier otra biblioteca, necesita comunicar a los usuarios los cambios sin retrocompatibilidad. Cuando ocurren tales cambios en las bibliotecas, es frustrante, y lo mismo sucede cuando los cambios sin retrocompatibilidad se llevan a cabo en los módulos de Terraform. Se recomienda aplicar etiquetas de git y semver al utilizar módulos de Terraform.
¿Tu servicio de producción está funcionando en tu portátil o en un centro de datos?
Hashicorp tiene herramientas como para ejecutar tu terraform. Estos servicios centralizados facilitan la gestión, auditoría y aprobación de cambios en terraform.
¿No escribes pruebas?
Los ingenieros reconocen que es necesario probar el código, pero a menudo ignoran las verificaciones al trabajar con Terraform. Para la infraestructura, esto puede traer problemas insidiosos. Recomiendo 'probar' o 'crear ejemplos' de pilas utilizando módulos que se puedan desplegar correctamente para ser verificados durante CI/CD.
Terraform y microservicios
La vida y la muerte de las empresas de microservicios dependen de la velocidad, actualización y destrucción de nuevas pilas de microservicios operativos.
El problema negativo más común relacionado con las arquitecturas de microservicios, del cual no se puede escapar, está relacionado con el trabajo y no con el código. Si consideras Terraform solo como una herramienta para automatizar el lado infraestructural de la arquitectura de microservicios, te privas de las verdaderas ventajas de este sistema. Ahora ya .
Fuente: habr.com
