En una de las reuniones de la comunidad St.Net .Net de desarrolladores de la comunidad SpbDotNet, realizamos un experimento y decidimos hablar sobre cómo puede aplicar enfoques que se han convertido en estándar en el mundo Linux para automatizar las infraestructuras de Windows. Pero para no llevar todo al punto de marcar el marcador Ansible, se decidió mostrar esto con el ejemplo de implementación de una aplicación ASP.Net.
Aleksey Chernov, Desarrollador Senior del equipo que desarrolla la biblioteca de componentes de UI para nuestros proyectos, se ofreció como orador. Y sí, no te pareció: un desarrollador de JavaScript se presentó frente a una audiencia .Net.
Cualquiera que esté interesado en el resultado de tal experimento, bienvenido, bajo el corte para decodificar.
Hola) Ya se han echado a perder un poco aquí y han dicho que soy front-end, por lo que ya pueden divergir =) Mi nombre es Alexey, he estado haciendo todo tipo de cosas sobre desarrollo web durante bastante tiempo. Comencé con Perl, luego estaba PHP, un pequeño RoR, un poco, un poco de eso. Y luego JavaScript irrumpió en mi vida, y desde entonces he estado haciendo casi todo esto.
Además de JS, últimamente he estado escribiendo bastantes autotests (además, en el mismo JS) y, por lo tanto, tengo que lidiar con la automatización del despliegue de bancos de pruebas y la infraestructura para ellos.
Antecedentes
Hace dos años, terminé en Veeam, donde están desarrollando productos para Windows. En ese momento me sorprendió mucho, pero resultó que sucede =). Pero, sobre todo, me sorprendió el nivel inusualmente bajo de automatización de todo lo relacionado con la implementación, la implementación de aplicaciones, las pruebas, etc.
Nosotros, los que estamos desarrollando para Linux, nos hemos acostumbrado al hecho de que todo debería estar en Docker, hay Kubernetes, y todo se desarrolla con un solo clic. Y cuando terminé en un entorno donde todo esto no está allí, me sorprendió. Y cuando comencé a hacer pruebas automáticas, me di cuenta de que esto era solo un 20% de éxito, y todo lo demás estaba preparando la infraestructura para ellos.

Mis sentimientos al principio
Condiciones actuales
Te contaré un poco sobre cómo se arregla todo con nosotros, qué tenemos que automatizar y qué hacemos.
Tenemos un montón de productos diferentes, la mayoría de ellos bajo Windows, hay varios bajo Linux e incluso algo bajo Solaris. Se recopilan muchas compilaciones diariamente para todos los productos. En consecuencia, es necesario implementarlo todo en los laboratorios de prueba, tanto para el control de calidad como para los propios desarrolladores, para que puedan verificar la integración de la aplicación. Todo esto requiere una gran infraestructura de muchos servidores de hierro y máquinas virtuales. Y a veces hacemos pruebas de rendimiento, cuando necesitamos levantar de inmediato mil máquinas virtuales y ver qué tan rápido funcionarán nuestras aplicaciones.
Los problemas
Por supuesto, en las primeras etapas (leer, hace mucho tiempo), cuando intentaba automatizar todo de frente, se usaba PowerShell. La herramienta es poderosa, pero los scripts de implementación son extremadamente complicados. Otro problema fue la falta de gestión centralizada de este proceso. Algunos scripts fueron ejecutados localmente por desarrolladores, algunos en máquinas virtuales creadas en la era de los mamuts, etc. Como resultado: fue difícil obtener un solo resultado y comprender qué funciona y qué no. Vienes a trabajar, abres el navegador: el servidor no está disponible. Por qué no está disponible, qué sucedió, dónde se rompió, no estaba completamente claro. No había un único punto de entrada, y tenía que buscar la verdad en las salas de chat en funcionamiento, y es bueno que alguien responda.
Otro problema, no tan obvio, son los novatos. Fue difícil para ellos. La primera semana de trabajo, solo profundizaron en lo que estaba sucediendo. Habitualmente vivíamos con esto, asegurándonos a nosotros mismos que la vida es algo difícil y que debemos soportarlo. Para comprender y perdonar, por así decirlo.
Pero en algún momento encontraron la fuerza interior para superarlo y mirar a su alrededor. Probablemente de alguna manera puedes manejarlo.

