2014-07-07 29 views
5

ho una definizione Vars come questo:with_subelements ansible valore predefinito

sites: 
- site: mysite1.com 
    exec_init: 
    - "command1 to exec" 
    - "command2 to exec" 
- site: mysite2.com 

allora ho giocare con la seguente attività

- name: Execute init scripts for all sites 
    shell: "{{item.1}}" 
    with_subelements: 
    - sites 
    - exec_init 
    when: item.0.exec_init is defined 

L'idea qui è che avrò più definizioni di "Sito" con dozzine di altre proprietà nei miei vars, quindi vorrei eseguire più comandi di script Shell per quei siti che hanno definito "exec_init"

Doing in questo modo si salta sempre l'esecuzione del compito, ho provato questo in tutte le combinazioni che posso immaginare, ma non riesco a farlo funzionare ...

È questo il modo corretto di farlo? forse sto cercando di ottenere qualcosa che non ha senso?

Grazie per il vostro aiuto

risposta

4

Hm, sembra avere una struttura non uniforme per gli elementi in sites è qualcosa with_subelements non piace. E anche che item non contiene il sottoelemento specificato nell'elenco with_subelements. Si può fare diverse cose:

  1. assicurarsi di avere una lista exec_init, anche se è vuota. with_subelements salterà gli elementi con sottoelementi vuoti. Penso che questa sia l'opzione migliore, anche se un po 'scomoda quando si scrive il playbook.

  2. Non usare with_subelements e lotti eseguire da soli (un po 'brutto):

    - name: Execute init scripts for all sites 
        shell: "echo '{{item.exec_init | join(';')}}' | bash" 
        when: item.exec_init is defined 
        with_items: sites 
    
  3. Personalizza with_subelements in modo che fosse elementi con il sottoelemento mancante. Puoi copiare l'originale (il mio è in /usr/local/lib/python2.7/dist-packages/ansible/runner/lookup_plugins/with_subelements.py) e metterlo in una directory lookup_plugins accanto al tuo playbook, con un nome diverso (ad esempio subelements_missingok.py). Quindi modificare la linea 59 da:

    raise errors.AnsibleError("could not find '%s' key in iterated item '%s'" % (subelement, item0)) 
    

    a:

    continue 
    

    Allora il tuo compito può apparire così:

    - name: Execute init scripts for all sites 
        debug: "msg={{item.1}}" 
        with_subelements_missingok: 
        - sites 
        - exec_init 
    
4

E ancora un altro modo, con la bandiera skip_missing (Ansible 2.0+):

- name: nested loop skip missing elements 
    with_subelements: 
    - sites 
    - exec_init 
    - flags: 
     skip_missing: true 
2

Questo funziona per me. Sto usando la versione 2.1.1 Basta aggiungere il terzo elemento della lista elementi secondari come mostrato

- name: Iterate over something 
    with_subelements: 
    - "{{ unit }}" 
    - config 
    - skip_missing: True 
+0

Documentazione ufficiale nell'ultimo paragrafo di questa sezione: http://docs.ansible.com/ansible/playbooks_loops.html#looping-over-subelements –