A aproximação do Ano Novo estava próxima. As crianças de todo o país já enviaram cartas ao Papai Noel ou fizeram seus pedidos de presentes, enquanto o principal executor — um dos grandes varejistas — se preparava para o apogeu das vendas. Em dezembro, a carga em seu data center aumenta várias vezes. Portanto, a empresa decidiu modernizar o data center e colocar em operação várias dezenas de novos servidores para substituir equipamentos cujo tempo de vida estava se esgotando. Assim, a introdução termina em um pano de fundo de flocos de neve e começa o thriller.

O equipamento chegou ao local meses antes do pico de vendas. O serviço de operações, é claro, sabe como e o que ajustar nos servidores para colocá-los em um ambiente de produção. Mas precisávamos automatizar isso e eliminar o fator humano. Além disso, os servidores substituíam um conjunto de sistemas SAP, críticos para a empresa, antes da migração.
A colocação em funcionamento dos novos servidores estava rigidamente ligada ao prazo final. E adiar isso significava colocar em risco a entrega de um bilhão de presentes e a migração dos sistemas. Mudanças na data não poderiam ser feitas nem mesmo pela equipe do Papai Noel ou do Santa Claus — transferir o sistema SAP para a gestão do armazém só pode ser feito uma vez por ano. De 31 de dezembro a 1 de janeiro, enormes armazéns do varejista, somando o tamanho de 20 campos de futebol, param suas operações por 15 horas. E essa é a única janela de tempo para migrar o sistema. Não podíamos cometer erros ao ativar os servidores.
Deixe-me esclarecer imediatamente: minha história reflete as ferramentas e o processo de gerenciamento de configurações que nossa equipe utiliza.
O sistema de gerenciamento de configurações consiste em vários níveis. O componente chave é o sistema CMS. Na operação industrial, a falta de um dos níveis resultaria inevitavelmente em surpresas desagradáveis.
Gerenciamento da instalação do SO
O primeiro nível é o sistema de gerenciamento da instalação de sistemas operacionais em servidores físicos e virtuais. Ele cria configurações básicas do SO, eliminando o fator humano.
Com este sistema, obtivemos instâncias de servidores com SO que eram típicas e adequadas para futura automação. Durante a "distribuição", eles recebiam o conjunto mínimo de usuários locais e chaves públicas SSH, além de uma configuração de SO consistente. Podíamos gerenciar os servidores através da CMS com garantia, sabendo que "por baixo", no nível do SO, não havia surpresas.
A tarefa "máxima" para o sistema de gerenciamento de instalação é configurar automaticamente os servidores desde o nível de BIOS/Firmware até o SO. Muito disso depende do hardware e das tarefas de configuração. Para hardware heterogêneo, pode-se considerar . Se todo o "hardware" for de um único fornecedor, muitas vezes é mais conveniente usar ferramentas de gerenciamento prontas (por exemplo, HP ILO Amplifier, DELL OpenManage, etc.).
Para a instalação do SO em servidores físicos, usamos o Cobbler, conhecido por todos, que possui um conjunto definido de perfis de instalação acordados com o serviço de operações. Ao adicionar um novo servidor à infraestrutura, o engenheiro vinculava o endereço MAC do servidor ao perfil necessário no Cobbler. Na primeira inicialização pela rede, o servidor recebia um endereço temporário e um SO atualizado. Depois, ele era movido para a VLAN/endereço IP alvo e continuava a funcionar lá. Sim, mudar a VLAN leva tempo e requer coordenação, mas isso proporciona proteção adicional contra a instalação acidental do servidor em um ambiente de produção.
Criávamos servidores virtuais com base em templates preparados com o HashiCorp Packer. A razão era a mesma: evitar possíveis erros humanos na instalação do SO. Mas, ao contrário dos servidores físicos, o Packer permite não usar PXE, inicialização pela rede e mudança de VLAN. Isso facilitou e simplificou a criação de servidores virtuais.