El primer paso para resolver el problema es aceptarlo.
Selección de soluciones
Cuando no sabes qué hacer, mira lo que otros están haciendo.
Y para empezar, hicimos nuestra lista de requisitos para lo que queremos obtener al final.
- Código de base unificado. Todos los scripts de implementación deben estar en el mismo lugar. Desea implementar algo o ver cómo se desarrolla: aquí hay un repositorio para usted, vaya allí.
- Todos saben cómo funciona. Las preguntas deberían desaparecer a la "No entiendo cómo implementarlo, así que el segundo día no puedo cerrar el error".
- Posibilidad de comenzar por botón. Necesitamos poder controlar las implementaciones. Por ejemplo, algún tipo de interfaz web, donde vayas, presionas un botón, y el producto deseado se implementa en el host deseado.
Después de asegurarnos de que esta lista cubra el mínimo de requisitos necesarios y suficientes para nuestra felicidad, comenzamos a intentarlo. Tradicionalmente, lo primero que intentaron resolver problemas fue el método de ataque frontal. ¿Tenemos muchos scripts de PowerShell? Así que combinémoslos en un solo repositorio. Pero el problema no es que haya demasiados guiones, sino que diferentes equipos hicieron lo mismo con diferentes guiones. Caminé por diferentes equipos, escuché sus requisitos, recopilé los mismos scripts, intenté peinarlos y parametrizarlos de alguna manera, y luego los puse en un solo repositorio.
Fallo: el intento falló. En primer lugar, comenzamos a discutir mucho sobre por qué estamos haciendo esto y no de esa manera. ¿Por qué se utilizó este método, y no otro, etc. Y como resultado, había muchos que querían rehacer todo "como debería", en el principio de "Voy a bifurcar y reescribir todo por usted". Y, por supuesto, no será posible combinar ramas con este enfoque.
Intento número dos: se suponía que debía tomar nuestro servidor CI (TeamCity), hacer algunas plantillas y, utilizando la herencia, cerrar el problema principal desde el primer intento. Pero, como habrás adivinado de inmediato, Fail también nos estaba esperando : puedes usar la plantilla solo para la última versión, lo que significa que no lograremos las versiones necesarias. Y la consecuencia de una gran cantidad de equipos: las plantillas se volvieron muy numerosas, se hizo más difícil administrarlas y en el horizonte era claramente visible un nuevo pantano.

