Lo que aprendí al probar 200 líneas de código de infraestructura

Lo que aprendí al probar 200 líneas de código de infraestructura

El enfoque IAC (Infraestructura como Código) consiste no sólo en el código que se almacena en el repositorio, sino también en las personas y procesos que rodean este código. ¿Es posible reutilizar enfoques desde el desarrollo de software hasta la gestión y descripción de infraestructura? Sería una buena idea tener esta idea en mente mientras lees el artículo.

Versión Inglés

Esta es una transcripción de mi actuaciones en Conferencia Devops 2019-05-28.

Diapositivas y vídeos

Infraestructura como historia de bash

Lo que aprendí al probar 200 líneas de código de infraestructura

Supongamos que llegas a un nuevo proyecto y te dicen: “tenemos Infraestructura como Código". En realidad resulta Infraestructura como historia de bash o por ejemplo Documentación como historial de bash.. Esta es una situación muy real; por ejemplo, Denis Lysenko describió un caso similar en un discurso. Cómo reemplazar toda la infraestructura y empezar a dormir tranquilo, contó cómo obtuvieron una infraestructura coherente para el proyecto a partir de la historia de bash.

Con algunas ganas podemos decir que Infraestructura como historia de bash esto es como un código:

  1. reproducibilidad: Puede tomar el historial de bash, ejecutar los comandos desde allí y, por cierto, puede obtener una configuración funcional como resultado.
  2. versionando: sabes quién entró y qué hicieron, nuevamente, no es un hecho que esto te llevará a una configuración funcional en la salida.
  3. historia: la historia de quién hizo qué. Sólo que no podrás usarlo si pierdes el servidor.

¿Qué hacer?

Infraestructura como Código

Lo que aprendí al probar 200 líneas de código de infraestructura

Incluso un caso tan extraño como Infraestructura como historia de bash puedes tirarlo por las orejas Infraestructura como Código, pero cuando queramos hacer algo más complicado que el viejo servidor LAMP, llegaremos a la conclusión de que este código necesita modificarse, cambiarse y mejorarse de alguna manera. A continuación nos gustaría considerar los paralelos entre Infraestructura como Código y desarrollo de software.

SECO

Lo que aprendí al probar 200 líneas de código de infraestructura

En un proyecto de desarrollo de un sistema de almacenamiento, había una subtarea configurar periódicamente SDS: estamos lanzando una nueva versión; es necesario implementarla para realizar más pruebas. La tarea es extremadamente sencilla:

  • inicie sesión aquí a través de ssh y ejecute el comando.
  • copie el archivo allí.
  • corrija la configuración aquí.
  • iniciar el servicio allí
  • ...
  • ¡GANANCIA!

Para la lógica descrita, bash es más que suficiente, especialmente en las primeras etapas del proyecto, cuando apenas comienza. Este no esta mal que uses bash, pero con el tiempo hay solicitudes para implementar algo similar, pero ligeramente diferente. Lo primero que me viene a la mente es copiar y pegar. Y ahora ya tenemos dos guiones muy similares que hacen casi lo mismo. Con el tiempo, la cantidad de scripts creció y nos enfrentamos al hecho de que existe una cierta lógica comercial para implementar una instalación que debe sincronizarse entre diferentes scripts, esto es bastante complicado.

Lo que aprendí al probar 200 líneas de código de infraestructura

Resulta que existe una práctica llamada DRY (No te repitas). La idea es reutilizar el código existente. Suena simple, pero no llegamos a esto de inmediato. En nuestro caso, fue una idea banal: separar las configuraciones de los scripts. Aquellos. Lógica empresarial de cómo se implementa la instalación por separado, configuraciones por separado.

SÓLIDO para CFM

Lo que aprendí al probar 200 líneas de código de infraestructura

Con el tiempo el proyecto creció y continuación natural Fue el surgimiento de Ansible. La razón principal de su aparición es que hay experiencia en el equipo y que bash no está diseñado para una lógica compleja. Ansible también comenzó a contener una lógica compleja. Para evitar que la lógica compleja se convierta en un caos, existen principios para organizar el código en el desarrollo de software. SÓLIDO Además, por ejemplo, Grigory Petrov en el informe "¿Por qué un especialista en TI necesita una marca personal?" planteó la pregunta de si una persona está diseñada de tal manera que le resulta más fácil trabajar con algunas entidades sociales, en el desarrollo de software estas son objetos. Si combinamos estas dos ideas y continuamos desarrollándolas, notaremos que también podemos usar SÓLIDO para que sea más fácil mantener y modificar esta lógica en el futuro.