Fig. 1. Gerenciamento da instalação de sistemas operacionais.
Gerenciamento de segredos
Qualquer sistema de gerenciamento de configurações contém dados que devem ser ocultos de usuários comuns, mas são necessários para a preparação de sistemas. Isso inclui senhas de usuários locais e contas de serviço, chaves de certificados, vários tokens de API, etc. Normalmente, são chamados de "segredos".
Se desde o início não determinar onde e como armazenar esses segredos, dependendo da rigorosidade dos requisitos de segurança da informação, é provável que ocorram as seguintes formas de armazenamento:
- diretamente no código de gerenciamento de configurações ou em arquivos no repositório;
- em ferramentas especializadas de gerenciamento de configurações (por exemplo, Ansible Vault);
- em sistemas de CI/CD (Jenkins/TeamCity/GitLab/etc.) ou em sistemas de gerenciamento de configurações (Ansible Tower/Ansible AWX);
- também os segredos podem ser gerenciados manualmente. Por exemplo, são disponibilizados em um local acordado e, em seguida, utilizados pelos sistemas de gerenciamento de configurações;
- diferentes combinações do que foi descrito acima.
Cada método tem suas desvantagens. A principal delas é a ausência de políticas de acesso aos segredos: não é possível ou é difícil determinar quem pode usar determinados segredos. Outro ponto negativo é a falta de auditoria de acesso e um ciclo de vida completo. Como substituir rapidamente, por exemplo, uma chave pública que está codificada e em vários sistemas relacionados?
Utilizamos um repositório centralizado de segredos, o HashiCorp Vault. Isso nos permitiu:
- armazenar segredos de forma segura. Eles são criptografados, e mesmo que alguém tenha acesso ao banco de dados do repositório Vault (por exemplo, restaurando-o de um backup), não conseguirá ler os segredos armazenados lá;
- organizar políticas de acesso aos segredos. Apenas os segredos 'designados' são acessíveis a usuários e aplicativos;
- realizar auditoria de acesso aos segredos. Qualquer ação realizada com os segredos é registrada no log de auditoria do Vault;
- organizar um 'ciclo de vida' completo para o trabalho com segredos. Eles podem ser criados, revogados, ter um prazo de validade definido, etc.
- integrar facilmente com outros sistemas que precisam de acesso aos segredos;
- e também aplicar criptografia de ponta a ponta, senhas descartáveis para sistemas operacionais e bancos de dados, certificados de autoridades certificadoras etc.
Agora vamos abordar o sistema central de autenticação e autorização. Poderíamos ter funcionado sem ele, mas gerenciar usuários em múltiplos sistemas relacionados é bastante complicado. Configuramos a autenticação e autorização através do serviço LDAP. Caso contrário, no mesmo Vault, teríamos que emitir continuamente e monitorar os tokens de autenticação dos usuários. E adicionar ou remover usuários se tornaria uma busca por "em todos os lugares que eu criei/removi este usuário?"
Adicionamos mais um nível ao nosso sistema: gerenciamento de segredos e autenticação/autorização central;

Fig. 2. Gerenciamento de segredos.
Gerenciamento de configurações
Chegamos ao cerne — ao sistema CMS. No nosso caso, trata-se da combinação Ansible e Red Hat Ansible AWX.
Em vez do Ansible, pode-se utilizar Chef, Puppet, SaltStack. Optamos pelo Ansible por vários critérios.
- Em primeiro lugar, sua versatilidade. O conjunto de módulos prontos para gerenciamento . E se faltar algum, você pode procurar no GitHub e no Galaxy.
- Em segundo lugar, não é necessário instalar e manter agentes no hardware gerenciado, provar que eles não interferem na carga e confirmar a ausência de "backdoors".
- Em terceiro lugar, o Ansible possui uma baixa barreira de entrada. Um engenheiro competente escreverá um playbook funcional logo no primeiro dia de trabalho com o produto.
Mas apenas o Ansible em um ambiente de produção não era suficiente para nós. Caso contrário, surgiriam muitos problemas com restrição de acesso e auditoria das ações dos administradores. Como restringir o acesso? Precisávamos que cada departamento gerenciasse (ou seja, executasse o playbook do Ansible) seu próprio conjunto de servidores. Como permitir a execução de playbooks do Ansible específicos apenas para determinados funcionários? Ou como rastrear quem executou um playbook, sem criar múltiplas contas locais nos servidores e equipamentos gerenciados pelo Ansible?
A maior parte dessas questões é resolvida pelo Red Hat , ou seu projeto upstream open-source . Portanto, preferimos usá-lo para o cliente.
E mais um detalhe sobre o perfil do nosso sistema CMS. O playbook do Ansible deve ser armazenado em sistemas de gerenciamento de repositórios de código. No nosso caso, é o .
Portanto, o gerenciamento das configurações é realizado pela combinação Ansible/Ansible AWX/GitLab (veja a Fig. 3). Naturalmente, o AWX/GitLab está integrado a um sistema único de autenticação, e o playbook do Ansible é integrado ao HashiCorp Vault. As configurações entram no ambiente de produção somente através do Ansible AWX, onde todas as "regras do jogo" estão definidas: quem e o que pode configurar, de onde obter o código de gerenciamento de configurações para o CMS, etc.