Cansado de caer boca abajo en cualquier intento de despegar, se decidió volver a sentarse y pensar mucho. Entonces, tenemos una gran cantidad de scripts ps por un lado y una gran cantidad de virtuales por el otro. Pero nos equivocamos, porque esa no era la raíz del problema. El problema era que siempre había una persona entre estas cosas. No importa si se trata de un desarrollador, un probador u otra persona, la siguiente cadena lógica siempre ha ocurrido en la cabeza:
- Entonces, necesito una máquina virtual para las pruebas
- Sí, aquí tenemos un grupo de servidores.
- Y aquí está el script que necesito, ahora lo ejecutaré y todo sucederá
Con la realización de algo aparentemente tan simple, el problema general comenzó a jugar con nuevos colores. Resultó que todos nuestros dolores son por la falta de una descripción única de nuestra infraestructura. Estaba en la mente de las personas que lo crearon, se sentaron en diferentes departamentos, no buscaron documentarlo de alguna manera y, en general, cada uno vivió en su propio estado.
En este momento, llegamos a la conclusión de que la respuesta a todos nuestros problemas es:
Infraestructura como código
Es precisamente que toda nuestra infraestructura debe describirse en código y depositarse en el repositorio. Todas las máquinas virtuales, todos sus parámetros, todo lo que está instalado allí, todo debe describirse en el código.
Surge una pregunta legítima: ¿por qué?
Respondemos: este enfoque nos dará la oportunidad de aplicar las mejores prácticas del mundo del desarrollo, al que todos estamos tan acostumbrados:
- Control de versiones. Siempre podemos entender qué y cuándo ha cambiado. No más anfitriones saliendo de la nada o ido a ninguna parte. Siempre estará claro quién hizo los cambios.
- Revisión de código. Podremos controlar los procesos de implementación para que algunos no infrinjan a otros.
- Integración continua.
Selección de herramienta
Como todos sabemos, hay muchas herramientas de administración de configuración. Optamos por Ansible, porque contiene un conjunto de características que necesitamos.
En primer lugar, queremos que el sistema de automatización no ejecute ningún instalador, algo para migrar a algún lado, etc. En primer lugar, desde ese sistema queremos que después de presionar un botón veamos la interfaz de usuario de la aplicación que necesitamos.
Por lo tanto, la característica clave para nosotros es la idempotencia. Ansible no importa lo que pasó antes. Después de comenzar el libro de jugadas deseado, siempre obtenemos el mismo resultado. Esto es muy importante cuando dices no "Instalar IIS", sino "Debe haber IIS", y no tienes que pensar si estuvo allí antes o no. Es muy difícil lograr esto con los guiones, y los libros de jugadas de Ansible brindan esa oportunidad.
También vale la pena mencionar la falta de agente de Ansible. La mayoría de los sistemas de automatización funcionan a través de agentes. Hay muchas ventajas en esto, por ejemplo, el mejor rendimiento, pero era importante para nosotros que no hubiera un agente para que el sistema no tuviera que estar preparado de alguna manera adicional.
PowerShell:
$url = "http://buildserver/build.msi" $output = "$PSSscriptRoot\build.msi" Invoke-WebRequest -Uri $url -OutFile $output
Ansible:
name: Download build hosts: all tasks: name: Download installer win_get_url: url: "http://buildserver/build.msi" dest: "build.msi" force: no
Aquí vemos que en el ejemplo básico, el script ps será aún más conciso que el libro de jugadas de Ansible. 3 líneas de guión versus 7 líneas de libro de jugadas para descargar un archivo.
Pero, Petka, hay un matiz (s). Tan pronto como queramos observar el principio de idempotencia y, por ejemplo, asegurarnos de que el archivo en el servidor no haya cambiado y no necesite descargarlo, deberá implementar una solicitud HEAD en el script, que agrega aproximadamente 200 líneas. Y en el libro de jugadas, uno. El módulo Ansible win_get_url, que realiza todas las comprobaciones por usted, contiene 257 líneas de código que no tiene que insertar en cada secuencia de comandos.
Y este es solo un ejemplo de una tarea muy simple.