El principio de responsabilidad única

Lo que aprendí al probar 200 líneas de código de infraestructura

Cada clase realiza solo una tarea.

No es necesario mezclar código y crear monstruos espagueti divinos monolíticos. La infraestructura debería consistir en simples ladrillos. Resulta que si divide el libro de jugadas de Ansible en partes pequeñas y lee los roles de Ansible, serán más fáciles de mantener.

El principio abierto cerrado

Lo que aprendí al probar 200 líneas de código de infraestructura

Principio abierto/cerrado.

  • Abierto a extensión: significa que el comportamiento de una entidad se puede ampliar creando nuevos tipos de entidad.
  • Cerrado al cambio: como resultado de ampliar el comportamiento de una entidad, no se deben realizar cambios en el código que utiliza esas entidades.

Inicialmente, implementamos la infraestructura de prueba en máquinas virtuales, pero debido a que la lógica empresarial de implementación estaba separada de la implementación, agregamos la implementación a baremetall sin ningún problema.

El principio de sustitución de Liskov

Lo que aprendí al probar 200 líneas de código de infraestructura

Principio de sustitución de Barbara Liskov. Los objetos en un programa deben ser reemplazables con instancias de sus subtipos sin cambiar la ejecución correcta del programa.

Si lo miras de manera más amplia, no es una característica de ningún proyecto en particular que pueda aplicarse allí. SÓLIDO, generalmente se trata de CFM, por ejemplo, en otro proyecto es necesario implementar una aplicación Java en caja sobre varios Java, servidores de aplicaciones, bases de datos, sistemas operativos, etc. Usando este ejemplo, consideraré otros principios. SÓLIDO

En nuestro caso, existe un acuerdo dentro del equipo de infraestructura de que si hemos instalado el rol imbjava u oraclejava, entonces tenemos un ejecutable binario de Java. Esto es necesario porque Los roles ascendentes dependen de este comportamiento; esperan java. Al mismo tiempo, esto nos permite reemplazar una implementación/versión de Java por otra sin cambiar la lógica de implementación de la aplicación.

El problema aquí es que es imposible implementar esto en Ansible, por lo que aparecen algunos acuerdos dentro del equipo.

El principio de segregación de interfaces

Lo que aprendí al probar 200 líneas de código de infraestructura

Principio de separación de interfaces: “Muchas interfaces específicas de cliente son mejores que una interfaz de propósito general.

Inicialmente, intentamos poner toda la variabilidad de la implementación de aplicaciones en un manual de Ansible, pero fue difícil de soportar, y el enfoque, cuando especificamos una interfaz externa (el cliente espera el puerto 443), luego se puede ensamblar una infraestructura a partir de individuos. ladrillos para una implementación específica.

El principio de inversión de dependencia

Lo que aprendí al probar 200 líneas de código de infraestructura

El principio de inversión de dependencia. Los módulos de niveles superiores no deberían depender de módulos de niveles inferiores. Ambos tipos de módulos deben depender de abstracciones. Las abstracciones no deberían depender de los detalles. Los detalles deben depender de abstracciones.

Aquí el ejemplo se basará en un antipatrón.

  1. Uno de los clientes tenía una nube privada.
  2. Pedimos máquinas virtuales dentro de la nube.
  3. Pero debido a la naturaleza de la nube, la implementación de aplicaciones estaba ligada al hipervisor en el que se encontraba la VM.

Aquellos. La lógica de implementación de aplicaciones de alto nivel fluía con dependencias hacia niveles inferiores del hipervisor, y esto significaba problemas al reutilizar esta lógica. No hagas eso.

Interacción

Lo que aprendí al probar 200 líneas de código de infraestructura

La infraestructura como código no se trata sólo de código, sino también de la relación entre el código y las personas, de las interacciones entre los desarrolladores de infraestructura.

Factor de bus

Lo que aprendí al probar 200 líneas de código de infraestructura

