2014-09-05 9 views
9

Ich möchte eine Variable an einen Benachrichtigungshandler übergeben, kann aber nirgends finden Sie hier auf SO, die Dokumente oder die Probleme im Github Repo, wie es geht. Was ich mache, ist die Bereitstellung mehrerer Webapps. Wenn der Code für eine dieser Webapps geändert wird, sollte der Dienst für diese Webanwendung neu gestartet werden.ansible: Verwenden von with_items mit Benachrichtigungshandler

Von this SO question, ich habe diese, etwas zu arbeiten:

- hosts: localhost 
    tasks: 
    - name: "task 1" 
    shell: "echo {{ item }}" 
    register: "task_1_output" 
    with_items: [a,b] 
    - name: "task 2" 
    debug: 
     msg: "{{ item.item }}" 
    when: item.changed 
    with_items: task_1_output.results 

(. Legen Sie es in test.yml und führen Sie es mit ansible-playbook test.yml -c local)

Aber diese registriert das Ergebnis der ersten Aufgabe und bedingt Schleifen über das in der zweiten Aufgabe. Mein Problem ist, dass es unordentlich wird, wenn Sie zwei oder mehr Aufgaben haben, die die zweite Aufgabe benachrichtigen müssen! Starten Sie beispielsweise den Webdienst neu, wenn entweder der Code aktualisiert wurde oder die Konfiguration geändert wurde.

AFAICT, es gibt keine Möglichkeit, eine Variable an einen Handler zu übergeben. Das würde es sauber für mich reparieren. Ich habe einige Probleme auf GitHub gefunden, wo andere Leute auf das gleiche Problem stoßen, und einige Syntaxen werden vorgeschlagen, aber keine von ihnen funktioniert tatsächlich.

Das Einfügen eines untergeordneten Playbooks funktioniert auch nicht, da die Verwendung von with_items zusammen mit include veraltet war.

In meinen Spielbüchern habe ich eine site.yml, die die Rollen einer Gruppe auflistet, dann in der group_vars für diese Gruppe definiere ich die Liste der Webapps (einschließlich der Versionen), die installiert werden sollen. Das erscheint mir richtig, weil ich auf diese Weise das gleiche Playbook für Inszenierung und Produktion verwenden kann. Die einzige Lösung besteht jedoch darin, die Rolle mehrmals zu definieren und die Rollenliste für die Bereitstellung und Produktion zu duplizieren.

Also, was ist die Weisheit hier?

Antwort

5

ich es endlich gelöst, indem die Anwendungen Aufspalten aus über mehrere Instanzen der gleichen Rolle. Auf diese Weise kann der Handler in der Rolle auf Variablen verweisen, die als Rollenvariable definiert sind.

In site.yml:

- hosts: localhost 
    roles: 
    - role: something 
    name: a 
    - role: something 
    name: b 

In Rollen/etwas/Aufgaben/main.yml:

- name: do something 
    shell: "echo {{ name }}" 
    notify: something happened 

- name: do something else 
    shell: "echo {{ name }}" 
    notify: something happened 

In Rollen/etwas/Handler/main.yml:

- name: something happened 
    debug: 
    msg: "{{ name }}" 

Scheint viel weniger hackish als die erste Lösung!

+1

Ich würde argumentieren, das wird nicht funktionieren, nur das gleiche mit Ansible 1.8.4 und 1.9.0 getestet. Der Handler löst immer "Name" gemäß dem ersten Rollenaufruf "a" auf, auch wenn er durch einen nachfolgenden Rollenaufruf ausgelöst wird. Da der Handler und seine Benachrichtigung bei allen Rollenaufrufen global sind, können Sie sie nicht so parametrisieren. – famousgarkin

+2

Seltsam! Ich denke, ich habe das damals mit 1.7.1 getestet. Aber ich habe es wieder in Betrieb genommen, indem ich die Benachrichtigung auf "etwas passiert mit {{name}}" in tasks/main.yml geändert habe und den Namen des Handlers in "etwas passiert mit {{name}}" geändert habe. '. – j0057

+0

Siehe hier: https://gist.github.com/j0057/5af0ac913a203a5b94ef - Entschuldigung, ich musste die Verzeichnisse glätten, vielleicht, wenn Sie es forkeln, können Sie auf einen früheren Commit zugreifen, wo die Verzeichnisse nicht abgeflacht sind. – j0057

14

Variablen in Ansible sind global, daher gibt es keinen Grund, eine Variable an den Handler zu übergeben. Wenn Sie versuchen, einen Handler so zu parametrisieren, dass Sie versuchen, eine Variable im Namen eines Handlers zu verwenden, können Sie dies nicht in Ansible tun.

Was Sie tun können, ist eine Prozedur erstellen, die leicht genug, um über eine Liste der angebotenen Dienste Schleifen, hier ist ein funktionierendes Beispiel, die lokal getestet werden können:

- hosts: localhost 
    tasks: 
    - file: > 
     path=/tmp/{{ item }} 
     state=directory 
    register: files_created 
    with_items: 
     - one 
     - two 
    notify: some_handler 

    handlers: 
    - name: "some_handler" 
     shell: "echo {{ item }} has changed!" 
     when: item.changed 
     with_items: files_created.results 
+2

ich diese Methode versucht hatte, aber es funktioniert nicht gut, wenn zwei oder mehr Aufgaben kann oder nicht den Handler benachrichtigen. – j0057

0

Von einem Handler können Sie jede registrierte Variable aufrufen, aber registrierte Variable werden von der letzten Aufgabe überschrieben.

- hosts: localhost 
    tasks: 
    - name: Task1 
    file: path=/toto/ state=directory 
    register: files_created 
    notify: some_handler 

    - name: Task2 
    file: path=/toto/ state=directory 
    register: files_created 
    notify: some_handler 

    handlers: 
    - name: "some_handler" 
     debug: msg="{{ file_created.results }}" 

In diesem Beispiel enthält die Variable 'file_created' nur das Ergebnis 'Task2'. Ich hatte das gleiche Problem und schlug eine PR: https://github.com/ansible/ansible/pull/6674

Damit wäre es:

- hosts: localhost 
    tasks: 
    - name: Task1 
    file: path=/toto/ state=directory 
    register: files_created 
    notify: some_handler 
    append_to_list: yes 

    - name: Task2 
    file: path=/toto/ state=directory 
    register: files_created 
    notify: some_handler 
    append_to_list: yes 


    handlers: 
    - name: "some_handler" 
     debug: msg="{{ item.results }}" 
     with_items: files_created 
+0

gute PR, aber das ist eigentlich noch nicht in Ansible – Evan

+0

The PR wurde geschlossen und nie zusammengeführt, also ist dies keine Antwort. –

Verwandte Themen