Desmistificando Handlers do Ansible: Garantindo Reinicializações de Serviço Idempotentes
Aprenda como os handlers do Ansible reiniciam ou recarregam serviços apenas quando as tarefas mudam, com exemplos para playbooks, funções e descarga de handlers.
Desmistificando os Handlers do Ansible: Garantindo Reinicializações Idempotentes de Serviços
Os handlers do Ansible resolvem um problema comum de implantação: seu arquivo de configuração pode ser verificado em cada execução, mas seu serviço deve reiniciar apenas quando esse arquivo realmente mudar. Sem handlers, seu playbook pode reiniciar serviços saudáveis sem motivo.
Este guia explica como os handlers funcionam, onde defini-los e quando descarregá-los antecipadamente. Os exemplos usam serviços web, mas o mesmo padrão funciona para workers de aplicativos, agendadores e daemons do sistema.
O Que São os Handlers do Ansible?
No Ansible, um handler é uma tarefa que é executada apenas depois que outra tarefa o notifica. Quando uma tarefa altera algo e inclui notify, o Ansible coloca o handler correspondente na fila.
Características principais dos handlers:
- Acionados por notificação: Um handler é executado quando uma tarefa alterada usa
notify. - Executados uma vez por play: Se cinco tarefas notificarem o mesmo handler, o Ansible ainda o executa uma vez no final do play.
- Melhores para reinicializações e recarregamentos: Handlers são ideais para ações de serviço que devem ocorrer apenas após alterações de configuração.
Por Que Usar Handlers para Reinicializações de Serviços?
O caso de uso principal dos handlers do Ansible é o gerenciamento de serviços. Quando você atualiza um arquivo de configuração do Apache, Nginx ou aplicativo, o serviço geralmente precisa de uma reinicialização ou recarregamento. Você só quer essa ação quando o arquivo implantado difere do arquivo atual.
Considere a alternativa:
- Sem handlers: Uma tarefa de reinicialização direta é executada toda vez que o playbook a atinge, a menos que você adicione condições extras.
- Com handlers: A tarefa de template ou cópia notifica uma reinicialização apenas quando relata
changed.
Por exemplo, um playbook de produção do Nginx pode ser executado a cada hora para corrigir desvios de configuração. Com handlers, arquivos de configuração inalterados não causam recarregamentos a cada hora.
Como Implementar Handlers do Ansible
Os handlers residem em uma seção handlers em um playbook ou em handlers/main.yml dentro de uma role. O nome do handler deve corresponder ao nome usado por notify.
Sintaxe Básica do Handler
Os handlers são declarados em um bloco handlers no nível do playbook ou dentro de uma role.
---
- name: Configurar e reiniciar servidor web
hosts: webservers
become: yes
tasks:
- name: Garantir que a configuração do Apache esteja presente
template:
src: templates/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
notify:
- Reiniciar Apache
handlers:
- name: Reiniciar Apache
service:
name: httpd
state: restarted
Neste exemplo:
- Uma tarefa
templateé usada para implantar um novo arquivo de configuração do Apache (httpd.conf). - A palavra-chave
notifyé definida comoReiniciar Apache. Isso significa que se a tarefatemplatealterar com sucesso o arquivohttpd.conf, o Ansible sinalizará o handler chamadoReiniciar Apache. - A seção
handlersdefine o handlerReiniciar Apache, que usa o móduloservicepara reiniciar o serviçohttpd.
Notificando Múltiplos Handlers
Uma única tarefa pode notificar vários handlers. Isso é útil se alterar uma configuração exigir reiniciar vários serviços ou realizar várias ações de limpeza.
---
- name: Implantar aplicativo com atualizações de banco de dados e servidor web
hosts: app_servers
become: yes
tasks:
- name: Atualizar configuração do aplicativo
copy:
src: files/app.conf
dest: /etc/app/app.conf
notify:
- Reiniciar serviço do aplicativo
- Recarregar Nginx
handlers:
- name: Reiniciar serviço do aplicativo
service:
name: myapp
state: restarted
- name: Recarregar Nginx
service:
name: nginx
state: reloaded
Neste cenário, se app.conf for atualizado, ambos os handlers Reiniciar serviço do aplicativo e Recarregar Nginx serão acionados.
Usando Handlers em Roles
Os handlers são comumente usados dentro de roles do Ansible. Eles são definidos no arquivo handlers/main.yml de uma role. Quando uma tarefa dentro da role (ou de um playbook que inclui a role) notifica um handler definido na role, o Ansible o executará.
Vamos supor que você tenha uma role chamada apache com a seguinte estrutura:
apache/
├── handlers/
│ └── main.yml
└── tasks/
└── main.yml
apache/tasks/main.yml:
---
- name: Implantar configuração do Apache
template:
src: httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
notify:
- Reiniciar Apache
apache/handlers/main.yml:
---
- name: Reiniciar Apache
service:
name: httpd
state: restarted
Então, em seu playbook, você incluiria a role:
---
- name: Configurar servidor web usando role Apache
hosts: webservers
become: yes
roles:
- apache
Quando a tarefa Implantar configuração do Apache na role apache for executada e modificar a configuração, o handler Reiniciar Apache definido em apache/handlers/main.yml será acionado.
Melhores Práticas para Usar Handlers
- Mantenha cada handler focado em uma ação.
- Use nomes que correspondam à ação, como
Recarregar Nginx. - Prefira
state: reloadedquando o serviço suportar recarregamentos e uma reinicialização completa não for necessária. - Evite tarefas de reinicialização diretas após tarefas de configuração.
- Lembre-se de que handlers notificados são executados no final do play, a menos que você os descarregue.
Conceitos Avançados: Descarregando Handlers
Por padrão, os handlers são executados uma vez no final de um play. Às vezes, você precisa de uma reinicialização antes que as tarefas posteriores continuem. Por exemplo, você pode precisar reiniciar um aplicativo após escrever sua configuração principal antes de executar uma verificação de saúde ou migração.
---
- name: Realizar atualizações de configuração sequenciais exigindo reinicializações imediatas de serviço
hosts: servers
become: yes
tasks:
- name: Atualizar arquivo de configuração principal
copy:
src: files/primary.conf
dest: /etc/myapp/primary.conf
notify:
- Reiniciar Myapp
- name: Descarregar handlers para aplicar reinicialização imediata
meta: flush_handlers
- name: Atualizar arquivo de configuração secundário
copy:
src: files/secondary.conf
dest: /etc/myapp/secondary.conf
notify:
- Reiniciar Myapp
handlers:
- name: Reiniciar Myapp
service:
name: myapp
state: restarted
Aqui, a primeira alteração de configuração aciona Reiniciar Myapp, e meta: flush_handlers o executa imediatamente. Uma tarefa posterior pode notificar o mesmo handler novamente se alterar outro arquivo.
Quando Consultar um Profissional
Peça uma revisão quando um handler reiniciar bancos de dados de produção, balanceadores de carga ou serviços em cluster. Alguns sistemas precisam de reinicializações contínuas, verificações de quorum ou etapas de drenagem que não devem ser ocultadas por trás de um handler simples.
Conclusão
Use handlers do Ansible sempre que uma tarefa alterada deva acionar uma reinicialização de serviço, recarregamento ou recarregamento de daemon. Eles mantêm seus playbooks idempotentes, reduzem reinicializações desnecessárias e tornam as alterações de serviço mais fáceis de raciocinar.