¿Vale la pena cambiar de Powershell DSC a Ansible y cómo hacerlo?

Poco se escribe sobre IaC en Windows, porque DevOps / SRE está asociado principalmente con Linux y Kubernetes. Decidimos remediar esta situación y comparar las herramientas que se pueden utilizar para administrar IaC basado en Windows. El artículo será útil para los desarrolladores que trabajan con infraestructura de Windows y eligen métodos de gestión, y para aquellos que ya han implementado Powershell DSC o Ansible, pero tienen dudas sobre su decisión. A continuación compartiremos nuestra experiencia y te contaremos:

  • cómo funciona Powershell DSC y en qué se diferencia de Ansible al administrar la infraestructura en Windows;
  • por qué nos cambiamos a Ansible;
  • qué problemas enfrentaron y cómo se resolvieron;
  • cómo se comparan las expectativas y la realidad después de cambiar a Ansible;
  • quién debería elegir Powershell DSC y quién debería elegir Ansible.


Por qué se eligió originalmente PowerShell DSC



Mindbox tiene una cultura DevOps / SRE desarrollada, a pesar de la infraestructura predominantemente de Windows: Hyper-V, IIS, MS SQL Server. Y aunque la compañía se está moviendo gradualmente a Linux y Open Source, Windows todavía prevalece.



Para administrar esta infraestructura, planearon usar código de infraestructura: escribirlo, guardarlo en el repositorio y luego usar alguna herramienta para convertir el código en infraestructura real. Si bien Ansible es la herramienta de administración de infraestructura basada en código más popular, tradicionalmente se ha asociado con el mundo de Linux. Queríamos algo nativo y específico de Windows, por lo que elegimos PowerShell DSC.



Cómo funciona Powershell DSC



La configuración de estado deseado de PowerShell (DSC) es un servicio que viene con Windows listo para usar y lo ayuda a administrar su infraestructura a través de archivos de configuración. Acepta el código de infraestructura en PowerShell como entrada y lo transforma internamente en comandos que configuran el sistema. Además de las operaciones triviales, como instalar componentes de Windows, modificar claves de registro, crear archivos o configurar servicios, puede hacer muchas cosas que suelen hacer los scripts de PowerShell. Por ejemplo, un ciclo completo de configuración de DNS o una instancia de MS SQL Server de alta disponibilidad.







Enlaces útiles al diagrama:

Ejemplo de una configuración simple para documentos DSC

Cómo usar archivos de datos

SQL Server- Windows Server 2019

DSC pull server SQL Windows Server 2019



DSC Ansible



DSC Ansible
. pull-, , .NET Framework 4.0 WMF 5.1 , ansible, ansible-playbook ansible-inventory. Linux-, — python
,
Pull/push- Pull push push
pull-
-: , , , -: , ,
~1300 Gallery ~20000 Ansible Galaxy
PowerShell YAML
, Ansible
()


, DSC



Las expectativas de DSC no se cumplieron en todos los sentidos. Además, durante el trabajo, surgieron nuevas necesidades que no pudieron ser satisfechas con la ayuda de DSC.



Los desarrolladores no pueden usar la herramienta por sí mismos sin la ayuda de la SRE. Aunque casi todos los equipos tienen un SRE, la herramienta IaC debe ser lo suficientemente simple como para que un desarrollador pueda usarla y no dedicar más de media hora a ella. DSC le permite usar no solo código declarativo, sino también cualquier construcción de Powershell. Esto significa que existe una alta probabilidad de crear un código que será difícil de mantener o que provocará una falla en la infraestructura. Por ejemplo, implementar una aplicación con parámetros incorrectos en el entorno incorrecto.



No se puede omitir la configuración de ejecución en seco antes de rodar,para ver exactamente qué cambios se aplicarán y cuáles no.



Es difícil para DSC organizar las comprobaciones de estilo de código y sintaxis. Hay pocas herramientas de validación y no están actualizadas. Ya lo hemos hecho para Ansible.