Y si lo piensas, necesitamos idempotencia en todas partes:
- Verificar la existencia de una máquina virtual. En el caso de los scripts, corremos el riesgo de producir un número infinito de ellos, o el script se bloqueará al principio.
- ¿Qué paquetes msi hay en la máquina? En el mejor de los casos, aquí no caerá nada; en el peor de los casos, la máquina dejará de funcionar adecuadamente.
- ¿Tengo que volver a descargar artefactos de compilación? Es bueno si tus construcciones pesan una docena de megabytes. ¿Y los que tienen un par de gigabytes?
Y otros ejemplos, donde la salida es inflar scripts con ramificaciones interminables de ifs que no se pueden depurar adecuadamente e imposibles de administrar.
Entre otras cosas que son importantes para nosotros, Ansible no utiliza agentes para administrar sus hosts y máquinas. En Linux, por supuesto, se ejecuta en ssh, mientras que en Windows se usa WinRM. De ahí la consecuencia obvia: Ansible es multiplataforma. Admite una cantidad fantástica de plataformas, hasta equipos de red.
Y el último, pero no menos importante, es el formato de grabación de configuración YAML. Todos están acostumbrados, es fácil de leer y es fácil darse cuenta de lo que está sucediendo allí.
Pero no todo es tan dulce, hay problemas:
- El problema es dudoso: para ejecutar libros de jugadas, aún necesita una máquina Linux, incluso si toda su infraestructura es exclusivamente Windows. Aunque este no es un gran problema en el mundo moderno, porque en Windows 10 ahora hay WSL, donde puedes ejecutar Ubuntu, bajo el cual manejar playbooks.
- A veces, los libros de jugadas son realmente difíciles de depurar. Ansible está escrito en python, y lo último que quiero ver es una hoja de pila de pila de python de cinco pantallas. Y un error tipográfico en el nombre del módulo
Como funciona
Primero, necesitamos una máquina Linux. En la terminología de Ansible, esto se llama la máquina de control.
Los libros de jugadas comenzarán a partir de él, y toda la magia sucede en él.
En esta máquina necesitaremos:
- Python y el administrador de paquetes python pip. Muchas distribuciones tienen fuera de la caja, por lo que no hay sorpresas aquí.
- Instale Ansible a través de pip, como la forma más universal: pip install ansible
- Agregue un módulo winrm para ir a máquinas Windows: pip install pywinrm [credssp]
- Y en las máquinas que queremos controlar, necesitamos habilitar winrm, porque Está desactivado por defecto. Hay muchas formas de hacer esto, y todas se describen en la documentación de Ansible. Pero lo más simple es tomar la secuencia de comandos finalizada del repositorio de Ansible y ejecutarla con la opción de autorización requerida: ConfigureRemotingForAnsible.ps1 -EnableCredSSP
La parte más importante que necesitábamos para dejar de sufrir con los scripts ps era Inventory. Un archivo YAML (en nuestro caso), que describe nuestra infraestructura y dónde siempre puede mirar para entender dónde se implementa. Y, por supuesto, los propios libros de jugadas. En el futuro, el trabajo parece lanzar un libro de jugadas con el archivo de inventario necesario y parámetros adicionales.
all: children: webservers: hosts: spbdotnet-test-host.dev.local: dbservers: hosts: spbdotnet-test-host.dev.local: vars: ansible_connection: winrm ansible_winrm_transport: credssp ansible_winrm_server_cert_validation: ignore ansible_user: administrator ansible_password: 123qweASD
Aquí todo es simple: el grupo raíz es todos y dos subgrupos, servidores web y servidores de base de datos. Todo lo demás es intuitivo, pero llamaré su atención sobre el hecho de que Ansible por defecto cree que Linux está en todas partes, por lo que para Windows debe especificar winrm y el tipo de autorización.
Por supuesto, no necesita almacenar la contraseña de forma clara en el libro de jugadas, aquí hay solo un ejemplo. Las contraseñas se pueden almacenar, por ejemplo, en Ansible-Vault. Usamos TeamCity para esto, que pasa secretos a través de variables de entorno y no dispara nada.
Módulos
Todo lo que Ansible hace, lo hace con la ayuda de módulos. Los módulos para Linux están escritos en python, para Windows en PowerShell. Y una reverencia por la idempotencia: el resultado del módulo siempre viene en forma de un archivo json, que indica si ha habido cambios en el host o no.
En el caso general, ejecutaremos una construcción de la lista de módulos de archivo de inventario de grupo de host ansible del formulario:

Libros de jugadas
Un libro de jugadas es una descripción de cómo y dónde ejecutaremos los módulos Ansible.
- name: Install AWS CLI hosts: all vars: aws_cli_download_dir: c:\downloads aws_cli_msi_url: https://s3.amazonaws.com/aws-cli/AWSCLI32PY3.msi tasks: - name: Ensure target directory exists win_file: path: "{{ aws_cli_download_dir }}" state: directory - name: Download installer win_get_url: url: "{{ aws_cli_msi_url }}" dest: "{{ aws_cli_download_dir }}\\awscli.msi" force: no - name: Install AWS CLI win_package: path: "{{ aws_cli_download_dir }}\\awscli.msi" state: present
En este ejemplo, tenemos tres tareas. Cada tarea es una llamada de módulo. En este libro de jugadas, primero creamos un directorio (nos aseguramos de que exista), luego descargamos la AWS CLI allí e lo instalamos utilizando el módulo win_packge.
Al ejecutar este libro de jugadas, obtenemos este resultado.

El informe muestra que cuatro tareas se completaron con éxito y tres de las cuatro realizaron algunos cambios en el host.
Pero, ¿qué sucede si vuelves a ejecutar este libro de jugadas? No hemos escrito en ningún lugar que debamos crear el directorio, descargar el archivo instalador y ejecutarlo. Simplemente verificamos la disponibilidad de cada artículo y omitimos si está disponible.