Fig. 3. Gerenciamento de configurações.
Gerenciamento de testes
Nossa configuração é apresentada na forma de código. Portanto, somos obrigados a jogar segundo as mesmas regras que os desenvolvedores de software. Precisávamos organizar os processos de desenvolvimento, teste contínuo, entrega e aplicação do código de configuração nos servidores de produção.
Se isso não for feito imediatamente, os papéis escritos para a configuração deixariam de ser suportados e atualizados, ou parariam de ser executados em produção. A solução para essa dor é conhecida e se mostrou eficaz neste projeto:
- cada papel é coberto por testes modulares;
- os testes são executados automaticamente sempre que há uma alteração no código que controla as configurações;
- as alterações no código de gerenciamento de configurações vão para o ambiente de produção somente após a aprovação em todos os testes e na revisão de código.
O desenvolvimento de código e o gerenciamento de configurações tornaram-se mais tranquilos e previsíveis. Para organização de testes contínuos, utilizamos a ferramenta GitLab CI/CD, e para o framework de teste escolhemos .
Sempre que há uma alteração no código de gerenciamento de configurações, o GitLab CI/CD chama o Molecule:
- ele verifica a sintaxe do código,
- levanta um contêiner Docker,
- aplica o código alterado no contêiner criado,
- verifica a idempotência do papel e executa testes para esse código (a granularidade aqui está ao nível do papel ansible, veja a Fig. 4).
As configurações foram entregues ao ambiente de produção usando Ansible AWX. Os engenheiros responsáveis pela operação aplicavam as alterações na configuração através de modelos previamente definidos. O AWX solicitava a versão mais recente do código a partir do branch master do GitLab a cada aplicação. Assim, evitamos o uso de código não verificado ou desatualizado no ambiente de produção. Naturalmente, o código chegava ao branch master apenas após ser testado, revisado e aprovado.

Fig. 4. Testes automáticos de papéis no GitLab CI/CD.
Há um outro problema relacionado à operação de sistemas em produção. Na vida real, é muito difícil fazer alterações na configuração apenas através do código CMS. Situações inesperadas surgem, onde o engenheiro precisa alterar a configuração "aqui e agora", sem esperar pela correção do código, testes, aprovações etc.
Como resultado, devido a alterações manuais, surgem discrepâncias na configuração em equipamentos semelhantes (por exemplo, em nós de um cluster HA, configurações sysctl diferentes). Ou a configuração real no equipamento difere daquela especificada no código CMS.
Portanto, além dos testes contínuos, verificamos os ambientes de produção quanto a discrepâncias de configuração. Escolhemos a opção mais simples: executar o código de configuração da CMS em modo 'dry run', ou seja, sem aplicar alterações, mas com notificação sobre todas as discrepâncias entre a configuração planejada e a real. Implementamos isso com execuções periódicas de todos os playbooks do Ansible com a opção '--check' nos servidores de produção. A execução e a atualidade do playbook são sempre garantidas pelo Ansible AWX (veja a Fig. 5):

Fig. 5. Verificações de discrepância de configurações no Ansible AWX.
Após as verificações, o AWX envia um relatório de discrepâncias aos administradores. Eles analisam a configuração problemática e, em seguida, a corrigem por meio de playbooks ajustados. Assim, mantemos a configuração no ambiente de produção e a CMS está sempre atualizada e sincronizada. Isso evita os desagradáveis 'milagres' quando o código da CMS é aplicado em servidores de 'produção'.
Agora temos um nível importante de testes, que consiste em Ansible AWX/GitLab/Molecule (Fig. 6).

Fig. 6. Gestão de testes.
Difícil? Não discordo. Mas tal complexo de gerenciamento de configurações se tornou a resposta abrangente para muitas questões relacionadas à automação da configuração de servidores. Agora, um varejista sempre tem uma configuração estritamente definida para seus servidores padrão. A CMS, ao contrário do engenheiro, não se esquece de adicionar as configurações necessárias, criar usuários e realizar dezenas ou centenas de ajustes exigidos.
Nas configurações de servidores e ambientes, hoje não existem 'conhecimentos secretos'. Todas as características necessárias estão refletidas nos playbooks. Nada de criatividade e instruções obscuras: 'instale como um Oracle comum, mas lá é necessário definir algumas configurações do sysctl e adicionar usuários com o UID apropriado. Pergunte aos caras da operação, eles sabem.».
A capacidade de detectar discrepâncias de configuração e corrigí-las antecipadamente traz tranquilidade. Sem um sistema de gerenciamento de configurações, isso geralmente acontece de maneira diferente. Os problemas se acumulam até que um dia 'explodam' em produção. Depois, realiza-se uma análise de falhas, verificam-se e corrigem-se as configurações. E o ciclo se repete novamente.
E claro, aceleramos a implementação dos servidores de alguns dias para algumas horas.
Na própria noite de Ano Novo, quando as crianças desembrulhavam presentes com alegria e os adultos faziam desejos ao som das badaladas, nossos engenheiros migraram o sistema SAP para novos servidores. Até o Papai Noel diria que os melhores milagres são bem planejados.
P.S. Nossa equipe frequentemente enfrenta a situação em que os clientes desejam resolver as tarefas de gerenciamento de configurações da maneira mais simples possível. Idealmente, como se fosse mágica — com uma única ferramenta. Mas na prática, tudo é mais complicado (sim, novamente não trouxeram as balas de prata): é preciso criar todo um processo usando ferramentas que sejam convenientes para a equipe do cliente.
Autor: Sergey Artemov, arquiteto de departamento ‘Infosistemas Jet’
Fonte: habr.com