En el modo de empuje DSC, no hay una forma conveniente de rastrear el estado de las tareas. Si la configuración se aplicó con un error, se deben tomar acciones adicionales para el diagnóstico: ejecute comandos para obtener el estado de la aplicación de configuración, mire los registros de eventos. Si el error se produjo en varios servidores, lleva mucho tiempo.



El modo pull nunca se convirtió en una ventaja.En él, la configuración se aplica de forma asincrónica: es imposible saber exactamente cuándo se completa la aplicación de la nueva configuración sin correas y muletas.



Uso excesivo de dos herramientas IaC distintas que configuran servidores. Ansible puede hacer lo mismo que DSC, y ya estamos usando Ansible para configurar hosts Linux y equipos de red.



¿Cómo planeas cambiar de DSC a Ansible?



Al principio, la tarea parecía sencilla, durante aproximadamente un mes. Hemos identificado tres etapas de trabajo:

  • aprenda a conectarse a hosts de Windows usando Ansible;
  • reescriba configuraciones de DSC usando módulos Ansible;
  • elimine el servidor de extracción DSC, su base de datos y otros artefactos.


Esto es lo que era el flujo de trabajo en DSC y cómo planeamos organizarlo en Ansible:









La estructura estándar de roles en Ansible



On Ansible, planeamos separar el código complejo que configura e instala algo en el código de rol y dividir los roles en separados. repositorios. En el repositorio principal de Ansible, solo deben permanecer las llamadas a roles, anulaciones de parámetros de roles y listas de servidores por grupo. Entonces, no solo SRE, sino también cualquier desarrollador podría implementar el rol en los servidores requeridos o modificar el parámetro sin profundizar en la lógica del código de infraestructura. El desarrollador puede corregir el código de función solo después de la revisión de SRE.



¿Qué dificultades enfrentó al cambiar a Ansible y cómo se resolvieron?



Cuando comenzó el trabajo, nos dimos cuenta de que nos habíamos equivocado: la tarea no era fácil. No hubo problemas solo con el repositorio, y en otros asuntos tuve que investigar mucho y mejorar los desarrollos.



WinRM o SSH



La primera sorpresa fue la elección del tipo de conexión. En el caso de Windows, hay dos: WinRM y SSH. Resultó que Ansible es lento para ejecutar WinRM. Dicho esto, Ansible no recomienda usar OpenSSH listo para usar para Windows Server 2019. Y encontramos una nueva solución:

  1. Bifurcó y rehizo el papel de Galaxy.
  2. Escribimos un libro de jugadas que solo tiene un desafío para este papel. Este es el único libro de jugadas que se conecta a los hosts a través de WinRM.
  3. Prometheus Blackbox Exporter monitorea el puerto 22 / tcp y la versión OpenSSH como herramientas estándar :



    - alert: SSHPortDown

      expr: probe_success{job=~".*-servers-ssh",instance!~".*domain..ru"} == 0

      for: 1d

      annotations:

       summary: "Cannot reach {{`{{ $labels.instance }}`}} with SSH"




  4. LDAP- , Windows- :



    plugin: ldap_inventory

    domain: 'ldaps://domain:636'

    search_ou: "DC=domain,DC=ru"

    ldap_filter: "(&(objectCategory=computer)(operatingSystem=*server*)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"

    validate_certs: False

    exclude_hosts:

     - db-

    account_age: 15

    fqdn_format: True




  5. OpenSSH , Windows- SSH .
  6. OpenSSH . Packer, Ansible:



    "type": "shell-local",

    "tempfile_extension": ".ps1",

    "execute_command": ["powershell.exe", "{{.Vars}} {{.Script}}"],

    "env_var_format": "$env:%s=\"%s\"; ",

    "environment_vars": [

    "packer_directory={{ pwd }}",

    "ldap_machine_name={{user `ldap_machine_name`}}",

    "ldap_username={{user `ldap_username`}}",

    "ldap_password={{user `ldap_password`}}",

    "ansible_playbooks={{user `ansible_playbooks`}}",

    "github_token={{user `github_token`}}"

    ],

    "script": "./scripts/run-ansiblewithdocker.ps1"











