Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using set_facts and with_items together in Ansible

Tags:

ansible

I'm currently using Ansible 1.7.2. I have the following test playbook:

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

The first task sets a fact that's a list with one item in it. The subsequent tasks append to that list with more values. The first three tasks work as expected, but the last one doesn't. Here's the output when I run this:

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 

Given the with_items in task 4 and the fact that the output shows the task properly iterated over the items in that list, I would have expected the result to contain all the numbers zero through six. But that last task seems to only be evaluating set_fact with the last item in the list. Is this possibly a bug in Ansible?

Edit: I also just tested this on ansible 1.8 and the output was identical.

like image 641
Bruce P Avatar asked Apr 01 '15 19:04

Bruce P


People also ask

What is set_fact in Ansible-playbook?

This module allows setting new variables. Variables are set on a host-by-host basis just like facts discovered by the setup module. These variables will be available to subsequent plays during an ansible-playbook run.

How do you assign variables in Ansible?

To define a variable in a playbook, simply use the keyword vars before writing your variables with indentation. To access the value of the variable, place it between the double curly braces enclosed with quotation marks. In the above playbook, the greeting variable is substituted by the value Hello world!

What is With_item in Ansible?

What is Ansible with_items? The Ansible with_items is a handy plugin to perform loop operations in a playbook. The plugin accepts items and then passes them to the calling module. For example, you can pass a list of packages to install and then give each item in the list to the install task.


1 Answers

There is a workaround which may help. You may "register" results for each set_fact iteration and then map that results to list:

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

Output:

< TASK: debug var=foo >  ---------------------     \   ^__^      \  (oo)\_______         (__)\       )\/\             ||----w |             ||     ||   ok: [localhost] => {     "var": {         "foo": [             "four",              "five",              "six"         ]     } } 
like image 64
serge Avatar answered Sep 18 '22 02:09

serge