2015-05-04 16 views
15

Sono seduto di fronte a un progetto Ansible abbastanza complesso che stiamo utilizzando per impostare i nostri ambienti di sviluppo locali (più VM) e c'è un ruolo che utilizza i fatti raccolti da Ansible per configurare il file /etc/hosts su ogni VM. Sfortunatamente, quando vuoi eseguire il playbook per un solo host (usando il parametro -limit) i fatti dagli altri host sono (ovviamente) mancanti.Raccolta fatture forzata su tutti gli host

C'è un modo per forzare Ansible a raccogliere informazioni su tutti gli host, anche se si limita il playbook a un host specifico?

Abbiamo provato ad aggiungere una riproduzione al playbook per raccogliere i dati da tutti gli host, ma ovviamente anche questo si limita a un host dato dal parametro -limit. Se ci fosse un modo per forzare questo gioco a girare su tutti gli host prima delle altre giocate, sarebbe perfetto.

Ho cercato su Google un po 'e ho trovato la soluzione con il fatto che si memorizza nella cache con i redis, ma dal momento che il nostro playbook è utilizzato localmente, volevo evitare la necessità di software aggiuntivo. Lo so, non è un grosso problema, ma stavo solo cercando una soluzione "pulita", solo Ansible, e mi chiedevo se questo sarebbe esistito.

risposta

9

In generale, il modo per ottenere i fatti per tutti i padroni di casa anche quando non si desidera eseguire operazioni su tutti gli host è quello di fare qualcosa di simile:

- hosts: all 
    tasks: [ ] 

Ma come lei ha ricordato, il --limit parametro limiterà a quali host questo verrà applicato.

Non credo che ci sia un modo per dire semplicemente ad Ansible di ignorare il parametro --limit su qualsiasi riproduzione. Tuttavia, potrebbe esserci un altro modo per fare ciò che vuoi interamente all'interno di Ansible.

Non l'ho usato personalmente, ma ad Ansible 1.8 fact caching è disponibile. In poche parole, con effetti di caching abilitato Ansible utilizzerà un server Redis per memorizzare nella cache tutti i fatti su host che incontra e sarete in grado di farvi riferimento nelle successive Playbook:

Con Infatti caching abilitato, è possibile per macchina in un gruppo per fare riferimento a variabili relative a macchine nell'altro gruppo, nonostante non siano state comunicate con l'esecuzione corrente di/usr/bin/ansible-playbook.

+2

Grazie per la risposta. Questa era la nostra prima soluzione, ma sembra che il caching dei fatti sia l'unica soluzione per questo problema. Sarebbe bello avere qualcosa che possa scavalcare il parametro limite per la raccolta di fatti. – tehK

5

Questo sembra essere ancora un problema senza una soluzione pulita qui nel 2016, ma le versioni più recenti di Ansible offrono una "jsonfile" back-end infatti caching, che sembra essere un compromesso decente per l'installazione di Redis a livello locale solo per affrontare questo bisogno. Ora sparo un ansible all -m setup prima di eseguire un playbook con l'opzione --limit. Abbastanza buono per il jazz!

http://docs.ansible.com/ansible/playbooks_variables.html#fact-caching

1

Si potrebbe modificare il vostro playbook a:

... 
- hosts: "{{ limit_hosts|default('default_group') }}" 
    tasks: 
    ... 
... 

E quando lo si esegue, se some_var non è definito (stato normale), allora verrà eseguito sul gruppo di inventario default_group, ma se lo si esegue come:

ansible-playbook --extra-vars "limit_hosts=myHost" myplaybook.yml 

Poi sarà eseguito solo su vostra myHost, ma si potrebbe ancora hav e altre sezioni con diverse dichiarazioni hosts: .., per la raccolta di fatti o qualsiasi altra cosa in realtà.

4

La versione 2 di Ansible ha introdotto un modo pulito e ufficiale per farlo utilizzando fatti delegati (vedere: http://docs.ansible.com/ansible/latest/playbooks_delegation.html#delegated-facts).

--- 
# This play will still work as intended if called with --limit 

- name: Hostfile generation 
    hosts: all 
    become: true 

    pre_tasks: 
    - name: Gather facts from ALL hosts (regardless of limit or tags) 
     setup: 
     delegate_to: "{{ item }}" 
     delegate_facts: True 
     when: hostvars[item]['ansible_default_ipv4'] is not defined 
     with_items: "{{ groups['all'] }}" 

    tasks: 
    - template: 
     src: "templates/hosts.j2" 
     dest: "/etc/hosts"