Cuando estábamos reescribiendo el código de Ansible, periódicamente nos encontramos con la duplicación de código. Por ejemplo, casi todas las configuraciones de DSC contenían una configuración windows_exporter. Lo único que fue diferente fueron los recolectores que el exportador tuvo que usar:







para deshacernos del código duplicado, movimos windows_exporter a un rol de Ansible separado, y los parámetros de esta configuración, a variables de grupo de host.



Autenticación de segundo salto



Probablemente, la autenticación de segundo salto es el problema más común que enfrentan quienes comenzaron a usar Ansible en Windows: este diseño causa el error Acceso denegado debido al hecho de que, de manera predeterminada, es imposible delegar credenciales para la autorización en un recurso remoto sin configuraciones adicionales. Para solucionar el error, por ejemplo, new_credentials ayuda. Pero preferimos aprovechar el hecho de que Ansible puede llamar a recursos DSC a través del módulo win_dsc. Llamamos al recurso File DSC, que de forma predeterminada se ejecuta en la cuenta de la computadora. La delegación de Kerberos no es necesaria en este caso:



- name: Custom modules loaded into module directory

   win_copy:

    src: '\\share\dsc\modules'

    dest: 'C:\Program Files\WindowsPowerShell\Modules'

    remote_src: yes












- name: Custom modules loaded into module directory

   win_dsc:

    resource_name: File

    SourcePath: '\\share\dsc\modules'

    DestinationPath: 'C:\Program Files\WindowsPowerShell\Modules'

    Type: Directory

    Recurse: true

    Force: true

    MatchSource: true








Al mismo tiempo, no hay contradicción en abandonar DSC, pero usar sus recursos si resuelven mejor el problema que el módulo Ansible. El objetivo principal es dejar de usar configuraciones DSC, porque era el ecosistema DSC el que no nos convenía, y no los recursos en sí. Por ejemplo, si necesita crear un conmutador virtual de Hyper-V, tendrá que usar el recurso DSC; Ansible aún no tiene herramientas para administrar la configuración de Hyper-V.



Desconexión de la red



Algunas tareas provocan la desconexión (desconexión) de la red en servidores configurables. Por ejemplo, creando un conmutador virtual Hyper-V a partir del ejemplo anterior: el problema es que en DSC dicha llamada funciona, pero en Ansible falla porque el host administrado se ha desconectado. Esto se debe a que Windows siempre se desconecta al crear un conmutador externo virtual. La solución es agregar un argumento asíncrono a la tarea : así es como Ansible envía la tarea al host, espera un tiempo específico y solo entonces solicita el estado.



- name: External switch present

   win_dsc:

     resource_name: xVMSwitch

     Ensure: 'Present'

     Name: 'Virtual Network'

     Type: 'External'

     NetAdapterName: 'TEAM_LAN'

     AllowManagementOS: True












async: 10











Infraestructura de deriva



Cuando comenzamos a portar el código, encontramos un cambio de configuración. Estas son las diferencias reales entre lo que se describe en el código y la configuración real del servidor o software. La razón es que, en algunos casos, DSC hizo solo una parte del trabajo y el resto se realizó mediante scripts o manualmente de acuerdo con las instrucciones.



Para facilitar el trabajo con IaC, hemos recopilado todos los scripts y documentos y hemos elaborado instrucciones uniformes e inequívocas. Además, organizamos el proceso para que nadie hiciera cambios accidentales en Ansible. Almacenamos todo el código de infraestructura en GitHub y asignamos tareas a ingenieros a través de Proyectos de GitHub, por lo que tenemos la capacidad de asociar cambios al código de infraestructura (solicitudes de extracción) con tareas. Entonces podemos ver los cambios para cada tarea completada. Si la tarea no tiene ningún cambio, no se aceptará y se devolverá para su revisión.



Errores de recopilación de datos



