# Matching against any nested elements in a variable

**URL:** <https://forum.ansible.com/t/matching-against-any-nested-elements-in-a-variable/13430>\
**Category:** Ansible Project\
**Created:** [September 6, 2013, 9:35pm UTC](https://forum.ansible.com/t/matching-against-any-nested-elements-in-a-variable/13430 "2013-09-06T21:35:45Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kent\_R\_Spillner](https://avatars.discourse-cdn.com/v4/letter/k/ea5d25/32.png) [@Kent\_R\_Spillner](https://forum.ansible.com/u/Kent_R_Spillner)\
**Post date:** [September 6, 2013, 9:35pm UTC](https://forum.ansible.com/t/matching-against-any-nested-elements-in-a-variable/13430/1 "2013-09-06T21:35:45Z")

</div>

I want to use Ansible to install the appropriate RAID controller utility for every server but work in a fairly mixed environment with different vendors and different RAID controllers. I think the best way to handle this is by writing a custom module that provides a raid\_controller\_manufacturer fact, but before I do I wanted to see if it would be possible to just do some fuzzy matching on nested elements in the ansible\_devices fact.

Here's a partial snippet from running setup against a SuperMicro server with an LSI controller:

"ansible\_devices": {  
&nbsp;&nbsp;&nbsp;&nbsp;"sda": {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"host": "RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS 2108 [Liberator] (rev 04)"  
&nbsp;&nbsp;&nbsp;&nbsp;}  
}

Here's a partial snippet from running setup against another SuperMicro with an Adaptec controller:

"ansible\_devices": {  
&nbsp;&nbsp;&nbsp;&nbsp;"sda": {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"host": "RAID bus controller: Adaptec AAC-RAID (rev 09)"  
&nbsp;&nbsp;&nbsp;&nbsp;}  
}

And here's another partial snippet from running setup against an HP with an HP SmartArray controller:

"ansible\_devices": {  
&nbsp;&nbsp;&nbsp;&nbsp;"cciss!c0d0": {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"host": "RAID bus controller: Hewlett-Packard Company Smart Array Controller (rev 04)"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
}

So, long story short is there a way to do something akin to the following:

- name: Install HP SmartArray util  
&nbsp;&nbsp;yum: name=hpacucli state=latest  
&nbsp;&nbsp;when: ansible\_devices.\*.host contains "Hewlett-Packard Company Smart Array Controller"  
- name: Install LSI MegaRaid util  
&nbsp;&nbsp;yum: name=MegaCli state=latest  
&nbsp;&nbsp;when: ansible\_devices.\*.host contains "LSI Logic / Symbios Logic MegaRAID"  
- name: Install Adaptec util  
&nbsp;&nbsp;yum: name=aacraid state=latest  
&nbsp;&nbsp;when: ansible\_devices.\*.host contains "Adaptec AAC-RAID"

---

<div class="post-metadata">

**Author:** ![Serge\_van\_Ginderacht](https://avatars.discourse-cdn.com/v4/letter/s/b782af/32.png) [@Serge\_van\_Ginderacht](https://forum.ansible.com/u/Serge_van_Ginderacht)\
**Post date:** [September 6, 2013, 9:49pm UTC](https://forum.ansible.com/t/matching-against-any-nested-elements-in-a-variable/13430/2 "2013-09-06T21:49:57Z")

</div>

​maybe we should have the values of lspci (and lsusb)​ in setup?

---

<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:** [September 6, 2013, 9:55pm UTC](https://forum.ansible.com/t/matching-against-any-nested-elements-in-a-variable/13430/3 "2013-09-06T21:55:12Z")

</div>

Nothing presently doable as the “when” is more or less a Python expression.

(also this quickly spirals into complicated because you could have more than one raid card)

lspci data quickly bloats setup results, so it seems like a custom fact module may be best here.

---

<div class="post-metadata">

**Author:** ![Kent\_R\_Spillner](https://avatars.discourse-cdn.com/v4/letter/k/ea5d25/32.png) [@Kent\_R\_Spillner](https://forum.ansible.com/u/Kent_R_Spillner)\
**Post date:** [September 6, 2013, 11:20pm UTC](https://forum.ansible.com/t/matching-against-any-nested-elements-in-a-variable/13430/4 "2013-09-06T23:20:02Z")

</div>

> lspci data quickly bloats setup results, so it seems like a custom fact  
> module may be best here.

Cool, thanks Serge and Michael for your responses!

---

<div class="post-metadata">

**Author:** ![Kent\_R\_Spillner](https://avatars.discourse-cdn.com/v4/letter/k/ea5d25/32.png) [@Kent\_R\_Spillner](https://forum.ansible.com/u/Kent_R_Spillner)\
**Post date:** [September 9, 2013, 8:27pm UTC](https://forum.ansible.com/t/matching-against-any-nested-elements-in-a-variable/13430/5 "2013-09-09T20:27:10Z")

</div>

> (also this quickly spirals into complicated because you could have more  
> than one raid card)
> 
> lspci data quickly bloats setup results, so it seems like a custom fact  
> module may be best here.

Is there a way to access facts directly from a Python module?

I wrote the raid\_controller\_facts module today. I'm using the common module boilerplate as described in the docs. Rather than call lspci a second time and parse the output again (the first time being in the setup module) I'm cheating and passing ansible\_devices as an argument to my module:

- name: Gather RAID controller facts  
&nbsp;&nbsp;raid\_controller\_facts:  
&nbsp;&nbsp;&nbsp;&nbsp;devices: "{{ ansible\_devices }}"

And then in the implementation I iterate through module.params["devices"] and check if the host field contains the word RAID.

I've got it all working fine, but ansible\_devices is being converted to a string value before being passed to my module so I use ast.literal\_eval to convert it back to a hash. Besides avoiding the unnecessary conversion to string and back, I have a few servers with Python 2.4.2 so the ast module isn't available, and my module doesn't work on them.

So, long story short, if I could access the ansible\_devices fact directly in my module then I could avoid a little busy work and work on systems with older Python installs.

---

<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:** [September 9, 2013, 11:16pm UTC](https://forum.ansible.com/t/matching-against-any-nested-elements-in-a-variable/13430/6 "2013-09-09T23:16:56Z")

</div>

Nope, you would have to pass them in.

If you are doing complex arguments, when you say " {{ foo }}" you are requesting a string.

This is the _one_ case where the old style var is still useful, to indicate you want a reference, which I still think we need a syntax for.

raid\_controller\_facts:  
devices: $devices

Should work for you.

---

<div class="post-metadata">

**Author:** ![Kent\_R\_Spillner](https://avatars.discourse-cdn.com/v4/letter/k/ea5d25/32.png) [@Kent\_R\_Spillner](https://forum.ansible.com/u/Kent_R_Spillner)\
**Post date:** [September 10, 2013, 4:26pm UTC](https://forum.ansible.com/t/matching-against-any-nested-elements-in-a-variable/13430/7 "2013-09-10T16:26:10Z")

</div>

> This is the \*one\* case where the old style var is still useful, to indicate  
> you want a reference, which I still think we need a syntax for.
> 
> raid\_controller\_facts:  
> &nbsp;&nbsp;&nbsp;devices: $devices
> 
> Should work for you.

Yep, that worked perfectly. Thanks!
