0

Here is a very simple code fragment taken from my "kafka" role:

- import_role:
    name: java
  notify:
    - restart kafka
    - restart zookeeper

Basically I want to install Java running "java" role and when there are changes performed by that role (e.g. Java has been updated), then restart "kafka" and "zookeeper" services. It turns out, Ansible doesn't throw any error as well as not running these handlers specified in "notify" field.

What would be my options to workaround this?

P.S. Java is being installed manually, not from repositories.

Erikas
  • 1,006
  • 11
  • 22
  • 1
    Ooops, duplicate: https://stackoverflow.com/questions/57542223/ansible-run-handler-only-if-any-task-in-role-changed – Erikas Sep 17 '20 at 08:07
  • Does this answer your question? [ansible - run handler only if any task in role changed](https://stackoverflow.com/questions/57542223/ansible-run-handler-only-if-any-task-in-role-changed) – toydarian Sep 17 '20 at 08:23
  • Not really. I want to see what options do I have since my problem is very straightforward. The other thread is literally asking why it doesn't work, and I am asking what are my alternatives. – Erikas Sep 17 '20 at 08:27
  • This is exactly the question you said was a duplicate an hour ago... – toydarian Sep 17 '20 at 09:01
  • Nevermind, I answered my own question. – Erikas Sep 17 '20 at 09:17

2 Answers2

2

I am answering my own question.


Problem

I have 3 roles in total:

  • kafka - installs kafka and zookeeper apps, configures, enables/starts services etc.
  • ssl - copies certificates to the server specific dir and that's it. When certificate is changed, I need to restart only kafka service.
  • java - installs java and that is it. When java is updated, I need to restart both kafka and zookeeper services.

Then intention was to run only kafka role and include other ssl and java roles inside kafka role. Like this:

- import_role:
    name: java
  notify:
    - restart kafka
    - restart zookeeper

- import_role:
    name: ssl
  notify:
    - restart kafka

I've been expecting above code to work, because why not? Ansible did not throw any error regarding this, but silently did not run any handlers...

Note: both ssl and java are being re-usable roles, used by few other roles/playbooks.


Workaround

I've changed my handlers in kafka role into like this:

- name: restart kafka
  service:
    name: kafka
    state: restarted
  when: "'kafka_all' in group_names"
  listen:
    - restart SSL dependent services
    - restart java dependent services
    - restart kafka & zookeeper services

- name: restart zookeeper
  service:
    name: zookeeper
    state: restarted
  when: "'kafka_all' in group_names"
  listen:
    - restart java dependent services
    - restart kafka & zookeeper services

Then changed code in kafka role tasks like this:

- import_role:
    name: java

- import_role:
    name: ssl

And in both java and ssl role tasks I've added handlers accordingly. Like this for ssl role:

- name: upload SSL files
  copy:
    src: <hidden>
    dest: <hidden>
  notify: restart SSL dependent services

All above code might not make any sense yet, but familiarize yourself with below key points:

  1. In kafka role I import and not include other roles. It means that imported roles (kafka and ssl) are able to "see" handlers of kafka role. Upstream note.
  2. I am using Ansible's 2.8 new feature called listen. It means tasks can call a specified "listener" and it will automatically calls all listening handlers. If there are no handlers bound to the listener, it will not run anything (and that's expected behavior).
  3. Not so important, but I am using when: "'kafka_all' in group_names" just because I am storing kafka installation tasks in task file install.yml and I specified there notify: restart kafka & zookeeper services and the thing is - I want to install Kafka on server where I want Kafka as a service as well as on server where I want to have Kafka CLI tools only (so no services are started). Such server won't be part of kafka_all and eventually these handlers won't be executed.
Erikas
  • 1,006
  • 11
  • 22
0

In case anyone else stumbles on this post and wishes for something aside from workarounds. I have found through some testing and research that one should be able to now have notify: work in import_role:. As of Ansible v2.11 it appears that notify: is no longer ignored in the case of import_role:, meaning, the handlers specified as part of the import_role: task will run in the event said role does happen to make a change.

This seems to be an indirect benefit of now (at least as of Ansible v2.11) being able to add notify: to block: and notify: also not being ignored by import_tasks: (see https://github.com/ansible/ansible/blame/stable-2.11/changelogs/CHANGELOG-v2.11.rst#L879 and https://github.com/ansible/ansible/pull/73572/commits).

cavcrosby
  • 1
  • 1
  • 2