# How to loop over an array inside a dictionary

**URL:** <https://forum.ansible.com/t/how-to-loop-over-an-array-inside-a-dictionary/16814>\
**Category:** Ansible Project\
**Created:** [November 18, 2014, 6:55pm UTC](https://forum.ansible.com/t/how-to-loop-over-an-array-inside-a-dictionary/16814 "2014-11-18T18:55:42Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thomas\_Krahn](https://avatars.discourse-cdn.com/v4/letter/t/958977/32.png) [@Thomas\_Krahn](https://forum.ansible.com/u/Thomas_Krahn)\
**Post date:** [November 18, 2014, 6:55pm UTC](https://forum.ansible.com/t/how-to-loop-over-an-array-inside-a-dictionary/16814/1 "2014-11-18T18:55:42Z")

</div>

Hi All

i’m trying to migrate my Oracle installation from Puppet to Ansible. As i need severyl ORACLE\_HOME on one server i have defned the following dictionary variable:

oracle\_app\_directory=/app  
oracle\_db\_homes:

dbhome\_1:  
version: 12.1.0  
path: “{{ oracle\_app\_directory }}/oracle/product/12.1.0/dbhome\_1”  
installation\_files\_directory: /share/oracle/12.1.0/patches  
installation\_files:

- linuxamd64\_12c\_database\_1of2.zip

- linuxamd64\_12c\_database\_2of2.zip  
unpack\_directory: /share/oracle/12.1.0/unpacked  
dbhome\_2:  
version: 11.2.0  
path: “{{ oracle\_app\_directory }}/oracle/product/11.2.0/dbhome\_1”  
installation\_files\_directory: /share/oracle/11.2.0/patches  
installation\_files:

- linuxamd64\_11g\_database\_1of2.zip

- linuxamd64\_11g\_database\_2of2.zip

unpack\_directory: /share/oracle/11.2.0/unpacked

I need to loop over the dictionary (oracle\_db\_homes) to unpack the files (installation\_files) for each defined ORACLE\_HOME into a directory (unpack\_directory).

How can i do that with Ansible ?

---

<div class="post-metadata">

**Author:** ![jorginator74](https://avatars.discourse-cdn.com/v4/letter/j/f19dbf/32.png) [@jorginator74](https://forum.ansible.com/u/jorginator74)\
**Post date:** [November 18, 2014, 9:29pm UTC](https://forum.ansible.com/t/how-to-loop-over-an-array-inside-a-dictionary/16814/2 "2014-11-18T21:29:45Z")

</div>

Hi

> Hi All
> 
> i'm trying to migrate my Oracle installation from Puppet to Ansible. As i need  
> severyl ORACLE\_HOME on one server i have defned the following dictionary  
> variable:
> 
> oracle\_app\_directory=/app  
> oracle\_db\_homes:  
> &nbsp;&nbsp;dbhome\_1:  
> &nbsp;&nbsp;&nbsp;&nbsp;version: 12.1.0  
> &nbsp;&nbsp;&nbsp;&nbsp;path: "{{ oracle\_app\_directory }}/oracle/product/12.1.0/dbhome\_1"  
> &nbsp;&nbsp;&nbsp;&nbsp;installation\_files\_directory: /share/oracle/12.1.0/patches  
> &nbsp;&nbsp;&nbsp;&nbsp;installation\_files:  
> &nbsp;&nbsp;&nbsp;&nbsp;- linuxamd64\_12c\_database\_1of2.zip  
> &nbsp;&nbsp;&nbsp;&nbsp;- linuxamd64\_12c\_database\_2of2.zip  
> &nbsp;&nbsp;&nbsp;&nbsp;unpack\_directory: /share/oracle/12.1.0/unpacked  
> &nbsp;&nbsp;dbhome\_2:  
> &nbsp;&nbsp;&nbsp;&nbsp;version: 11.2.0  
> &nbsp;&nbsp;&nbsp;&nbsp;path: "{{ oracle\_app\_directory }}/oracle/product/11.2.0/dbhome\_1"  
> &nbsp;&nbsp;&nbsp;&nbsp;installation\_files\_directory: /share/oracle/11.2.0/patches  
> &nbsp;&nbsp;&nbsp;&nbsp;installation\_files:  
> &nbsp;&nbsp;&nbsp;&nbsp;- linuxamd64\_11g\_database\_1of2.zip  
> &nbsp;&nbsp;&nbsp;&nbsp;- linuxamd64\_11g\_database\_2of2.zip  
> &nbsp;&nbsp;&nbsp;&nbsp;unpack\_directory: /share/oracle/11.2.0/unpacked
> 
> I need to loop over the dictionary (oracle\_db\_homes) to unpack the files  
> (installation\_files) for each defined ORACLE\_HOME into a directory  
> (unpack\_directory).
> 
> How can i do that with Ansible ?

[http://docs.ansible.com/playbooks\_loops.html#looping-over-hashes](http://docs.ansible.com/playbooks_loops.html#looping-over-hashes)

should help. For example:

&nbsp;&nbsp;tasks:  
&nbsp;&nbsp;&nbsp;&nbsp;- name: Do clever stuff  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;command: echo {{item.key}}: Oracle version {{item.value.version}} goes into {{item.value.path}}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_dict: oracle\_db\_homes

But your data structure looks a bit odd to me: Does each entry in  
oracle\_db\_homes need to have a name? If not, you can define it as an  
array rather than a dict/hash:

oracle\_db\_homes:  
- version: 12.1.0  
&nbsp;&nbsp;path: "{{oracle\_app\_directory}}/oracle/somewhere/here"  
- version: 11.2.0  
&nbsp;&nbsp;path: "{{oracle\_app\_directory}}/oracle/somewhere/else"

Hope this helps

---

<div class="post-metadata">

**Author:** ![Thomas\_Krahn](https://avatars.discourse-cdn.com/v4/letter/t/958977/32.png) [@Thomas\_Krahn](https://forum.ansible.com/u/Thomas_Krahn)\
**Post date:** [November 19, 2014, 1:25pm UTC](https://forum.ansible.com/t/how-to-loop-over-an-array-inside-a-dictionary/16814/3 "2014-11-19T13:25:05Z")

</div>

Hi Karl,

Thanks for your answer. The name is needed as I need to reference it from another data structure. My problem is really not how to loop over a dict. My problem is the array installation\_files where I need to loop additionally.

I need to unpack the installation files for every home 😉

Thomas

---

<div class="post-metadata">

**Author:** ![James\_Martin1](https://avatars.discourse-cdn.com/v4/letter/j/0ea827/32.png) [@James\_Martin1](https://forum.ansible.com/u/James_Martin1)\
**Post date:** [November 19, 2014, 3:06pm UTC](https://forum.ansible.com/t/how-to-loop-over-an-array-inside-a-dictionary/16814/4 "2014-11-19T15:06:43Z")

</div>

Karl is correct. Your data structure is making things difficult. If you make your datastructure a list of dictionaries, you can use the with\_subelements function, described here: [http://docs.ansible.com/playbooks\_loops.html#looping-over-subelements](http://docs.ansible.com/playbooks_loops.html#looping-over-subelements)

`

- hosts: localhost  
vars:  
oracle\_app\_directory: /app  
oracle\_db\_homes:
- version: 12.1.0  
path: “{{ oracle\_app\_directory }}/oracle/product/12.1.0/dbhome\_1”  
installation\_files\_directory: /share/oracle/12.1.0/patches  
installation\_files:
- linuxamd64\_12c\_database\_1of2.zip
- linuxamd64\_12c\_database\_2of2.zip  
unpack\_directory: /share/oracle/12.1.0/unpacked
- version: 11.2.0  
path: “{{ oracle\_app\_directory }}/oracle/product/11.2.0/dbhome\_1”  
installation\_files\_directory: /share/oracle/11.2.0/patches  
installation\_files:
- linuxamd64\_11g\_database\_1of2.zip
- linuxamd64\_11g\_database\_2of2.zip  
unpack\_directory: /share/oracle/11.2.0/unpacked  
tasks:
- debug: msg=“{{ item.0.version }} – {{ item.1 }}”  
with\_subelements:
- oracle\_db\_homes
- installation\_files

`

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [November 19, 2014, 3:40pm UTC](https://forum.ansible.com/t/how-to-loop-over-an-array-inside-a-dictionary/16814/5 "2014-11-19T15:40:18Z")

</div>

a slight change can make the structure a lot more usable:

oracle\_db\_homes:

- orahome: dbhome\_1  
version: 12.1.0

---

<div class="post-metadata">

**Author:** ![Thomas\_Krahn](https://avatars.discourse-cdn.com/v4/letter/t/958977/32.png) [@Thomas\_Krahn](https://forum.ansible.com/u/Thomas_Krahn)\
**Post date:** [November 19, 2014, 4:28pm UTC](https://forum.ansible.com/t/how-to-loop-over-an-array-inside-a-dictionary/16814/6 "2014-11-19T16:28:34Z")

</div>

Hi James

thanks a lot for you help. My first problem is solved :-).

Let me try to explain why i think i need the “dbhome\_1” and “dbhome\_2”. If one of you guys has a solution for this also than my migration to Ansible can go one.

Second Problem:

I have several databases on one host so i wanted to define another variable like this:

oracle\_databases:  
DB1:  
dbhome: dbhome\_1  
… some other stuff…  
DB2:  
dbhome: dbhome\_1  
DB3:  
dbhome: dbhome\_2

So my idea (like i do it in Puppet) is to use the value of _oracle\_database.dbhome_ to reference to _oracle\_db\_home[dbhome].path_.

Any idea?

---

<div class="post-metadata">

**Author:** ![James\_Martin1](https://avatars.discourse-cdn.com/v4/letter/j/0ea827/32.png) [@James\_Martin1](https://forum.ansible.com/u/James_Martin1)\
**Post date:** [November 19, 2014, 6:06pm UTC](https://forum.ansible.com/t/how-to-loop-over-an-array-inside-a-dictionary/16814/7 "2014-11-19T18:06:50Z")

</div>

I stand corrected, it does seem you can use with\_subelements with a dictionary. The following (on ansible 1.8-devel) will loop through all the installation\_files

`

- hosts: localhost  
vars:  
oracle\_app\_directory: /app  
oracle\_db\_homes:  
DB1:  
path: “{{ oracle\_app\_directory }}/oracle/product/12.1.0/dbhome\_1”  
installation\_files\_directory: /share/oracle/12.1.0/patches  
installation\_files:
- linuxamd64\_12c\_database\_1of2.zip
- linuxamd64\_12c\_database\_2of2.zip  
unpack\_directory: /share/oracle/12.1.0/unpacked  
DB2:  
path: “{{ oracle\_app\_directory }}/oracle/product/11.2.0/dbhome\_1”  
installation\_files\_directory: /share/oracle/11.2.0/patches  
installation\_files:
- linuxamd64\_11g\_database\_1of2.zip
- linuxamd64\_11g\_database\_2of2.zip  
unpack\_directory: /share/oracle/11.2.0/unpacked  
tasks:
- debug: msg=" {{ item.1 }}"  
with\_subelements:
- oracle\_db\_homes
- installation\_files

ansible-playbook -i hosts test.yml |grep msg  
TASK: [debug msg=" {{ item.1 }}“] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
“msg”: " linuxamd64\_12c\_database\_1of2.zip”  
“msg”: " linuxamd64\_12c\_database\_2of2.zip"  
“msg”: " linuxamd64\_11g\_database\_1of2.zip"  
“msg”: " linuxamd64\_11g\_database\_2of2.zip"

`
