2014-09-05 13 views
9

Voglio passare una variabile a un gestore di notifiche, ma non riesco a trovare da nessuna parte che si trovi qui su SO, i documenti oi problemi nel repository github, come farlo. Quello che sto facendo è distribuire più webapps e quando il codice per una di queste webapps viene cambiato, dovrebbe riavviare il servizio per quella webapp.ansible: using with_items con gestore di notifiche

Da this SO question, ho avuto questo lavoro, un po ':

- 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 

(. Metti in test.yml ed eseguirlo con ansible-playbook test.yml -c local)

Ma questo registra il risultato della prima operazione e condizionatamente esegue il ciclo su quello nella seconda attività. Il mio problema è che diventa complicato quando si hanno due o più attività che devono notificare la seconda attività! Ad esempio, riavviare il servizio Web se il codice è stato aggiornato o se la configurazione è stata modificata.

AFAICT, non c'è modo di passare una variabile a un gestore. Questo lo aggiustererebbe in modo pulito per me. Ho trovato alcuni problemi su github in cui altre persone si imbattono nello stesso problema e vengono proposte alcune sintassi, ma nessuna di queste funzioni effettivamente.

Anche l'utilizzo di un sub-playbook non funziona, perché l'utilizzo di with_items insieme a include è stato dichiarato obsoleto.

Nei miei quaderni, ho uno site.yml che elenca i ruoli di un gruppo, quindi nello group_vars per quel gruppo definisco l'elenco di webapp (incluse le versioni) che dovrebbero essere installate. Mi sembra corretto, perché in questo modo posso usare lo stesso playbook per la messa in scena e la produzione. Ma forse l'unica soluzione è definire il ruolo più volte e duplicare l'elenco dei ruoli per la gestione temporanea e la produzione.

Quindi qual è la saggezza qui?

risposta

5

ho finalmente risolto suddividendo le applicazioni fuori sopra più istanze dello stesso ruolo. In questo modo, il gestore nel ruolo può fare riferimento a variabili definite come variabile di ruolo.

In site.yml:

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

in ruoli/qualcosa/attività/main.yml:

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

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

in ruoli/qualcosa/gestori/main.yml:

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

Sembra molto meno hacker della prima soluzione!

+1

Direi che non funzionerà, ho appena provato lo stesso con Ansible 1.8.4 e 1.9.0. Il gestore risolve sempre 'nome' in base al primo richiamo del ruolo,' a' qui, anche quando viene attivato da una successiva chiamata di ruolo. Poiché il gestore e la sua notifica sono globali attraverso le chiamate di ruolo, non è possibile parametrizzarlo in questo modo. – famousgarkin

+2

Strano! Penso di averlo provato, con 1.7.1 al momento. Ma ho funzionato di nuovo cambiando la notifica a "qualcosa è successo a {{nome}}" 'in tasks/main.yml e cambiando il nome del gestore in" "è successo qualcosa a {{nome}}" '. – j0057

+0

Vedere il contenuto qui: https://gist.github.com/j0057/5af0ac913a203a5b94ef - scusa ho dovuto appiattire le directory, forse se lo si biforca è possibile accedere a un commit precedente in cui le directory non sono appiattite. – j0057

14

Le variabili in Ansible sono globali, quindi non c'è motivo di passare una variabile al gestore. Se si sta tentando di impostare un handler in modo parametrizzato nel modo in cui si sta tentando di utilizzare una variabile nel nome di un gestore, non sarà possibile farlo in Ansible.

Che cosa si può fare è creare un gestore che loop su un elenco dei servizi abbastanza facilmente, ecco un esempio di lavoro che può essere testato a livello locale:

- 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

avevo provato questo metodo, ma non funziona bene quando due o più attività può o non notificare il gestore. – j0057

0

Da un gestore è possibile chiamare qualsiasi variabile registrata, ma la variabile registrata viene sovrascritta dall'ultima attività.

- 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 questo esempio la variabile 'file_created' contiene solo il risultato 'Task2'. Ho avuto lo stesso problema e ha proposto un PR: https://github.com/ansible/ansible/pull/6674

Con questo, sarebbe:

- 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

buon PR, ma questo non è in realtà ancora ansible – Evan

+0

The PR è stato chiuso e mai unito, quindi questa non è una risposta. –

Problemi correlati