Vale a pena mudar do Powershell DSC para o Ansible e como fazer isso

Pouco se escreveu sobre IaC no Windows, porque DevOps / SRE está associado principalmente ao Linux e Kubernetes. Decidimos remediar esta situação e comparar as ferramentas que podem ser usadas para gerenciar IaC baseado em Windows. O artigo será útil para desenvolvedores que trabalham com infraestrutura Windows e escolhem métodos de gerenciamento, e para aqueles que já implementaram o Powershell DSC ou Ansible, mas têm dúvidas sobre sua decisão. A seguir, compartilharemos nossa experiência e lhe contaremos:

  • como o Powershell DSC funciona e como ele difere do Ansible ao gerenciar a infraestrutura no Windows;
  • por que mudamos para o Ansible;
  • quais problemas enfrentaram e como foram resolvidos;
  • como as expectativas e a realidade se comparam após a mudança para o Ansible;
  • quem deve escolher o Powershell DSC e quem deve escolher o Ansible.


Por que PowerShell DSC foi originalmente escolhido



Mindbox tem uma cultura DevOps / SRE desenvolvida, apesar da infraestrutura predominantemente Windows: Hyper-V, IIS, MS SQL Server. E embora a empresa esteja gradualmente mudando para Linux e Open Source, o Windows ainda prevalece.



Para gerenciar essa infraestrutura, eles planejaram usar o código da infraestrutura: escrevê-lo, salvá-lo no repositório e, em seguida, usar alguma ferramenta para transformar o código em infraestrutura real. Embora o Ansible seja a ferramenta de gerenciamento de infraestrutura baseada em código mais popular, ele tem sido tradicionalmente associado ao mundo Linux. Queríamos algo nativo e específico do Windows, então escolhemos PowerShell DSC.



Como funciona o Powershell DSC



PowerShell Desired State Configuration (DSC) é um serviço que vem com o Windows pronto para uso e ajuda você a gerenciar sua infraestrutura por meio de arquivos de configuração. Ele aceita o código de infraestrutura no PowerShell como entrada e o transforma internamente em comandos que configuram o sistema. Além de operações triviais, como instalação de componentes do Windows, modificação de chaves de registro, criação de arquivos ou configuração de serviços, ele pode fazer muitas coisas que os scripts do PowerShell costumam fazer. Por exemplo, um ciclo completo de configuração de DNS ou uma instância de MS SQL Server altamente disponível.







Links úteis para o diagrama:

Exemplo de uma configuração simples para documentos DSC

Como usar arquivos de dados

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



As expectativas do DSC não foram atendidas em todos os sentidos. Além disso, durante o trabalho, surgiram novas necessidades que não poderiam ser satisfeitas com a ajuda do DSC.



Os desenvolvedores não podem usar a ferramenta por conta própria sem a ajuda do SRE. Embora quase todas as equipes tenham um SRE, a ferramenta IaC deve ser simples o suficiente para que um desenvolvedor possa usá-la e não passar mais de meia hora nela. O DSC permite que você use não apenas código declarativo, mas também qualquer construção Powershell. Isso significa que há uma grande chance de fazer código que será difícil de manter ou que levará a uma falha de infraestrutura. Por exemplo, implementar um aplicativo com parâmetros incorretos no ambiente errado.



Não é possível pular a configuração de simulação antes de rolar,para ver exatamente quais alterações serão aplicadas e quais não.



É difícil para o DSC organizar verificações de sintaxe e estilo de código. Existem poucas ferramentas de validação e não são atualizadas. Já fizemos isso para Ansible.



No modo push DSC, não há maneira conveniente de rastrear o status das tarefas. Se a configuração foi aplicada com um erro, ações adicionais devem ser executadas para diagnóstico: execute comandos para obter o status do aplicativo de configuração, consulte os logs de eventos. Se o erro ocorreu em vários servidores, é demorado.



O modo pull nunca se tornou uma vantagem.Nele, a configuração é aplicada de forma assíncrona - é impossível saber exatamente quando a aplicação da nova configuração é concluída sem alças e muletas.



Uso excessivo de duas ferramentas IaC distintas que configuram servidores. O Ansible pode fazer o mesmo que o DSC e já estamos usando o Ansible para configurar hosts Linux e equipamentos de rede.



