Usando o Módulo de Serviço para Tarefas Comuns de Administração do Sistema
Use comandos ad-hoc do Ansible para iniciar, parar, reiniciar, recarregar, habilitar e desabilitar serviços Linux com segurança.
Usando o Módulo de Serviço para Tarefas Comuns de Administração do Sistema
O Ansible é útil mesmo quando você não precisa de um playbook completo. Se um serviço está inativo em alguns hosts, ou você precisa desabilitar algo barulhento antes de uma janela de manutenção, um comando ad-hoc pode ser a ferramenta certa. Ele fornece o mesmo direcionamento de inventário e modelo de escalonamento de privilégios sem exigir que você crie um arquivo YAML para uma operação única.
O módulo service embutido é uma das ferramentas mais frequentemente usadas no kit de ferramentas de um administrador de sistemas. Ele fornece uma interface padronizada e idempotente para gerenciar serviços em diversas distribuições Linux, abstraindo as diferenças entre sistemas init como Systemd, SysVinit e Upstart. Este guia detalha como aproveitar o módulo service exclusivamente através de comandos ad-hoc para realizar operações essenciais e comuns de administração do sistema.
Entendendo Comandos Ad-Hoc e o Módulo service
Comandos ad-hoc são execuções de linha única que usam o comando /usr/bin/ansible, especificando um grupo alvo (-i), um módulo (-m) e argumentos (-a). Eles não são persistentes e não dependem de arquivos YAML de playbook.
O módulo service requer principalmente dois parâmetros:
name: O nome do serviço a ser gerenciado (ex.:httpd,nginx,sshd).state: O estado operacional desejado (started,stopped,restarted,reloaded).enabled(Opcional): Se o serviço deve iniciar na inicialização do sistema (yesouno).
Sintaxe Básica do Comando Ad-Hoc
Todos os exemplos abaixo utilizam o comando ansible. Como gerenciar serviços geralmente requer privilégios de root, a flag -b (become/sudo) é quase sempre necessária.
ansible <host_pattern> -m service -a "name=<service_name> state=<action> enabled=<yes/no>" -b
Nota: Substitua
<host_pattern>pelo seu host ou grupo alvo (ex.:webservers,all).
1. Garantindo que um Serviço Esteja em Execução (Iniciando um Serviço)
Uma das tarefas mais comuns é garantir que um serviço crítico esteja atualmente ativo. O parâmetro state=started garante que, se o serviço estiver parado, o Ansible o inicia. Se já estiver em execução, o Ansible não faz nada (idempotência).
Exemplo: Garantindo que o servidor web Nginx esteja em execução em todos os servidores web
ansible webservers -m service -a "name=nginx state=started" -b
Se o Ansible retornar uma mensagem changed: true, o serviço estava parado e foi iniciado. Se retornar changed: false, o serviço já estava em execução.
2. Parando um Serviço
Para interromper imediatamente um serviço ativo, use state=stopped. Isso é útil para manutenção, limpeza de dependências ou patches de segurança imediatos.
Exemplo: Parando o banco de dados PostgreSQL em todos os servidores de banco de dados
ansible db_servers -m service -a "name=postgresql state=stopped" -b
Dica: Ao parar um serviço crítico, certifique-se de executar um comando de verificação posteriormente usando um módulo diferente, como o módulo
command, para confirmar o status, se necessário (ex.:ansible db_servers -a 'systemctl status postgresql').
3. Reiniciando e Recarregando Serviços
Quando arquivos de configuração são modificados, os serviços geralmente precisam ser recarregados graciosamente ou reiniciados à força. O módulo service lida com ambas as ações.
Reiniciando (state=restarted)
Reiniciar envolve uma parada completa e subsequente início do serviço. Isso é necessário para alterações que afetam o comportamento subjacente do daemon.
Exemplo: Reiniciando o daemon SSH em todos os hosts
ansible all -m service -a "name=sshd state=restarted" -b
Recarregando (state=reloaded)
Recarregar, quando suportado pelo serviço (como Nginx ou Apache), aplica alterações de configuração sem interromper as conexões em andamento. Este é o método preferido em ambientes de alta disponibilidade.
Exemplo: Recarregando graciosamente a configuração do Nginx
ansible webservers -m service -a "name=nginx state=reloaded" -b
Importante: Se um serviço não suportar
reload, o resultado depende do gerenciador de serviços e da definição da unidade. Algumas unidades falham na solicitação de recarga, algumas mapeiam a recarga para outra ação e algumas não fazem nada útil. Verifique a documentação do próprio serviço antes de confiar na recarga para alterações em produção.
4. Gerenciando a Persistência do Serviço (Habilitando e Desabilitando)
O parâmetro state controla o status de tempo de execução atual. O parâmetro separado enabled controla se o serviço será iniciado automaticamente quando o sistema operacional inicializar.
Garantindo que um Serviço Inicie na Inicialização (enabled=yes)
Isso é crucial para serviços de missão crítica que devem sobreviver a uma reinicialização do host.
Exemplo: Garantindo que o serviço Docker esteja habilitado e em execução
ansible dockernodes -m service -a "name=docker state=started enabled=yes" -b
Impedindo que um Serviço Inicie na Inicialização (enabled=no)
Isso é frequentemente usado para proteger sistemas ou desabilitar serviços padrão desnecessários (ex.: desabilitar o firewall embutido se você usa um firewall baseado em nuvem).
Exemplo: Desabilitando o serviço padrão Firewalld
ansible all -m service -a "name=firewalld state=stopped enabled=no" -b
Melhor Prática de Segurança: Sempre garanta que serviços não utilizados estejam tanto
stoppedquantoenabled=nopara evitar inicialização inesperada durante atualizações ou reinicializações do sistema.
5. Lidando com Tipos de Serviço Avançados e Erros
Embora o módulo service genérico seja projetado para funcionar em todos os principais sistemas init, existem cenários onde o tratamento explícito é útil ou necessário.
Quando o Módulo Genérico Falha
Em casos raros, especialmente em sistemas mais antigos ou ambientes altamente personalizados, o módulo service genérico pode falhar ao detectar o sistema init correto. O Ansible fornece módulos específicos do sistema para tais casos:
systemd: Para todas as distribuições modernas (CentOS 7+, Ubuntu 15+, Debian 8+).sysvinit: Para sistemas mais antigos ou distribuições especializadas.
Se você sabe que seu alvo está usando Systemd, você pode usar explicitamente o módulo systemd, embora sua sintaxe seja idêntica à do módulo service genérico para operações básicas:
# Usando explicitamente o módulo systemd (funcionalidade idêntica a 'service')
ansible servers -m systemd -a "name=chronyd state=started enabled=yes" -b
Gerenciando Serviços com Scripts Personalizados
Se você precisar executar um comando de serviço não suportado nativamente pelo sistema init (ex.: variáveis de ambiente personalizadas durante a inicialização), você pode precisar combinar o módulo service com outras tarefas em um playbook completo, ou usar o módulo shell para intervenção ad-hoc, embora isso reduza a idempotência.
# Exemplo de comando ad-hoc usando 'shell' para tarefas de serviço complexas (use com cuidado)
ansible webservers -a "/usr/bin/my_custom_service_script restart" -b
Folha de Dicas de Comandos Ad-Hoc do Módulo de Serviço
| Tarefa | Argumentos | Exemplo de Comando |
|---|---|---|
| Garantir Execução | state=started |
ansible all -m service -a "name=apache2 state=started" -b |
| Parar Serviço | state=stopped |
ansible all -m service -a "name=fail2ban state=stopped" -b |
| Forçar Reinicialização | state=restarted |
ansible servers -m service -a "name=postfix state=restarted" -b |
| Recarga Graciosa | state=reloaded |
ansible webservers -m service -a "name=httpd state=reloaded" -b |
| Definir para Início Automático | enabled=yes |
ansible all -m service -a "name=firewalld enabled=yes" -b |
| Desabilitar Início Automático | enabled=no |
ansible all -m service -a "name=cups enabled=no" -b |
| Garantir Execução e Habilitado | state=started enabled=yes |
ansible control -m service -a "name=ansible_api state=started enabled=yes" -b |
Um Fluxo de Trabalho Seguro para Incidentes Reais
Quando você usa o módulo de serviço do Ansible durante um incidente, o comando em si geralmente é a parte fácil. A parte mais difícil é garantir que você está mirando os hosts certos e entendendo o que o gerenciador de serviços fará.
Comece com a inspeção do inventário. Se você está prestes a reiniciar o Nginx em webservers, verifique o que esse grupo contém:
ansible-inventory -i inventory.ini --graph webservers
Se seu inventário é dinâmico, execute a mesma verificação contra a fonte dinâmica. É comum que tags de nuvem incluam hosts que você não esperava, especialmente após migrações ou eventos de escalonamento temporário. Uma reinicialização de serviço que é segura em cinco nós de aplicação pode ser arriscada em todos os nós de uma região.
Em seguida, execute um comando somente leitura contra o mesmo alvo:
ansible webservers -m command -a "systemctl is-active nginx" -b
Isso confirma o usuário da conexão, escalonamento de privilégios, padrão de host e nome do serviço antes de você fazer uma alteração. No Debian e Ubuntu, o serviço web geralmente é nginx ou apache2; em muitas famílias Red Hat, o Apache geralmente é httpd. O módulo Ansible não pode adivinhar a convenção de nomenclatura do pacote para você.
Para serviços de alto risco, use --limit primeiro:
ansible webservers --limit web01.example.com -m service -a "name=nginx state=reloaded" -b
Se funcionar, expanda para um pequeno grupo, depois para o grupo completo. Comandos ad-hoc não têm a estrutura de implantação embutida de um playbook com serial, então você precisa ser deliberado. Para uma grande frota, um playbook curto pode ser mais seguro do que um comando ad-hoc gigante porque você pode definir serial, adicionar verificações de saúde e parar em caso de falha.
Tenha cuidado com state=restarted. Ele sempre solicita uma reinicialização, então relata changed e interrompe o serviço mesmo que nada mais tenha mudado. Isso é bom quando você realmente quer uma reinicialização. É um desperdício quando você está usando isso como uma maneira preguiçosa de "garantir que as coisas estejam bem". Para verificações de rotina, prefira state=started; ele inicia um serviço parado, mas deixa um serviço em execução em paz.
enabled=yes e enabled=no merecem o mesmo cuidado. Eles alteram o comportamento de inicialização, não apenas o comportamento atual em tempo de execução. Se você executar isso durante a solução de problemas:
ansible all -m service -a "name=firewalld state=stopped enabled=no" -b
você não apenas parou o firewall agora; você também disse ao sistema para não iniciá-lo após a reinicialização. Isso pode estar correto em um ambiente de nuvem onde firewalls de host são intencionalmente desabilitados, ou pode violar sua linha de base de segurança. Em uma equipe de operações compartilhada, deixe uma nota no ticket ou faça um commit de uma alteração no playbook para que a decisão persistente seja visível.
Para serviços gerenciados pelo systemd, o módulo ansible.builtin.systemd_service fornece opções específicas do systemd, como daemon_reload, masked e serviços com escopo de usuário. O módulo service genérico ainda é útil para o básico portátil, mas quando você precisar de comportamento específico do systemd, use o módulo systemd diretamente:
ansible appservers -m ansible.builtin.systemd_service -a "name=myapp state=restarted daemon_reload=true" -b
Finalmente, sempre leia o resultado. changed=true significa que o Ansible pediu ao módulo para alterar algo, não que o aplicativo esteja saudável depois. Um serviço pode reiniciar limpo e ainda falhar em sua própria verificação de saúde dois segundos depois. Siga as alterações de serviço com uma verificação que corresponda ao aplicativo:
ansible webservers -m uri -a "url=http://127.0.0.1/health status_code=200"
ou, se HTTP não estiver disponível:
ansible webservers -m command -a "systemctl is-active nginx" -b
Os melhores comandos de serviço ad-hoc são chatos: alvo estreito, estado claro, escalonamento de privilégios incluído e um comando de verificação logo em seguida. Esse hábito previne a maioria dos erros que vêm do gerenciamento de serviços em velocidade.
Quando um Comando Ad-Hoc Deve se Tornar um Playbook
Comandos ad-hoc são excelentes para trabalho rápido e de baixo contexto. Eles não são um substituto para operações repetíveis. Se você se pegar colando o mesmo comando de serviço no chat, adicionando uma etapa de verificação manual e dizendo a alguém "execute isso nos dois primeiros hosts, espere, depois execute no resto", isso já é um playbook tentando existir.
Um playbook fornece intenção revisável:
- name: Recarregar nginx com segurança
hosts: webservers
become: true
serial: 5
tasks:
- name: Validar configuração do nginx
ansible.builtin.command: nginx -t
changed_when: false
- name: Recarregar nginx
ansible.builtin.service:
name: nginx
state: reloaded
- name: Verificar endpoint de saúde local
ansible.builtin.uri:
url: http://127.0.0.1/health
status_code: 200
A mesma operação ainda é simples, mas agora tem agrupamento, validação e uma verificação de saúde. Pode viver no Git. Alguém pode revisá-lo antes da próxima janela de manutenção. Você também pode adicionar any_errors_fatal: true ou ajustar o comportamento de falha em vez de assistir a um terminal e tomar decisões sob pressão.
Continue usando comandos ad-hoc service para inícios, paradas e verificações rápidas. Recorra a um playbook quando a operação alterar a disponibilidade voltada para o cliente, precisar de uma ordem de implantação ou precisar ser repetida por outra pessoa. Essa linha não é sobre cerimônia; é sobre tornar as partes arriscadas visíveis.