5 lecciones que aprendimos al escribir más de 300,000 líneas de código de infraestructura

Una breve clase magistral sobre el desarrollo de código de infraestructura


imagen


En octubre de este año, hice una presentación en la conferencia HashiConf 2018, donde hablé sobre 5 lecciones clave que yo y mis colegas de Gruntwork aprendimos en el proceso de crear y mantener una biblioteca de más de 300,000 líneas de código de infraestructura utilizadas por cientos de empresas en sistemas de producción. En esta publicación, compartiré videos y diapositivas de la presentación, así como una versión resumida de la descripción de las 5 lecciones principales.


Videos y diapositivas



Introducción: DevOps ahora en la Edad de Piedra


A pesar del hecho de que la industria está llena de palabras progresivas de moda: Kubernetes, microservicios, redes de servicios, infraestructura inmutable, big data, lagos de datos, etc., la realidad es que cuando estás inmerso en la creación de infraestructura, no sientes tan de moda y progresista.


Personalmente, DevOps me recuerda más de esto:


imagen


imagen


imagen


imagen


Crear infraestructura a nivel de producción es difícil. Este es el verdadero estrés. Y come mucho tiempo. Mucho tiempo


Muestra cuánto tiempo llevará implementar el próximo proyecto de infraestructura. Nos basamos en datos empíricos que recopilamos en el curso del trabajo con cientos de empresas diferentes:


imagen


Lección 1. Lista de verificación para la infraestructura de fabricación


Los proyectos DevOps siempre tardan más de lo esperado. Siempre. Por qué
La primera razón es un corte de pelo de yak . A continuación se muestra una ilustración vívida de este fenómeno (este es un extracto de la serie "Malcolm in the Spotlight")



La segunda razón es que el proceso de creación de una infraestructura de nivel de producción (por ejemplo, la infraestructura en la que pondría su empresa) consta de miles de piezas pequeñas. La gran mayoría de los desarrolladores no conocen estos detalles, por lo tanto, al evaluar un proyecto, generalmente se olvida de muchas tareas críticas (y que requieren mucho tiempo).
Para evitar esto, cada vez que comience a trabajar en una nueva sección de la infraestructura, use la siguiente lista de verificación:



No todos los elementos de la lista serán necesarios para cada pieza individual de infraestructura, pero debe documentar consciente y explícitamente qué elementos implementó y cuáles decidió omitir y por qué.


Lección 2. Caja de herramientas


Enumeramos las principales herramientas que utilizamos en Gruntwork para crear y administrar infraestructura (a partir de 2018):


imagen


  • Terraform Usamos Terraform para desplegar toda la infraestructura subyacente, incluida la red, los subsistemas de equilibrio de carga, las bases de datos, las herramientas de administración de usuarios y permisos y todos nuestros servidores.
  • Packer Utilizamos Packer para configurar y crear imágenes de máquinas virtuales que ejecutamos en nuestros servidores.
  • Docker Algunos de nuestros servidores forman clústeres donde ejecutamos aplicaciones como contenedores Docker. Para los clústeres de Docker, utilizamos principalmente las siguientes herramientas: Kubernetes , ECS y Fargate .

Todas estas herramientas son útiles, pero ese no es el punto. Debe comprender que algunas herramientas no son suficientes. También es necesario cambiar el comportamiento del equipo.


En particular, incluso las mejores herramientas del mundo no ayudarán a su equipo si no quieren usarlas o si no tienen el tiempo suficiente para aprender cómo usarlas. Por lo tanto, la conclusión clave es que el uso de "infraestructura como código" es una inversión, es decir, se le requerirán ciertos costos iniciales. Si invierte sabiamente, recibirá grandes dividendos a largo plazo.


Lección 3. Los módulos grandes son malos


Los recién llegados a la aplicación de "infraestructura como código" a menudo definen toda su infraestructura para todos sus entornos (entorno de desarrollo, entorno intermedio, entorno de producción, etc.) en un archivo o un conjunto de archivos que se implementan como un todo. En vano