Como você planejou mudar de DSC para Ansible



No início, a tarefa parecia simples, por cerca de um mês. Identificamos três estágios de trabalho:

  • aprenda como se conectar a hosts Windows usando Ansible;
  • reescrever configurações DSC usando módulos Ansible;
  • remova o servidor pull DSC, seu banco de dados e outros artefatos.


Aqui está o que o fluxo de trabalho era no DSC e como planejamos organizá-lo em Ansible:









A estrutura padrão de funções em Ansible



On Ansible, planejamos separar o código complexo que configura e instala algo no código de função e dividir as funções em partes separadas repositórios. No repositório principal Ansible, apenas as chamadas para funções, substituições de parâmetros de funções e listas de servidores por grupo devem permanecer. Portanto, não apenas o SRE, mas também qualquer desenvolvedor pode implantar a função nos servidores necessários ou ajustar o parâmetro sem se aprofundar na lógica do código de infraestrutura. O desenvolvedor pode corrigir o código da função somente após a revisão do SRE.



Quais dificuldades você enfrentou ao mudar para o Ansible e como elas foram resolvidas



Quando o trabalho começou, percebemos que estávamos errados: a tarefa não era fácil. Não houve problemas apenas com o repositório, e em outros assuntos tive que pesquisar muito e melhorar os desenvolvimentos.



WinRM ou SSH



A primeira surpresa foi a escolha do tipo de conexão. No caso do Windows, existem dois deles - WinRM e SSH. Descobriu-se que o Ansible é lento para executar o WinRM. Dito isso, a Ansible não recomenda o uso do OpenSSH pronto para uso no Windows Server 2019. E encontramos uma nova solução:

  1. Bifurcou e refez o papel do Galaxy.
  2. Escrevemos um manual que só desafia essa função. Este é o único manual que se conecta a hosts via WinRM.
  3. O Prometheus Blackbox Exporter monitora a porta 22 / tcp e a versão OpenSSH como ferramentas padrão :



    - 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"











Quando estávamos reescrevendo o código do Ansible, periodicamente nos deparávamos com a duplicação de código. Por exemplo, quase todas as configurações DSC continham uma configuração windows_exporter. A única coisa diferente eram os coletores que o exportador precisava usar:







para se livrar do código duplicado, movemos windows_exporter para uma função Ansible separada e os parâmetros dessa configuração - para variáveis ​​de grupo de hosts.



Autenticação de segundo salto



Provavelmente, a autenticação de segundo salto é o problema mais comum enfrentado por quem começou a usar o Ansible no Windows: esse design causa o erro Acesso negado devido ao fato de que, por padrão, é impossível delegar credenciais para autorização em um recurso remoto sem configurações adicionais. Para contornar o erro, por exemplo, new_credentials ajuda. Mas preferimos aproveitar o fato de que Ansible pode chamar recursos DSC por meio do módulo win_dsc. Chamamos o recurso File DSC, que por padrão é executado na conta do computador. A delegação Kerberos não é necessária neste 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








Ao mesmo tempo, não há contradição em abandonar o DSC, mas usar seus recursos se eles resolverem melhor o problema do que o módulo Ansible. O objetivo principal é deixar de usar configurações DSC, porque era o ecossistema DSC que não nos convinha, e não os recursos em si. Por exemplo, se você precisar criar um switch virtual Hyper-V, terá que usar o recurso DSC - o Ansible ainda não tem ferramentas para gerenciar a configuração do Hyper-V.



Desconexão de rede



Algumas tarefas causam a desconexão da rede (desconexão) em servidores configuráveis. Por exemplo, criando um switch virtual Hyper-V a partir do exemplo acima: O problema é que em DSC essa chamada funciona, mas em Ansible ela falha porque o host gerenciado foi desconectado. Isso ocorre porque o Windows sempre se desconecta ao criar um comutador externo virtual. A solução é adicionar um argumento assíncrono à tarefa : é assim que Ansible envia a tarefa para o host, espera um tempo especificado e só então pergunta o estado.



- name: External switch present

   win_dsc:

     resource_name: xVMSwitch

     Ensure: 'Present'

     Name: 'Virtual Network'

     Type: 'External'

     NetAdapterName: 'TEAM_LAN'

     AllowManagementOS: True












