Automatizando ativação de servidores Linux com um padrão reproduzível
Como transformar ativação de servidor Linux em uma rotina reproduzível com Ansible, parâmetros explícitos, blast radius controlado, PLAY RECAP e critérios claros de validação e escalação.
Ativar servidor manualmente funciona.
Até o dia em que existem dez pessoas fazendo a mesma coisa de dez jeitos diferentes.
Um instala o pacote que lembra. Outro copia um arquivo antigo. Um terceiro esquece o monitoramento. O quarto termina tudo certo, mas ninguém consegue dizer exatamente qual receita foi aplicada.
Foi por isso que eu passei a tratar provisionamento como produto operacional, não como uma sequência de comandos.
A ideia é simples: receber um host novo, escolher uma receita, preencher parâmetros conhecidos e terminar com um estado que possa ser validado e repetido.
O que eu queria eliminar #
Um servidor novo normalmente precisa de várias peças antes de estar pronto para receber aplicação:
- configuração base do Linux;
- Docker quando a stack usa containers;
- Nginx;
- TLS/SSL;
- monitoramento;
- aplicação ou runtime correspondente;
- ajustes de acesso;
- validação final.
Fazer isso por checklist manual não é errado. O problema é que checklist não garante execução idêntica.
A automação precisa resolver outra pergunta:
como eu sei que dois servidores ativados em momentos diferentes passaram pelas mesmas regras?
O template precisa começar pelo alvo #
No Semaphore, uma das regras mais importantes do runbook é preencher explicitamente o campo de limite/alvo antes de rodar uma tarefa que altera ambiente.
Isso existe por um motivo bem pouco glamouroso: em automação, um parâmetro em branco pode mudar o blast radius inteiro.
A operação de ativação foi classificada internamente como risco médio e blast radius de um host novo.
Esse detalhe é mais importante que o playbook bonito.
Antes de perguntar “o que a task instala?”, eu quero saber:
| |
Uma entrada pequena, uma receita conhecida #
Em vez de expor dezenas de variáveis para quem executa a ativação, o template trabalha com um conjunto menor de parâmetros operacionais.
Conceitualmente:
| |
O tipo_ativacao seleciona a receita adequada para aquele servidor.
Isso permite manter diferenças reais entre stacks sem transformar cada ativação em um playbook completamente novo.
A mesma ideia vale para qualquer operação com perfis distintos:
| |
O que for igual fica na base. O que realmente muda fica na receita.
Compatibilidade também precisa ser explícita #
Outro padrão que apareceu nos playbooks foi normalizar arquitetura e distribuição antes de chamar roles mais antigas.
Um exemplo simplificado:
| |
Parece burocracia, mas evita que cada role tente interpretar arquitetura por conta própria.
Em ambientes mistos, essa camada de normalização vale muito.
Separar roles deixa a intenção legível #
Para um servidor de banco dedicado, por exemplo, a composição pode ficar próxima de:
| |
Isso ajuda em duas frentes.
Primeiro, fica claro o que pertence à base do servidor e o que pertence à função específica dele.
Segundo, a mesma role de monitoring pode ser aplicada em vários tipos de host sem copiar task de Zabbix para cada playbook.
A automação começa a escalar quando reuso deixa de significar copiar YAML.
Monitoramento entra no provisionamento, não depois #
Uma das escolhas que considero mais importantes é instalar monitoramento como parte da ativação.
Servidor não deveria chegar ao status de “pronto” e só depois alguém lembrar que ainda precisa cadastrá-lo na observabilidade.
Se o monitoramento é requisito operacional, ele faz parte da definição de pronto.
A mesma lógica vale para:
- Nginx válido;
- serviço habilitado;
- firewall coerente;
- certificado quando aplicável;
- acesso administrativo;
- aplicação respondendo.
PLAY RECAP virou contrato de execução #
No runbook, a execução termina com uma checagem simples e objetiva: olhar o PLAY RECAP.
O padrão operacional é:
| |
Isso não significa que failed=0 prova sozinho que a aplicação está funcional.
Ele prova uma coisa mais limitada: o Ansible completou as tasks sem registrar falha.
Depois ainda entram testes funcionais compatíveis com a receita.
Essa separação é saudável porque evita transformar um sinal de automação em uma promessa maior do que ele realmente significa.
Reboot automático muda a classificação de risco #
A rotina documentada termina com reboot do servidor.
Nesse caso específico, o alvo é um host novo. Mesmo assim, isso torna a ação parcialmente reversível e merece aparecer no runbook.
Se a mesma task pudesse atingir um host atendendo produção, a classificação de risco seria completamente diferente.
É por isso que eu gosto de documentar junto do template:
| |
Automação segura não é só código correto. É contexto operacional embutido no processo.
Nem toda automação pronta tecnicamente está liberada para rotina #
Um detalhe importante da fonte desse caso: a tarefa estava em revalidação parcial.
O playbook existia, havia passado por correções, mas o runbook ainda exigia executar e registrar cada tipo de receita antes de considerar o fluxo liberado para uso rotineiro.
Isso é uma distinção que vale preservar:
- código existe;
- código passa syntax check;
- execução terminou;
- cenário foi testado;
- rotina está homologada.
São estados diferentes.
Chamar tudo de “pronto” só porque o YAML está no repositório é pedir para descobrir a diferença em produção.
O que eu considero definição de pronto #
Para esse tipo de provisionamento, eu espero no mínimo:
- alvo explicitamente limitado;
- parâmetros validados;
- arquitetura/distribuição reconhecidas;
- roles executadas sem falha;
- monitoramento incluído;
- reboot, se previsto, concluído;
- host voltando acessível;
- serviços esperados ativos;
- endpoint funcional quando houver;
- log preservado para auditoria.
Se uma receita ainda não passou por execução real controlada, isso precisa estar escrito.
O ganho de verdade #
O principal benefício não é economizar os minutos de instalar Nginx ou Docker.
É conseguir responder:
“Como esse servidor foi ativado?”
E a resposta não depender da memória de quem estava de plantão.
Quando provisionamento vira receita versionada, com parâmetros explícitos, limite de alvo, validação e runbook, a operação fica menos artesanal.
Não elimina incidente.
Mas elimina uma categoria inteira de diferenças acidentais entre servidores — aquelas que só aparecem meses depois, quando dois hosts que deveriam ser iguais se comportam de formas completamente diferentes.
Me chama.
Manda o contexto, os sintomas e o que já foi testado. Bora organizar as evidências antes de sair mexendo.