Supongamos que tienes a Vasya en tu proyecto. Vasya sabe todo sobre su infraestructura, ¿qué pasará si Vasya desaparece repentinamente? Esta es una situación muy real, porque podría ser atropellado por un autobús. A veces ocurre. Si esto sucede y el conocimiento sobre el código, su estructura, cómo funciona, apariencias y contraseñas no se distribuye entre el equipo, entonces pueden surgir una serie de situaciones desagradables. Para minimizar estos riesgos y distribuir el conocimiento dentro del equipo, puede utilizar varios enfoques.

Par devopsing

Lo que aprendí al probar 200 líneas de código de infraestructura

No es como Como una broma, que los administradores bebieron cerveza, cambiaron contraseñas y un análogo de la programación en pareja. Aquellos. dos ingenieros se sientan frente a una computadora, un teclado y comienzan a configurar su infraestructura juntos: configurar un servidor, escribir una función de Ansible, etc. Suena bien, pero no funcionó para nosotros. Pero casos especiales de esta práctica funcionaron. Ha llegado un nuevo empleado, su mentor asume junto a él una tarea real, trabaja y le transfiere conocimientos.

Otro caso especial es una llamada de incidente. Durante un problema, se reúne un grupo de los que están de servicio y los involucrados, se nombra un líder, que comparte su pantalla y expresa el hilo de sus pensamientos. Otros participantes siguen los pensamientos del líder, espían los trucos desde la consola, comprueban que no se han perdido ni una línea en el registro y aprenden cosas nuevas sobre el sistema. Este enfoque funcionó la mayoría de las veces.

Revisión de código

Lo que aprendí al probar 200 líneas de código de infraestructura

Subjetivamente, fue más efectivo difundir conocimiento sobre la infraestructura y cómo funciona mediante la revisión de código:

  • La infraestructura se describe mediante código en el repositorio.
  • Los cambios se producen en una rama separada.
  • Durante una solicitud de fusión, puede ver el delta de cambios en la infraestructura.

Lo más destacado aquí fue que los revisores fueron seleccionados uno por uno, según un cronograma, es decir, con cierto grado de probabilidad subirás a una nueva pieza de infraestructura.

Estilo de código

Lo que aprendí al probar 200 líneas de código de infraestructura

Con el tiempo, comenzaron a aparecer disputas durante las revisiones, porque... Los revisores tenían su propio estilo y la rotación de revisores los apilaba con diferentes estilos: 2 espacios o 4, camelCase o Snake_case. No fue posible implementar esto de inmediato.

  • La primera idea fue recomendar el uso de linter, después de todo, todos son ingenieros, todos son inteligentes. Pero diferentes editores, sistemas operativos, no son convenientes.
  • Esto evolucionó hasta convertirse en un bot que escribía en slack para cada confirmación problemática y adjuntaba la salida de linter. Pero en la mayoría de los casos había cosas más importantes que hacer y el código seguía sin corregirse.

Maestro de construcción ecológica

Lo que aprendí al probar 200 líneas de código de infraestructura

Pasa el tiempo y hemos llegado a la conclusión de que no se pueden permitir confirmaciones que no pasen ciertas pruebas en el master. ¡Voilá! Inventamos Green Build Master, que se practica en el desarrollo de software desde hace mucho tiempo:

  • El desarrollo está en marcha en una rama separada.
  • Se están realizando pruebas en este hilo.
  • Si las pruebas fallan, el código no llegará al maestro.

Tomar esta decisión fue muy doloroso, porque... causó mucha controversia, pero valió la pena, porque... Las revisiones comenzaron a recibir solicitudes de fusiones sin diferencias de estilo y, con el tiempo, el número de áreas problemáticas comenzó a disminuir.

Pruebas de IAC

Lo que aprendí al probar 200 líneas de código de infraestructura

Además de la verificación de estilo, puede usar otras cosas, por ejemplo, para verificar que su infraestructura realmente se pueda implementar. O comprobar que los cambios en la infraestructura no provocarán pérdidas de dinero. ¿Por qué podría ser necesario esto? La pregunta es compleja y filosófica, es mejor responder con una historia de que de alguna manera había un escalador automático en Powershell que no verificó las condiciones límite => se crearon más máquinas virtuales de las necesarias => el cliente gastó más dinero de lo planeado. Esto no es muy agradable, pero sería muy posible detectar este error en etapas anteriores.