Esta es la idempotencia que no podríamos lograr con PowerShell.
Practica
Este es un ejemplo ligeramente simplificado, pero, en principio, esto es exactamente lo que hacemos todos los días.
Implementaremos una aplicación que consta de un servicio de Windows y una aplicación web bajo IIS.
- name: Setup App hosts: webservers tasks: - name: Install IIS win_feature: name: - Web-Server - Web-Common-Http include_sub_features: True include_management_tools: True state: present register: win_feature - name: reboot if installing Web-Server feature requires it win_reboot: when: win_feature.reboot_required
Primero, necesitamos ver si hay algún IIS en el host e instalarlo si no. Y sería bueno agregar de inmediato herramientas de administración y todas las funciones dependientes. Y es muy bueno si el host se reinicia si es necesario.
La primera tarea que resolvemos es el módulo win_feature, que se dedica a administrar las funciones de Windows. Y aquí por primera vez tenemos las variables de entorno Ansible, en el elemento de registro. ¿Recuerdas que dije que las tareas siempre devuelven un objeto json? Ahora, después de completar la tarea Instalar IIS, la salida del módulo win_feature se encuentra en la variable win_feature (discúlpeme por la tautología).
En la siguiente tarea, llamaremos al módulo win_reboot. Pero no necesitamos reiniciar nuestro servidor cada vez. Lo volveremos a cargar solo si el módulo win_feature nos devuelve este requisito en forma de variable.
El siguiente paso es instalar SQL. Ya se han inventado un millón de formas para hacer esto. Estoy usando el módulo win_chocolatey aquí. Este es un administrador de paquetes para Windows. Sí, eso es exactamente a lo que estamos tan acostumbrados en Linux. Los módulos son compatibles con la comunidad, y ahora ya hay más de seis mil de ellos. Te recomiendo encarecidamente que lo intentes.
- name: SQL Server hosts: dbservers tasks: - name: Install MS SQL Server 2014 win_chocolatey: name: mssqlserver2014express state: present
Entonces, preparamos el host para iniciar la aplicación, ¡impleméntelo!
- name: Deploy binaries hosts: webservers vars: myapp_artifacts: files/MyAppService.zip myapp_workdir: C:\myapp tasks: - name: Remove Service if exists win_service: name: MyAppService state: absent path: "{{ myapp_workdir }}\\MyAppService.exe"
Por si acaso, lo primero que hacemos es eliminar el servicio existente.
- name: Delete old files win_file: path: "{{ myapp_workdir }}\\" state: absent - name: Copy artifacts to remote machine win_copy: src: "{{ myapp_artifacts }}" dest: "{{ myapp_workdir }}\\" - name: Unzip build artifacts win_unzip: src: "{{ myapp_workdir }}\\MyAppService.zip" dest: "{{ myapp_workdir }}"
El siguiente paso es cargar nuevos artefactos en el host. Este libro de jugadas implica que se ejecuta en un servidor de compilación, todos los archivos están en una carpeta conocida e indicamos la ruta a ellos con variables. Después de copiar (win_copy), los archivos se desempaquetan (win_unzip). Luego solo registramos el servicio, decimos la ruta a exe y que debería iniciarse.
- name: Register and start the service win_service: name: ReporterService start_mode: auto state: started path: "{{ myapp_workdir }}\\MyAppService.exe"
Listo?
Parece que nuestro servicio está listo para el trabajo y la defensa, sin embargo, hay un "pero": no observamos el principio de idempotencia. Siempre eliminamos el código existente y luego implementamos el nuevo.
Y ese es el problema. Si eliminamos el antiguo servicio fuera de servicio, y después de que ocurriera algún tipo de error y el libro de jugadas no completara su trabajo, obtendremos un host roto. O, por ejemplo, implementamos varias aplicaciones al mismo tiempo, de las cuales una no ha cambiado, entonces no necesitamos implementarla también.
Que se puede hacer Alternativamente, puede verificar la suma de verificación de nuestros artefactos y compararlos con los del servidor.
- name: Get arifacts checksum stat: path: "{{ myapp_artifacts }}" delegate_to: localhost register: myapp_artifacts_stat - name: Get remote artifacts checksum win_stat: path: "{{ myapp_workdir }}\\MyAppService.zip" register: myapp_remote_artifacts_stat
Utilizamos el módulo stat, que proporciona todo tipo de información sobre archivos, incluida la suma de verificación. Luego, usando el registro de directivas familiar, escribimos el resultado en una variable. De interesante: delegate_to indica que esto debe hacerse en la máquina local donde se inicia el libro de jugadas.
- name: Stop play if checksums match meta: end_play when: - myapp_artifacts_stat.stat.checksum is defined - myapp_remote_artifacts_stat.stat.checksum is defined - myapp_artifacts_stat.stat.checksum == myapp_remote_artifacts_stat.stat.checksum
Y con la ayuda del metamódulo, decimos que necesitamos terminar el libro de jugadas si las sumas de verificación de los artefactos en las máquinas locales y remotas coinciden. Así es como observamos el principio de idempotencia.
- name: Ensure that the WebApp application exists win_iis_webapplication: name: WebApp physical_path: c:\webapp site: Default Web Site state: present
Ahora echemos un vistazo a nuestra aplicación web. Omitimos la parte sobre la copia de archivos, vamos directamente al grano. Nuestro servidor de compilación creó el editor, cargó todos los archivos sueltos en el host y usó el módulo incorporado para trabajar con aplicaciones IIS. Creará la aplicación y la ejecutará.
Reutilización de código
Una de las tareas que establecimos fue: permitir que cualquier ingeniero de la empresa inicie fácilmente una implementación. Escribe su libro de jugadas a partir de módulos listos para usar, dice que necesita ejecutar tal o cual producto en tal y tal host.
Para esto, Ansible tiene roles. Esto es esencialmente una convención. Creamos una carpeta / roles / en el servidor y ponemos nuestros roles en él. Cada rol es un conjunto de archivos de configuración: una descripción de nuestros dispositivos, variables, archivos de servicio, etc. Por lo general, una entidad aislada hace un papel. Instalar IIS es un gran ejemplo si necesitamos no solo instalarlo, sino también configurarlo de alguna manera o verificarlo con tareas adicionales. Hacemos un rol separado y, por lo tanto, aislamos todos los libros de jugadas relacionados con IIS en la carpeta de roles. En el futuro, simplemente llamamos a este rol con la directiva include_role% role_name%.
Naturalmente, creamos roles para todas las aplicaciones, dejando a los ingenieros la oportunidad de personalizar de alguna manera el proceso utilizando parámetros de configuración.
- name: Run App hosts: webservers tasks: - name: "Install IIS" include_role: name: IIS - name: Run My App include_role: name: MyAppService vars: myapp_artifacts: ./buld.zip
En este ejemplo, la función Ejecutar mi aplicación tiene la capacidad de transferir alguna ruta a artefactos.
Aquí tiene que poner una palabra sobre Ansible Galaxy, un repositorio de soluciones estándar comúnmente disponibles. Como es habitual en una sociedad decente, muchos problemas ya se han resuelto ante nosotros. Y si existe la sensación de que ahora comenzaremos a reinventar la rueda, primero debe mirar la lista de módulos integrados y luego profundizar en Ansible Galaxy. Es probable que el libro de jugadas que necesita ya haya sido creado por otra persona. Hay una gran cantidad de módulos allí, para todas las ocasiones.
Mayor flexibilidad
Pero, ¿qué pasa si no hay un módulo incorporado o una función adecuada en Galaxy? Hay dos opciones: o estamos haciendo algo mal, o realmente tenemos una tarea única.
En el caso de la segunda opción, siempre podemos escribir nuestro módulo. Como te mostré al principio, Ansible hace posible escribir el módulo más simple en literalmente 10 minutos, y cuando profundizas, te ayuda una documentación bastante detallada que cubre muchas preguntas.
Ci
En nuestro departamento, realmente amamos TeamCity, pero puede haber cualquier otro servidor de CI que elija. ¿Por qué necesitamos compartirlos?
En primer lugar, siempre podemos verificar la sintaxis de nuestros libros de jugadas. Si bien YAML considera que las pestañas son un error de sintaxis, esta es una característica muy útil.
También en el servidor CI ejecutamos ansible-lint. Este es un analizador estático de configuraciones ansibles, que ofrece una lista de recomendaciones.