async: 10











Infraestrutura de deriva



Quando começamos a portar o código, encontramos um desvio na configuração. Essas são as diferenças reais entre o que está descrito no código e a configuração real do servidor ou software. A razão é que em alguns casos o DSC fazia apenas parte do trabalho, e o resto era feito por scripts ou manualmente de acordo com as instruções.



Para facilitar o trabalho com IaC, coletamos todos os scripts e documentos e criamos instruções uniformes e inequívocas. Além disso, organizamos o processo de forma que ninguém fizesse alterações acidentais no Ansible. Armazenamos todo o código da infraestrutura no GitHub e atribuímos tarefas aos engenheiros por meio dos projetos do GitHub, para que possamos associar as alterações ao código da infraestrutura (solicitações pull) às tarefas. Assim, podemos ver as mudanças para cada tarefa concluída. Se a tarefa não tiver nenhuma alteração, ela não será aceita e será devolvida para revisão.



Erros de coleta de fatos



Ao contrário do DSC, o Ansible reúne fatos sobre hosts gerenciados na inicialização para que o desenvolvedor possa determinar o comportamento das tarefas dependendo do estado do host. Ao coletar fatos de hosts Windows, o Ansible pode gerar um erro devido ao código de módulo incorreto. Para corrigir isso, você precisa conectar a coleção ansible.windows. O pipeline para Ansible, antes de lançar cada manual, verifica a presença de arquivos requirements.yml com uma lista de funções e coleções necessárias e, em seguida, os instala. É aqui que adicionamos a coleção ansible.windows. Coleções



[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













É um novo conceito de desenvolvimento para a Ansible. Se antes apenas as funções eram distribuídas no Galaxy, agora você pode encontrar coleções de vários plug-ins e módulos, manuais e funções.



Testes



Antes de entregar o kit de ferramentas IaC aos desenvolvedores, queríamos ter certeza de que o código Ansible seria confiável e não quebraria nada. No caso do DSC, não houve testes especiais, embora exista um quadro especial para esta tarefa. As configurações geralmente eram validadas em servidores de teste, cuja falha não levava a defeitos.



O Ansible é geralmente testado usando a ferramenta de molécula . como um invólucro para a execução de testes. É uma ferramenta útil para funções do Linux, mas há um problema com o Windows. Anteriormente, a molécula era capaz de elevar a própria infraestrutura, mas agora os desenvolvedores removeram essa oportunidade. Agora a infraestrutura está sendo erguida com a ajuda de uma molécula do Docker ou fora de uma molécula. Testar as funções do Windows no Docker geralmente é impossível: o Hyper-V e a maioria dos outros recursos do Windows não serão instalados em um contêiner do Docker. Teremos que implantar a infraestrutura para testes fora da molécula e usar o driver delegado na molécula.



Ainda não resolvemos esse problema, mas encontramos ferramentas que irão detectar os erros mais óbvios:



Verificar Funcional Comente
Verificação sintática Verifica a sintaxe e a capacidade de execução do código Usamos verificação de sintaxe e linting localmente e no repositório. Por exemplo, incorporamos a verificação de pré-confirmação e configuramos a ação GitHub, que será iniciada em cada solicitação pull
Fiapos Verifica o código em busca de erros lógicos
Funcionamento a seco Permite que você saiba o que ele fará antes de lançar o manual Usamos lançamentos de código no pipeline: inicie o ansible-playbook com os sinalizadores check e diff, avalie as alterações e confirme o lançamento. Quando escrevemos papéis, levamos em consideração que para algumas tarefas é necessário indicar explicitamente o que exatamente eles devem mudar. Por exemplo win_command e win_shell


Como funciona o Ansible



Após implementarmos o Ansible e superarmos todas as dificuldades, foi formado o processo de ações dos engenheiros e lançamentos 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 Se a infraestrutura for somente Windows e você não quiser trabalhar com Linux.



Se você está pronto para adicionar seus recursos para DSC.



É necessário armazenar o estado da infraestrutura, bem como consertar sua deriva.

Implementar Ansible do zero Se você estiver executando um ambiente Windows / Linux misto e quiser converter scripts existentes em código de infraestrutura e implantá-lo usando sistemas CI / CD.




Evgeny Berendyaev, engenheiro SRE



All Articles