Uno podría preguntarse: ¿por qué hacer que la infraestructura compleja sea aún más compleja? Las pruebas de infraestructura, al igual que las de código, no tratan de simplificar, sino de saber cómo debería funcionar su infraestructura.

Pirámide de pruebas IaC

Lo que aprendí al probar 200 líneas de código de infraestructura

Pruebas de IaC: análisis estático

Si implementa toda la infraestructura a la vez y comprueba que funciona, es posible que descubra que lleva mucho tiempo y requiere mucho tiempo. Por lo tanto, la base debe ser algo que funcione rápidamente, hay mucho y cubre muchos lugares primitivos.

bash es complicado

Veamos un ejemplo trivial. seleccione todos los archivos en el directorio actual y cópielos a otra ubicación. Lo primero que me viene a la mente:

for i in * ; do 
    cp $i /some/path/$i.bak
done

¿Qué pasa si hay un espacio en el nombre del archivo? Bueno, está bien, somos inteligentes, sabemos cómo usar comillas:

for i in * ; do cp "$i" "/some/path/$i.bak" ; done

¿Bien hecho? ¡No! ¿Qué pasa si no hay nada en el directorio, es decir? globalizar no funcionará.

find . -type f -exec mv -v {} dst/{}.bak ;

¿Bien hecho ahora? No... Olvidé lo que puede haber en el nombre del archivo. n.

touch x
mv x  "$(printf "foonbar")"
find . -type f -print0 | xargs -0 mv -t /path/to/target-dir

Herramientas de análisis estático

El problema del paso anterior podría detectarse cuando olvidamos las comillas, para ello existen muchos remedios en la naturaleza. comprobación de concha, en general, hay muchos y lo más probable es que puedas encontrar un linter para tu pila en tu IDE.

Idioma

golpear
comprobación de concha

Rubí
RuboCop

pitón
Pylint

ansible
Pelusa ansible

Pruebas IaC: pruebas unitarias

Lo que aprendí al probar 200 líneas de código de infraestructura

Como vimos en el ejemplo anterior, los linters no son omnipotentes y no pueden señalar todas las áreas problemáticas. Además, por analogía con las pruebas en el desarrollo de software, podemos recordar las pruebas unitarias. Lo que inmediatamente me viene a la mente es shunita, junta, Rspec, pytest. ¿Pero qué hacer con ansible, chef, saltstack y otros como ellos?

Al principio hablamos de SÓLIDO y que nuestra infraestructura debería consistir en pequeños ladrillos. Ha llegado su hora.

  1. La infraestructura se divide en pequeños ladrillos, por ejemplo, roles de Ansible.
  2. Se implementa algún tipo de entorno, ya sea Docker o una máquina virtual.
  3. Aplicamos nuestro rol Ansible a este entorno de prueba.
  4. Comprobamos que todo funcionó como esperábamos (realizamos pruebas).
  5. Nosotros decidimos si está bien o no.

Pruebas IaC: herramientas de pruebas unitarias

Pregunta, ¿qué son las pruebas para CFM? Puede simplemente ejecutar el script o puede utilizar soluciones listas para usar para esto:

CFM

Ansible
Infraestructura de pruebas

Chef
inspeccionar

Chef
Especificaciones del servidor

pila de sal
Goss

Ejemplo de testinfra, comprobando que los usuarios test1, test2 existen y están en un grupo sshusers:

def test_default_users(host):
    users = ['test1', 'test2' ]
    for login in users:
        assert host.user(login).exists
        assert 'sshusers' in host.user(login).groups

¿Qué elegir? La pregunta es compleja y ambigua, aquí hay un ejemplo de cambios en proyectos en github para 2018-2019:

Lo que aprendí al probar 200 líneas de código de infraestructura

Marcos de prueba de IaC

Surge la pregunta: ¿cómo juntarlo todo y lanzarlo? Poder tómalo y hazlo tú mismo si hay un número suficiente de ingenieros. O puede optar por soluciones ya preparadas, aunque no hay muchas:

CFM

Ansible
molécula

Chef
Cocina de prueba

Terraform
Terratest

Ejemplo de cambios en proyectos en github para 2018-2019:

Lo que aprendí al probar 200 líneas de código de infraestructura

Molécula vs. cocina de prueba

Lo que aprendí al probar 200 líneas de código de infraestructura

