2015-04-01 9 views
36

Ich benutze derzeit Ansible 1.7.2. Ich habe folgende Test Textbuch:Verwenden von set_facts und with_items zusammen 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 

Die erste Aufgabe setzt eine Tatsache, die in ihm eine Liste mit einem Element ist. Die nachfolgenden Aufgaben fügen diese Liste mit mehr Werten an. Die ersten drei Aufgaben funktionieren wie erwartet, die letzte jedoch nicht. Hier ist der Ausgang ist, wenn ich dies auszuführen:

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 

Bei den with_items in Aufgabe 4 und der Tatsache, dass die Ausgabe der Aufgabe zeigt ordnungsgemäß über die Elemente in dieser Liste iteriert, würde ich das Ergebnis zu erwarten haben alle Zahlen enthalten null bis sechs. Aber diese letzte Aufgabe scheint nur set_fact mit dem letzten Element in der Liste auszuwerten. Ist das möglicherweise ein Fehler in Ansible?

Edit: Ich habe auch nur auf Ansible 1,8 getestet und die Ausgabe war identisch.

+0

Meine beste Vermutung wäre, dass ansible wertet '{{foo}}' nur einmal während der Ausführung der Aufgabe 'set fact 4' aus. Willst du herausfinden, wie man zwei Listen zusammenführt oder nur neugierig? – Kashyap

+0

Ja, das scheint der Fall zu sein. Nein, ich versuche nicht nur Listen zusammenzuführen. Ich versuche, dynamisch generierte Dateinamen zu verfolgen, damit andere Aufgaben sie durchlaufen können. –

+0

Sieht so aus, als ob dies eine Funktion ist, die viele Leute wünschen, und es gibt sogar eine [pull request] (https://github.com/ansible/ansible/pull/8019) dafür, aber es wird aus irgendeinem Grund hinausgeschoben ... –

Antwort

1

Sieht aus wie dieses Verhalten ist, wie Ansible derzeit funktioniert, obwohl es ein großes Interesse daran gibt, es wie gewünscht zu reparieren. Es gibt derzeit eine pull request mit der gewünschten Funktionalität, so hoffentlich wird dies in Ansible schließlich integriert werden.

57

Es gibt einen Workaround, der helfen kann. Sie können "Register" Ergebnisse für jede set_fact Iteration und Karte dann, dass die Ergebnisse zur Liste:

--- 
- 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 

Ausgang:

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


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

Dies sollte die akzeptierte Antwort sein. –

+1

dies wird auf ansible v2 fehlschlagen. Irgendwelche Ideen, wie man es mit V2 macht? – DomaNitro

+0

Es scheint, dass dies bricht, wenn Sie ein "When" zu Ihrem Spiel hinzufügen. Stattdessen erhalten Sie ein Ergebnis, das Ihnen sagt, dass etwas übersprungen wurde.: -/ –

7

Jinja 2.6 verfügt nicht über die Kartenfunktion. So eine alternative Art und Weise, dies zu tun wäre:

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

Wie in anderen Leuten Kommentare erwähnen, ist die Top-Lösung, die hier gegeben wurde, nicht für mich arbeitet in ansible 2.2, vor allem, wenn auch with_items verwenden.

Es scheint, dass die beabsichtigte Vorgehensweise von OP jetzt mit einer geringfügigen Änderung der Quotierung von item funktioniert.

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

Und ein längeres Beispiel, wo ich den ersten Fall von der Liste behandelt haben wird nicht definiert und hinzugefügt eine optionale when weil das auch verursacht wurde mir Kummer:

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