A diferencia de DSC, Ansible recopila datos sobre los hosts administrados al inicio para que el desarrollador pueda determinar el comportamiento de las tareas según el estado del host. Al recopilar datos de los hosts de Windows, Ansible puede generar un error debido a un código de módulo incorrecto. Para solucionarlo, debe conectar la colección ansible.windows. La canalización de Ansible, antes de lanzar cada libro de jugadas, verifica la presencia de archivos requirements.yml con una lista de roles y colecciones requeridos, y luego los instala. Aquí es donde agregamos la colección ansible.windows. Colecciones



[WARNING]: Error when collecting bios facts: New-Object : Exception calling ".ctor" with "0" argument(s): "Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index" At line:2

char:21 + ... $bios = New-Object -TypeName













Es un nuevo concepto de desarrollo para Ansible. Si anteriormente solo los roles se distribuían en Galaxy, ahora puede encontrar colecciones de varios complementos y módulos, libros de jugadas y roles.



Pruebas



Antes de entregar el kit de herramientas de IaC a los desarrolladores, queríamos asegurarnos de que el código de Ansible fuera confiable y no rompiera nada. En el caso de DSC, no hubo pruebas especiales, aunque existe un marco especial para esta tarea. Las configuraciones generalmente se validaban en servidores de ensayo, cuya falla no dio lugar a defectos.



Ansible generalmente se prueba usando la herramienta de moléculas . como envoltorio para ejecutar pruebas. Es una herramienta útil para los roles de Linux, pero hay un problema con Windows. Anteriormente, la molécula podía aumentar la infraestructura por sí misma, pero ahora los desarrolladores han eliminado esta oportunidad. Ahora la infraestructura se está elevando con la ayuda de una molécula en Docker o fuera de una molécula. La prueba de los roles de Windows en Docker suele ser imposible: Hyper-V y la mayoría de las demás funciones de Windows no se instalarán en un contenedor de Docker. Tendremos que implementar la infraestructura para pruebas fuera de la molécula y usar el controlador delegado en la molécula.



Aún no hemos resuelto este problema, pero hemos encontrado herramientas que detectarán los errores más obvios:



Controlar Funcional Comentario
Verificación sintáctica Comprueba la sintaxis y la capacidad de ejecución del código. Usamos verificación de sintaxis y linting localmente y en el repositorio. Por ejemplo, incorporamos la verificación previa a la confirmación y configuramos la acción de GitHub, que se lanzará en cada solicitud de extracción.
Linting Comprueba el código en busca de errores lógicos
Ejecución en seco Le permite saber qué hará antes de iniciar el libro de jugadas. Usamos implementaciones de código en la canalización: lanzamos ansible-playbook con las marcas check y diff, luego evaluamos los cambios y confirmamos la implementación. Cuando escribimos roles, tenemos en cuenta que para algunas tareas es necesario indicar explícitamente qué deben cambiar exactamente. Por ejemplo win_command y win_shell


Cómo funciona Ansible



Luego de que implementamos Ansible y superamos todas las dificultades, se conformó el proceso de acciones de ingenieros y lanzamientos automáticos:

  1. , Linux-. , , pull request GitHub-, .
  2. pull request GitHub Actions, . Linux-, . , , .
  3. pull request. , -, .
  4. . requirements.yml, GitHub- . — . . , Ansible, . pull request, .
  5. pull request GitHub Actions, Octopus Deploy. .
  6. Octopus Deploy . , ansible-playbook: --tags, --limit --extra-vars.
  7. , , . , .


Ansible







: DSC Ansible



DSC Ansible :

  • ;
  • dry run ;
  • ;
  • .




Linux- Ansible.



Linux, Ansible Linux, CI/CD Docker-.

DSC Si la infraestructura es solo de Windows y no desea trabajar con Linux.



Si está listo para agregar sus recursos para DSC.



Es necesario almacenar el estado de la infraestructura, así como corregir su deriva.

Implementar Ansible desde cero Si está ejecutando un entorno mixto de Windows / Linux y desea convertir scripts existentes en código de infraestructura e implementarlo utilizando sistemas CI / CD.




Evgeny Berendyaev, ingeniero de SRE



All Articles