Estas son solo algunas de las desventajas de este enfoque:


  • Baja velocidad Si toda la infraestructura se define en un solo lugar, la ejecución de cualquier comando tomará mucho tiempo. ¡Enfrentamos situaciones en las empresas cuando el equipo del terraform plan tardó 5-6 minutos en completarse!
  • Baja seguridad Si administra toda la infraestructura en conjunto, entonces para cambiar algo necesita permisos para acceder a todo. Es decir, casi todos los usuarios deberían ser administradores, y esto también es muy inconveniente.
  • Altos riesgos Si coloca todos sus huevos en una canasta, cree una situación en la que un error local pueda interrumpir el funcionamiento de toda la infraestructura. Por ejemplo, cuando realiza cambios menores en una aplicación externa en el entorno de desarrollo, un solo error tipográfico o un comando incorrecto puede provocar la eliminación de la base de datos de producción.
  • Es dificil de entender . Cuanto más código se coloca en un lugar, más difícil es para una persona entender todo esto. Y cuando todo esto esté conectado, las partes incomprensibles jugarán una broma cruel contigo.
  • Difícil de probar . Probar el código de infraestructura es difícil; probar grandes cantidades de código de infraestructura es casi imposible. Volveremos a esto más tarde.
  • Es difícil de analizar . La salida de comandos como el plan de terraformación se vuelve inútil, ya que nadie se molesta en ver miles de líneas. Además, el análisis de código se vuelve inútil.

En resumen, debe crear su código a partir de módulos compuestos pequeños, independientes y reutilizables. Esto no es noticia ni descubrimiento. Has escuchado esto miles de veces, aunque en situaciones ligeramente diferentes:


“Haz una cosa y hazlo bien” - Filosofía Unix.
“La primera regla de funciones es que deberían ser pequeñas. La segunda regla establece que las funciones deberían ser aún más pequeñas ". - "Código limpio"

Lección 4. El código de infraestructura sin pruebas automáticas es defectuoso


Si su código de infraestructura no tiene pruebas automatizadas, no funciona correctamente. Simplemente no lo sabes aún. Pero probar el código de infraestructura es difícil. No tiene un "host local" (por ejemplo, no puede implementar la nube privada virtual de AWS VPC en su computadora portátil), ni "pruebas unitarias" reales (por ejemplo, no puede aislar el código Terraform del mundo "exterior", porque es como veces y está diseñado para comunicarse con el mundo exterior).


Por lo tanto, para probar correctamente el código de infraestructura, generalmente debe implementarlo en un entorno real, ejecutar una infraestructura real, verificar que el código funciona y luego romperlo (para obtener una descripción de este estilo de prueba: consulte Terratest, esta es una biblioteca de código abierto que incluye herramientas para probar el código Terraform , Packer y Docker, trabajando con las API de AWS, GCP y Kubernetes, ejecutando comandos de shell localmente y en servidores remotos a través de SSH, así como muchas otras características). Por lo tanto, al probar la infraestructura, debe redefinir ligeramente las condiciones:


imagen


Las pruebas unitarias implementan y prueban uno o más módulos de infraestructura estrechamente relacionados del mismo tipo (por ejemplo, módulos para una sola base de datos).


Las pruebas de integración implementan y prueban varios módulos de infraestructura de varios tipos para verificar que funcionan juntos (por ejemplo, módulos de bases de datos y módulos de servicios web).


Las pruebas de extremo a extremo (e2e) implementan y prueban toda la arquitectura.
Tenga en cuenta que el diagrama es una pirámide: tenemos muchas pruebas unitarias, menos pruebas de integración y muy pocas pruebas e2e. Por qué Depende de la duración de cada tipo de prueba:


imagen


Las pruebas de infraestructura toman mucho tiempo, especialmente en los niveles superiores de la pirámide, y, naturalmente, querrá encontrar y corregir tantos errores como sea posible en la parte inferior. Para hacer esto, necesitas:


  1. Cree módulos independientes pequeños y simples (consulte la Lección 3) y escriba muchas pruebas unitarias para ellos, asegúrese de que funcionen correctamente.
  2. Combine estos bloques pequeños, simples y probados para crear una infraestructura más sofisticada que pruebe con menos integración y pruebas E2E.

Lección 5. Proceso de lanzamiento


Para resumir todo lo anterior. Así es como ahora creará y administrará su infraestructura:


  • Verifique la lista de verificación para la infraestructura de grado de producción y asegúrese de estar trabajando en la dirección correcta.
  • Defina su "infraestructura como código" con herramientas como Terraform, Packer y Docker. Asegúrese de que su equipo tenga tiempo suficiente para aprender estas herramientas (ver Recursos de DevOps ).
  • Cree código a partir de módulos compuestos pequeños e independientes (o use módulos estándar de la Infraestructura como biblioteca de códigos ).
  • Prepare pruebas automatizadas para sus módulos con Terratest .
  • Complete la solicitud para incluir sus cambios para revisar su código.
  • Lanza la nueva versión del código.
  • Copie la nueva versión del código de un entorno a otro.

imagen

Source: https://habr.com/ru/post/es434774/


All Articles