Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ansible with_items list of lists is flattening

Tags:

yaml

ansible

I'm trying to use ansible to loop over a list of lists to install some packages. But {{item}} is returning every element in the sub lists rather than the sublist itself. I have a yaml file which come from a manifest list from outside ansible and it looks like this:

---
modules:
 - ['module','version','extra']
 - ['module2','version','extra']
 - ['module3','version','extra']

My task looks like this:

task:
 - include_vars: /path/to/external/file.yml
 - name: install modules
   yum: name={{item.0}} state=installed
   with_items: "{{ modules }}"

When I run that I get:

fatal: [localhost]: FAILED! => {"failed": true, "msg": "ERROR! int object has no element 0"}

When I try:

- debug: msg="{{item}}"
  with_items: "{{module}}"

it prints every element (module, version, extra, and so on), not just the sublist (which is what I would expect)

like image 769
Neybar Avatar asked Feb 26 '16 21:02

Neybar


People also ask

What is {{ item }} Ansible?

item is not a command, but a variable automatically created and populated by Ansible in tasks which use loops. In the following example: - debug: msg: "{{ item }}" with_items: - first - second. the task will be run twice: first time with the variable item set to first , the second time with second .

How do you use nested loops in Ansible?

Nested loops in many ways are similar in nature to a set of arrays that would be iterated over using the with_nested operator. Nested loops provide us with a succinct way of iterating over multiple lists within a single task. Now we can create nested loops using with_nested.

What is Loop_var in Ansible?

Defining inner and outer variable names with loop_var However, by default Ansible sets the loop variable item for each loop. This means the inner, nested loop will overwrite the value of item from the outer loop. You can specify the name of the variable for each loop using loop_var with loop_control .

Does Ansible do until loops?

This loop is used for retrying task until certain condition is met. To use this loop in task you essentially need to add 3 arguments to your task arguments: until - condition that must be met for loop to stop. That is Ansible will continue executing the task until expression used here evaluates to true.


1 Answers

An alternative way to solve this issue is to use a complex item instead of a list of list. Structure your variables like this:

- modules:
  - {name: module1, version: version1, info: extra1}
  - {name: module2, version: version2, info: extra2}
  - {name: module3, version: version3, info: extra3}

Then you can still use with_items, like this:

- name: Printing Stuffs...
  shell: echo This is "{{ item.name }}", "{{ item.version }}" and "{{ item.info }}"
  with_items: "{{modules}}"
like image 154
gameweld Avatar answered Oct 07 '22 17:10

gameweld