Inicialmente nosotros Intenté usar testkitchen:

  1. Cree una máquina virtual en paralelo.
  2. Aplicar roles de Ansible.
  3. Ejecutar inspección.

Para 25-35 roles funcionó entre 40 y 70 minutos, lo cual fue mucho.

Lo que aprendí al probar 200 líneas de código de infraestructura

El siguiente paso fue la transición a jenkins/docker/ansible/molécula. Idiológicamente todo es igual.

  1. Libros de jugadas de pelusa.
  2. Alinea los roles.
  3. Contenedor de lanzamiento
  4. Aplicar roles de Ansible.
  5. Ejecute testinfra.
  6. Comprueba la idempotencia.

Lo que aprendí al probar 200 líneas de código de infraestructura

La peladura de 40 roles y las pruebas de una docena comenzaron a llevar unos 15 minutos.

Lo que aprendí al probar 200 líneas de código de infraestructura

Qué elegir depende de muchos factores, como la pila utilizada, la experiencia del equipo, etc. aquí cada uno decide por sí mismo cómo cerrar la pregunta de prueba unitaria

Pruebas de IaC: pruebas de integración

Lo que aprendí al probar 200 líneas de código de infraestructura

El siguiente paso en la pirámide de pruebas de infraestructura serán las pruebas de integración. Son similares a las pruebas unitarias:

  1. La infraestructura se divide en pequeños bloques, por ejemplo, roles de Ansible.
  2. Se implementa algún tipo de entorno, ya sea Docker o una máquina virtual.
  3. Para este entorno de prueba aplicar muchos Roles ansibles.
  4. Comprobamos que todo funcionó como esperábamos (realizamos pruebas).
  5. Nosotros decidimos si está bien o no.

En términos generales, no verificamos el rendimiento de un elemento individual del sistema como en las pruebas unitarias, verificamos cómo está configurado el servidor en su conjunto.

Pruebas de IaC: pruebas de extremo a extremo

Lo que aprendí al probar 200 líneas de código de infraestructura

En la cima de la pirámide nos reciben las pruebas de extremo a extremo. Aquellos. No verificamos el rendimiento de un servidor separado, un script separado o un bloque separado de nuestra infraestructura. Comprobamos que muchos servidores conectados entre sí, nuestra infraestructura funciona como esperamos. Desafortunadamente, nunca he visto soluciones en caja listas para usar, probablemente porque... La infraestructura suele ser única y difícil de modelar y crear un marco para realizar pruebas. Como resultado, cada uno crea sus propias soluciones. Hay una demanda, pero no hay respuesta. Por lo tanto, les diré lo que hay para incitar a otros a tener pensamientos sensatos o para restregarme en la nariz el hecho de que todo se inventó hace mucho tiempo antes que nosotros.

Lo que aprendí al probar 200 líneas de código de infraestructura

Un proyecto con una rica historia. Se utiliza en grandes organizaciones y probablemente cada uno de ustedes se haya cruzado indirectamente con él. La aplicación admite muchas bases de datos, integraciones, etc. Saber cómo se vería la infraestructura son muchos archivos de composición acoplable, y saber qué pruebas ejecutar en qué entorno es Jenkins.

Lo que aprendí al probar 200 líneas de código de infraestructura

Este esquema funcionó durante bastante tiempo, hasta que en el marco investigación No hemos intentado transferir esto a Openshift. Los contenedores siguen siendo los mismos, pero el entorno de lanzamiento ha cambiado (hola DRY de nuevo).

Lo que aprendí al probar 200 líneas de código de infraestructura

La idea de la investigación fue más allá y en openshift encontraron algo llamado APB (Ansible Playbook Bundle), que permite agrupar conocimientos sobre cómo implementar infraestructura en un contenedor. Aquellos. existe un punto de conocimiento repetible y comprobable sobre cómo implementar la infraestructura.

Lo que aprendí al probar 200 líneas de código de infraestructura

Todo esto sonaba bien hasta que nos topamos con una infraestructura heterogénea: necesitábamos Windows para las pruebas. Como resultado, el conocimiento de qué, dónde, cómo implementar y probar está en jenkins.

Conclusión

Lo que aprendí al probar 200 líneas de código de infraestructura

La infraestructura como código es

  • Código en el repositorio.
  • Interacción humana.
  • Pruebas de infraestructura.

enlaces

Fuente: habr.com

Añadir un comentario