# In v1.2 with\_items no longer iterates over a list of variables

**URL:** <https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958>\
**Category:** Ansible Project\
**Created:** [June 13, 2013, 8:10pm UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958 "2013-06-13T20:10:14Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Cory\_Wagner](https://avatars.discourse-cdn.com/v4/letter/c/9de053/32.png) [@Cory\_Wagner](https://forum.ansible.com/u/Cory_Wagner)\
**Post date:** [June 13, 2013, 8:10pm UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/1 "2013-06-13T20:10:14Z")

</div>

In version 1.2, we cannot iterate over a list of variables. Ansible now returns the fatal error “with\_items expects a list.” I need to reference a group variable to get a list of items. We’ve used this in a few different situations and now we need a another way to do this or a fix for this issue.

- name: example of broken with\_items issue  
hosts: all  
user: root  
vars:  
mail\_aliases:  
root: [sysadmin@example.com](mailto:sysadmin@example.com)  
oracle: [dbadmin@example.com](mailto:dbadmin@example.com)  
tasks:
- name: add mail aliases  
lineinfile: dest=/etc/aliases regexp=‘^${item}:’ line=“${item}:\t${mail\_aliases.$item}”  
with\_items: $mail\_aliases  
when\_set: $mail\_aliases  
notify: newaliases

---

<div class="post-metadata">

**Author:** ![Lorin\_Hochstein1](https://avatars.discourse-cdn.com/v4/letter/l/ce73a5/32.png) [@Lorin\_Hochstein1](https://forum.ansible.com/u/Lorin_Hochstein1)\
**Post date:** [June 14, 2013, 4:03pm UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/2 "2013-06-14T16:03:54Z")

</div>

Cory:

In your example, it looks like mail\_aliases is a hash. Should work if it’s a list, e.g.:

vars:  
mail\_aliases:

- [sysadmin@example.com](mailto:sysadmin@example.com)
- [dbadmin@example.com](mailto:dbadmin@example.com)

Also, I don’t think you need to dereference the variables anymore in “with\_items”, so you can do:

with\_items: mail\_aliases

Lorin

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 15, 2013, 4:05pm UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/3 "2013-06-15T16:05:22Z")

</div>

Correct, with\_items needs a list, not a hash.

---

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [June 16, 2013, 8:21am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/4 "2013-06-16T08:21:00Z")

</div>

This used to work with hashes too (iterating over hash keys). Is there  
any reason for not supporting this anymore?

---

<div class="post-metadata">

**Author:** ![Lorin\_Hochstein1](https://avatars.discourse-cdn.com/v4/letter/l/ce73a5/32.png) [@Lorin\_Hochstein1](https://forum.ansible.com/u/Lorin_Hochstein1)\
**Post date:** [June 16, 2013, 2:47pm UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/5 "2013-06-16T14:47:50Z")

</div>

> \> Correct, with\_items needs a list, not a hash.  
> \>  
> This used to work with hashes too (iterating over hash keys). Is there  
> any reason for not supporting this anymore?

You can now use Python snippets here, try doing this to turn the dict into  
a list with the values:

&nbsp;&nbsp;&nbsp;&nbsp;with\_items: mail\_aliases.values()

---

<div class="post-metadata">

**Author:** ![Sam\_Solomon](https://avatars.discourse-cdn.com/v4/letter/s/96bed5/32.png) [@Sam\_Solomon](https://forum.ansible.com/u/Sam_Solomon)\
**Post date:** [June 16, 2013, 6:22pm UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/6 "2013-06-16T18:22:54Z")

</div>

What I’ve done a few times recently for k/v type things is use a list of “dicts” (in python speak):

```auto
- name: example of alternative with_items usage
  hosts: all
  user: root
  vars:
    mail_aliases:
      - {name: root, email: sysa...@example.com}
      - {name: oracle, email: dba...@example.com}
  tasks:
  - name: add mail aliases
    lineinfile:
      dest: /etc/aliases
      regexp: '^${item.name}:'
      line: "${item.name}:\t${$item.email}"
    with_items: $mail_aliases
    when_set: $mail_aliases
    notify: newaliases

```

(untested, but I think it should work)

This also has the flexibility of adding even more “values” while keeping the code very readable.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 16, 2013, 8:28pm UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/7 "2013-06-16T20:28:28Z")

</div>

That’s funny as I never intended this, but .iteritems() works on both, so that follows.

I have nothing against checking if something is iterable instead of a list, but did not think anyone would have been doing it.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 17, 2013, 3:48am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/8 "2013-06-17T03:48:48Z")

</div>

Yep, this will definitely work.

If you are in 1.2 you can avoid the ${ … } and just say {{ [item.name](http://item.name) }}

---

<div class="post-metadata">

**Author:** ![Cory\_Wagner](https://avatars.discourse-cdn.com/v4/letter/c/9de053/32.png) [@Cory\_Wagner](https://forum.ansible.com/u/Cory_Wagner)\
**Post date:** [June 17, 2013, 2:30pm UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/9 "2013-06-17T14:30:54Z")

</div>

I was able to find a way around the problem by using the following reference:  
with\_items: $mail\_aliases.keys()

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [June 17, 2013, 9:25pm UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/10 "2013-06-17T21:25:48Z")

</div>

I couldn’t find reference to either keys() or values() in the Jinja2 documentation

[http://jinja.pocoo.org/docs/templates/](http://jinja.pocoo.org/docs/templates/)

when I went hunting for something similar. Not being a Python hacker, and thinking variables in this context where pure Jinja2 variables, I ended up using the dictsort filter, so the original example could be done like so

lineinfile: dest=/etc/aliases regexp=‘^{{ item.0 }}:’ line=“{{ item.0 }}:\t{{ item.1 }}”  
with\_items: mail\_aliases|dictsort

The nice thing about this approach is that you don’t lose the key =\> value mapping information in the original data.

K

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 18, 2013, 3:27am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/11 "2013-06-18T03:27:47Z")

</div>

It would be better to store the data as a list of hashes in that case.

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [June 18, 2013, 3:56am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/12 "2013-06-18T03:56:43Z")

</div>

True, for this play. But if you had an additional play where you wanted to  
look up the alias for a particular user, you can't use the same data.  
For one play, the data is most simply expressed as a list of hashes, but  
for the other, its a hash. Duplicating the data is obviously problematic.

There may be some Python trick to pick out an element of a list by a key,  
but its beyond me. I believe we can't use list comprehensions.

K

Kahlil (Kal) Hodgson GPG: C9A02289  
Head of Technology (m) +61 (0) 4 2573 0382  
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415  
401 Docklands Drive  
Docklands VIC 3008 Australia

"All parts should go together without forcing. You must remember that  
the parts you are reassembling were disassembled by you. Therefore,  
if you can't get them together again, there must be a reason. By all  
means, do not use a hammer." -- IBM maintenance manual, 1925

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 18, 2013, 4:16am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/13 "2013-06-18T04:16:14Z")

</div>

So what seems to occur to me here is that “with\_items” is clearly a list iteration, but it might make sense to make a “with\_dictionary” that allows you to get {{ item.key }} and {{ item.value }} seperately.

And then if the value was a dictionary, it would be like {{ item.value.somekey }}

Just a thought.

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [June 18, 2013, 4:23am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/14 "2013-06-18T04:23:34Z")

</div>

I like that. Much more obvious syntax 🙂

---

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [June 18, 2013, 7:49am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/15 "2013-06-18T07:49:08Z")

</div>

Nice thought, although I would prefer using "with\_keys", "{{ key.name  
}}" and "{{ key.value }}". Same concept, better naming, imho. And it's  
consistent with "with\_items".

---

<div class="post-metadata">

**Author:** ![Nick](https://avatars.discourse-cdn.com/v4/letter/n/f9ae1b/32.png) [@Nick](https://forum.ansible.com/u/Nick)\
**Post date:** [June 18, 2013, 10:12am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/16 "2013-06-18T10:12:30Z")

</div>

I had this problem a few months back, and wrote a pair of custom lookup plugins to do the job. (See below.) Was meaning to contribute it back but so far hadn't gotten around to it yet.

The examples below haven't been tested recently, so no guarantees they still work. But assuming they do, you can just put them in a directory, let's call it $library, define $ANSIBLE\_LIBRARY to include it, then you use them via "with\_keys" and "with\_values".

Cheers and HTH

N

---

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [June 19, 2013, 6:37pm UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/17 "2013-06-19T18:37:06Z")

</div>

Also, I think that it would be more reasonable and closer to Ansible's  
linear execution model to map YAML dictionaries to OrderedDict objects  
([http://docs.python.org/2/library/collections.html#ordereddict-objects](http://docs.python.org/2/library/collections.html#ordereddict-objects)),  
so that a 'with\_keys' implementation iterates through the keys in the  
order they are written in YAML code. The only problem is that  
OrderedDict is available in Python version \>= 2.7, but Ansible could  
fallback to a backported version if available, or to an ordinary dict if  
not.

What do you think?

---

<div class="post-metadata">

**Author:** ![Jeremiah\_Heller](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@Jeremiah\_Heller](https://forum.ansible.com/u/Jeremiah_Heller)\
**Post date:** [June 20, 2013, 12:53am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/18 "2013-06-20T00:53:59Z")

</div>

I like with\_keys; especially ordered! Little wary about falling back quietly to unordered. What about adding a companion attr? Say: unordered\_ok=True ? Just looking to make the fallback explicit.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 20, 2013, 2:45am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/19 "2013-06-20T02:45:06Z")

</div>

I’d suggest always sorting rather than having to request sorting.

---

<div class="post-metadata">

**Author:** ![Jim\_Kleckner](https://avatars.discourse-cdn.com/v4/letter/j/848f3c/32.png) [@Jim\_Kleckner](https://forum.ansible.com/u/Jim_Kleckner)\
**Post date:** [October 15, 2013, 12:46am UTC](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958/20 "2013-10-15T00:46:22Z")

</div>

“I have nothing against checking if something is iterable instead of a list, but did not think anyone would have been doing it.”

I had implemented this as part of a discussion with a colleague and then went back and found this discussion.

In part it was the “dict is iterable so it ought to be a suitable item iterator” reasoning that led to this.

It is not a good argument for it, but the change is only 3 lines of executable code…

Comments?  
[https://github.com/jkleckner/ansible/commit/9a18d60e6ef80bc6a25d29704c76fa93621d4830](https://github.com/jkleckner/ansible/commit/9a18d60e6ef80bc6a25d29704c76fa93621d4830)  
[https://github.com/jkleckner/ansible/tree/extend-with-items-allow-hash](https://github.com/jkleckner/ansible/tree/extend-with-items-allow-hash)

Jim

[Next page](https://forum.ansible.com/t/in-v1-2-with-items-no-longer-iterates-over-a-list-of-variables/12958.md?page=2)