Por ejemplo, aquí dice que tenemos un espacio extra al final de la línea, y para una tarea no se da ningún nombre. Esto es importante porque el nombre del módulo puede aparecer varias veces en el mismo libro de jugadas y todas las tareas deben nombrarse.
Por supuesto, aún puede escribir pruebas para libros de jugadas. Podemos permitirnos no hacer esto porque implementaremos en el entorno de prueba y no sucederá nada crítico. Pero si se implementa en el producto, sería mejor verificarlo todo. El beneficio de ansible le permite probar no solo libros de jugadas, sino también módulos individuales. Así que asegúrese de prestarle atención.
Y la segunda razón principal para usar el servidor CI es lanzar playbooks. Este es el mismo botón mágico "Hacer bien", que nos da TeamCity. Simplemente creamos algunas configuraciones simples para diferentes productos, donde decimos: ansible-playbook reporter_vm.yml -i Inventory.yml -vvvv y obtenemos el botón Implementar.
Comodidad adicional: puede construir compilaciones dependiendo de las compilaciones. Tan pronto como algo se ha consolidado, TeamCity comienza el proceso de reimplementación, después de lo cual solo podemos mirar los registros si algo se rompe repentinamente.
Total
- Scripts de PowerShell confusos y dispares que reemplazamos con configuraciones YAML.
- Reemplazamos varias implementaciones de los mismos problemas con roles comunes que pueden reutilizarse. Se ha creado un repositorio donde se encuentran los roles. Si el rol te conviene, solo utilízalo. Si no le conviene, simplemente envíe la solicitud de grupo, y le conviene =)
- Ahora puede verificar el éxito de la implementación en un solo lugar.
- Todos saben dónde buscar registros.
- Los problemas de comunicación también se resolvieron a través de un repositorio común y TeamCity. Todas las personas interesadas saben dónde están los libros de jugadas y cómo funcionan.
PD Todos los ejemplos del artículo se pueden tomar en github .