2015-04-01 12 views
36

Attualmente sto utilizzando Ansible 1.7.2. Ho il seguente playbook di prova:Utilizzo di set_facts e with_items insieme in Ansible

--- 
- hosts: localhost 
    tasks: 
    - name: set fact 1 
    set_fact: foo="[ 'zero' ]" 

    - name: set fact 2 
    set_fact: foo="{{ foo }} + [ 'one' ]" 

    - name: set fact 3 
    set_fact: foo="{{ foo }} + [ 'two', 'three' ]" 

    - name: set fact 4 
    set_fact: foo="{{ foo }} + [ '{{ item }}' ]" 
    with_items: 
     - four 
     - five 
     - six 

    - debug: var=foo 

La prima attività imposta un fatto che è un elenco con un elemento in esso. Le attività successive si aggiungono a quell'elenco con più valori. Le prime tre attività funzionano come previsto, ma l'ultima no. Ecco l'output quando eseguo questo:

PLAY [localhost] ************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [localhost] 

TASK: [set fact 1] ************************************************************ 
ok: [localhost] 

TASK: [set fact 2] ************************************************************ 
ok: [localhost] 

TASK: [set fact 3] ************************************************************ 
ok: [localhost] 

TASK: [set fact 4] ************************************************************ 
ok: [localhost] => (item=four) 
ok: [localhost] => (item=five) 
ok: [localhost] => (item=six) 

TASK: [debug var=foo] ********************************************************* 
ok: [localhost] => { 
    "foo": [ 
     "zero", 
     "one", 
     "two", 
     "three", 
     "six" 
    ] 
} 

PLAY RECAP ******************************************************************** 
localhost     : ok=6 changed=0 unreachable=0 failed=0 

Date le with_items in compiti 4 e il fatto che l'output mostra il compito correttamente iterata nel corso degli elementi in quella lista, mi sarei aspettato il risultato di contenere tutti i numeri da zero a sei. Ma quest'ultima attività sembra valutare solo set_fact con l'ultimo elemento nell'elenco. È forse un bug in Ansible?

Edit: ho anche appena testato su ansible 1.8 e l'output era identico.

+0

La mia ipotesi migliore sarebbe che ansible valuta '{{foo}}' solo una volta durante l'esecuzione del task 'set fact 4'. Vuoi capire come unire due liste o solo curioso? – Kashyap

+0

Sì, sembra essere il caso. No, non provando a unire semplicemente le liste. Sto cercando di tenere traccia dei nomi di file generati dinamicamente in modo che altre attività possano scorrere attraverso di essi. –

+0

Sembra che questa sia una caratteristica che molti desiderano, e c'è persino una [richiesta pull] (https://github.com/ansible/ansible/pull/8019) per questo, ma continua a essere espulsa per qualche motivo ... –

risposta

1

Sembra che questo comportamento sia il modo in cui Ansible funziona attualmente, sebbene sia molto interessante correggerlo per funzionare come desiderato. Attualmente c'è un pull request con la funzionalità desiderata, quindi spero che questo possa essere incorporato in Ansible alla fine.

57

C'è una soluzione che può aiutare. Si può "registrare" i risultati per ogni iterazione set_fact e poi mappare che i risultati alla lista:

--- 
- hosts: localhost 
    tasks: 
    - name: set fact 
    set_fact: foo_item="{{ item }}" 
    with_items: 
     - four 
     - five 
     - six 
    register: foo_result 

    - name: make a list 
    set_fact: foo="{{ foo_result.results | map(attribute='ansible_facts.foo_item') | list }}" 

    - debug: var=foo 

uscita:

< TASK: debug var=foo > 
--------------------- 
    \ ^__^ 
    \ (oo)\_______ 
     (__)\  )\/\ 
      ||----w | 
      ||  || 


ok: [localhost] => { 
    "var": { 
     "foo": [ 
      "four", 
      "five", 
      "six" 
     ] 
    } 
} 
+2

Questa dovrebbe essere la risposta accettata. –

+1

questo errore fallisce su ansible v2. Qualche idea su come farlo funzionare su V2? – DomaNitro

+0

Sembra che questo si interrompa se aggiungi un 'quando' al tuo gioco. Invece, otterrai un 'risultato' che ti dice solo che qualcosa è stato saltato.: -/ –

7

Jinja 2.6 non ha la funzione di carta. Quindi, un modo alternativo di fare questo sarebbe:

set_fact: foo="{% for i in bar_result.results %}{{ i.ansible_facts.foo_item }}{%endfor%}" 
3

Come accennato nei commenti di altre persone, la soluzione top qui dato non funzionava per me in Ansible 2.2, in particolare quando utilizzando anche with_items.

Sembra che l'approccio previsto da OP funzioni ora con una leggera modifica alla quotazione di item.

- set_fact: something="{{ something + [ item ] }}" 
    with_items: 
    - one 
    - two 
    - three 

E un esempio più dove ho gestito il caso iniziale della lista essere indefinito e aggiunto un optional when perché che è stato anche mi ha causato dolore:

- set_fact: something="{{ something|default([]) + [ item ] }}" 
    with_items: 
    - one 
    - two 
    - three 
    when: item.name in allowed_things.item_list 
Problemi correlati