ANSIBLE SERIES: h.t.wrt* … tasks, plays e books: handlers
CONT. 🔝
🔙 ANTERIOR: BLOCKS
Visto no final do post passado, numa breve participação coadjuvante, e já tendo aparecido em outras oportunidades aqui no BLOG, chegou a hora de conhecer um pouco mais sobre os handlers (traduzindo para o português: manipuladores). Objetiva e diretamente, são um tipo de tarefa que apenas se auto executa quando recebe uma notificação. Por exemplo, reiniciar determinado serviço (daemon) se, e somente se, alguma task modificou sua configuração. Em oposição, não fazer absolutamente nada enquanto tal permanecer inalterada. Outro fato importante, e assim como as variáveis, cada handler precisa ser nomeado exclusivamente.
- Exemplo;
- Controlando a execução de um handler (WHEN);
- Usando variáveis com handlers;
06-a. Handler Example
A seguir, o playbook verify-apache.yml
, apresentando uma play com handler simples:
--- - name: Verify apache installation hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: - name: Ensure apache is at the latest version ansible.builtin.yum: name: httpd state: latest - name: Write the apache config file ansible.builtin.template: src: /srv/httpd.j2 dest: /etc/httpd.confnotify:
- Restart apache
- name: Ensure apache is running ansible.builtin.service: name: httpd state: startedhandlers:
- name: Restart apache ansible.builtin.service: name: httpd state: restarted
Continuando, mais um playbook. Entretanto, agora é a vez de uma task (anteriormente foi uma play) ser responsável por notificar. Serve para demonstrar que uma única task é capaz de notificar mais de um handler simultaneamente:
- name: Template configuration file ansible.builtin.template: src: template.j2 dest: /etc/foo.confnotify:
- Restart memcached
- Restart apache
handlers:
- name:Restart memcached
ansible.builtin.service: name: memcached state: restarted - name:Restart apache
ansible.builtin.service: name: apache state: restarted
06-b. Controlando a execução de um handler (WHEN)
Devido a sua concepção, manipuladores são executados depois que todas as tarefas em uma determinada play foram concluídas. Tal método é eficiente pois o manipulador é executado apenas uma vez, independentemente de quantas tarefas o notificam. Por exemplo, se várias tarefas atualizam um arquivo de configuração e notificam um manipulador para reiniciar o Apache, o Ansible pula o Apache apenas uma vez para evitar reinicializações desnecessárias.
Caso necessite que os handlers sejam executados bem antes do final da execução, basta adicionar uma task que os liberte para tal. Faça uso do ‘meta module’ presente no ansible-base, chamando-o para que o Ansible execute ações:
tasks: - name: Some tasks go here ansible.builtin.shell: ... - name:Flush handlers
meta:
flush_handlers
- name: Some other tasks ansible.builtin.shell: ...
A tarefa meta: flush_handlers
aciona todos os manipuladores que foram notificados naquele ponto da play em específico.
06-c. Usando variáveis com handlers
Talvez queira que seus manipuladores usem variáveis. Por exemplo, se o nome de um serviço variar ligeiramente de distro para distro, você espera que sua saída mostre o nome exato do serviço reiniciado para cada máquina de destino. Por isso, evite colocar variáveis no nome do manipulador. Como os nomes do manipulador são modelados desde o início, o Ansible pode não ter um valor disponível para um nome como este aqui:
handlers:# This handler name may cause your play to fail!
- name: Restart "{{web_service_name
}}"
Se a variável usada no nome do manipulador não estiver disponível, toda a execução falhará. E antes que pense, não! Alterar essa variável “durante” não resultará em um manipulador recém-criado.
Em vez disso, coloque variáveis nos parâmetros de tarefa de seu manipulador. Você pode carregar os valores usando include_vars
como este:
tasks: - name: Set host variables based on distributioninclude_vars:
"{{ansible_facts.distribution
}}.yml" handlers: - name: Restart web service ansible.builtin.service:name:
"{{web_service_name
|default('httpd')
}}" state: restarted
Os manipuladores também podem “ouvir” tópicos genéricos e as tarefas podem notificar esses tópicos da seguinte maneira:
handlers: - name: Restart memcached ansible.builtin.service: name: memcached state: restartedlisten: "restart web services"
- name: Restart apache ansible.builtin.service: name: apache state: restartedlisten: "restart web services"
tasks: - name: Restart everything ansible.builtin.command: echo "this task will restart the web services"notify: "restart web services"
Isso torna muito mais fácil acionar vários manipuladores. Ele também desacopla os manipuladores de seus nomes, facilitando o compartilhamento de manipuladores entre playbooks e roles (especialmente ao usar funções de terceiros de uma fonte compartilhada como o Ansible Galaxy).
REFERÊNCIAS:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_handlers.html#handlers