2015-04-01 3 views
36

Я использую Ansible 1.7.2. У меня есть следующий тестовый учебник:Использование set_facts и with_items вместе в 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 

Первая задача устанавливает факт, который представляет собой список с одним элементом в нем. Последующие задачи добавляются к этому списку с большим количеством значений. Первые три задачи работают так, как ожидалось, но последний не работает. Вот вывод, когда я запускаю это:

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 

Учитывая with_items в задаче 4, и тот факт, что выход показывает задачу правильно итерированную над элементами в этом списке, я ожидал бы результат, содержащий все номера от нуля до шести. Но эта последняя задача, по-видимому, оценивает только set_fact с последним элементом в списке. Возможно, это ошибка в Ansible?

Редактировать: Я также просто проверил это на 1,8, и выход был идентичным.

+0

Мое предположение было бы, что анзибль оценивает '{{foo}}' только один раз во время выполнения задачи 'set fact 4'. Вы хотите выяснить, как объединить два списка или просто любопытно? – Kashyap

+0

Да, это похоже на случай. Нет, не пытайтесь просто слить списки. Я пытаюсь отслеживать динамически генерируемые имена файлов, чтобы другие задачи могли проходить через них. –

+0

Похоже, что это особенность, которую желают многие люди, и есть даже [тянуть запрос] (https://github.com/ansible/ansible/pull/8019) для него, но по какой-то причине он все равно выталкивается ... –

ответ

1

Похоже, что такое поведение как-то работает в настоящее время, хотя есть большая заинтересованность в том, чтобы он работал по желанию. В настоящее время есть pull request с желаемой функциональностью, поэтому, надеюсь, это в конечном итоге будет включено в Ansible.

57

Существует обходное решение, которое может помочь. Вы можете «зарегистрировать» результаты для каждой итерации set_fact, а затем карту, что приводит к списку:

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

Выход:

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


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

Это должен быть принятый ответ. –

+1

этот wil fail на незаменимом v2. Любые идеи, как заставить его работать на V2? – DomaNitro

+0

Кажется, что это ломается, если вы добавляете 'when' в свою игру. Вместо этого вы получите «результаты», которые просто скажут вам, что что-то пропущено.: -/ –

7

Дзиндзя 2,6 не имеет функцию карты. Таким образом, альтернативный способ сделать это будет:

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

Как уже упоминалось в комментариях других людей, верхнее решение, данное здесь не работает для меня в анзибль 2.2, в частности, когда и с помощью with_items.

Похоже, что предполагаемый подход OP работает сейчас с небольшим изменением на котировку item.

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

И больше примера, где я обработал начальный случай списка быть неопределенным и добавил дополнительный when потому, что также вызывает у меня горе:

- set_fact: something="{{ something|default([]) + [ item ] }}" 
    with_items: 
    - one 
    - two 
    - three 
    when: item.name in allowed_things.item_list 
Смежные вопросы