summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorRené Moser <mail@renemoser.net>2016-03-07 11:03:53 +0100
committerRene Moser <mail@renemoser.net>2016-03-07 13:00:05 +0100
commit66cb77107b60156ec4085300e6bd151a283a709c (patch)
treedb4359a20cfaf59f231c5c00ab8255320735e768 /docs
parentd60f0c94f8b66cb34631314be463722648cb9e98 (diff)
downloadansible-66cb77107b60156ec4085300e6bd151a283a709c.tar.gz
proposal: publish/subscribe for handlers
Diffstat (limited to 'docs')
-rw-r--r--docs/proposals/publish-subscribe.md205
1 files changed, 205 insertions, 0 deletions
diff --git a/docs/proposals/publish-subscribe.md b/docs/proposals/publish-subscribe.md
new file mode 100644
index 0000000000..f31d2dca33
--- /dev/null
+++ b/docs/proposals/publish-subscribe.md
@@ -0,0 +1,205 @@
+# Publish / Subscribe for Handlers
+
+*Author*: René Moser <@resmo>
+
+*Date*: 07/03/2016
+
+## Motivation
+
+In some use cases a publish/subscribe kind of event to run a handler is more convenient, e.g. restart services after replacing SSL certs.
+
+However, ansible does not provide a built-in way to handle it yet.
+
+
+### Problem
+
+If your SSL cert changes, you usually have to reload/restart services to use the new certificate.
+
+However, If you have a ssl role or a generic ssl play, you usually don't want to add specific handlers to it.
+Instead it would be much more convenient to use a publish/subscribe kind of paradigm in the roles where the services are configured in.
+
+The way we implemented it currently:
+
+I use notify to set a fact where later (in different plays) we act on a fact using notify again.
+
+~~~yaml
+---
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - name: copy an ssl cert
+ shell: echo cert has been changed
+ notify: publish ssl cert change
+ handlers:
+ - name: publish ssl cert change
+ set_fact:
+ ssl_cert_changed: true
+
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - name: subscribe for ssl cert change
+ shell: echo cert changed
+ notify: service restart one
+ when: ssl_cert_changed is defined and ssl_cert_changed
+ handlers:
+ - name: service restart one
+ shell: echo service one restarted
+
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - name: subscribe for ssl cert change
+ shell: echo cert changed
+ when: ssl_cert_changed is defined and ssl_cert_changed
+ notify: service restart two
+ handlers:
+ - name: service restart two
+ shell: echo service two restarted
+~~~
+
+However, this looks like a workaround of a feature that ansible should provide in a much cleaner way.
+
+## Approaches
+
+### Approach 1:
+
+Provide new `subscribe` keyword on handlers:
+
+~~~yaml
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - name: copy an ssl cert
+ shell: echo cert has been changed
+
+
+- hosts: localhost
+ gather_facts: no
+ handlers:
+ - name: service restart one
+ shell: echo service one restarted
+ subscribe: copy an ssl cert
+
+
+- hosts: localhost
+ gather_facts: no
+ handlers:
+ - name: service restart two
+ shell: echo service two restarted
+ subscribe: copy an ssl cert
+~~~
+
+### Approach 2:
+
+Provide new `subscribe` on handlers and `publish` keywords in tasks:
+
+~~~yaml
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - name: copy an ssl cert
+ shell: echo cert has been changed
+ publish: yes
+
+
+- hosts: localhost
+ gather_facts: no
+ handlers:
+ - name: service restart one
+ shell: echo service one restarted
+ subscribe: copy an ssl cert
+
+
+- hosts: localhost
+ gather_facts: no
+ handlers:
+ - name: service restart two
+ shell: echo service two restarted
+ subscribe: copy an ssl cert
+~~~
+
+### Approach 3:
+
+Provide new `subscribe` module:
+
+A subscribe module could consume the results of a task by name, optionally the value to react on could be specified (default: `changed`)
+
+~~~yaml
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - name: copy an ssl cert
+ shell: echo cert has been changed
+
+
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - subscribe:
+ name: copy an ssl cert
+ notify: service restart one
+ handlers:
+ - name: service restart one
+ shell: echo service one restarted
+
+
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - subscribe:
+ name: copy an ssl cert
+ react_on: changed
+ notify: service restart two
+ handlers:
+ - name: service restart two
+ shell: echo service two restarted
+~~~
+
+
+### Approach 4:
+
+Provide new `subscribe` module (same as Approach 3) and `publish` keyword:
+
+~~~yaml
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - name: copy an ssl cert
+ shell: echo cert has been changed
+ publish: yes
+
+
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - subscribe:
+ name: copy an ssl cert
+ notify: service restart one
+ handlers:
+ - name: service restart one
+ shell: echo service one restarted
+
+
+- hosts: localhost
+ gather_facts: no
+ tasks:
+ - subscribe:
+ name: copy an ssl cert
+ notify: service restart two
+ handlers:
+ - name: service restart two
+ shell: echo service two restarted
+~~~
+
+### Clarifications about role dependencies and publish
+
+When using service roles having the subscription handlers and the publish task (e.g. cert change) is defined in a depended role (SSL role) only the first service role running the "cert change" task as dependency will trigger the publish.
+
+In any other service role in the playbook having "SSL role" as dependency, the task won't be `changed` anymore.
+
+Therefore a once published "message" should not be overwritten or so called "unpublished" by running the same task in a followed role in the playbook.
+
+## Conclusion
+
+Feedback is requested to improve any of the above approaches, or provide further approaches to solve this problem.