# Passing nested arguments to a module

**URL:** <https://forum.ansible.com/t/passing-nested-arguments-to-a-module/14102>\
**Category:** Ansible Project\
**Created:** [December 9, 2013, 10:18am UTC](https://forum.ansible.com/t/passing-nested-arguments-to-a-module/14102 "2013-12-09T10:18:20Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Giorgio\_Valoti](https://avatars.discourse-cdn.com/v4/letter/g/a88e57/32.png) [@Giorgio\_Valoti](https://forum.ansible.com/u/Giorgio_Valoti)\
**Post date:** [December 9, 2013, 10:18am UTC](https://forum.ansible.com/t/passing-nested-arguments-to-a-module/14102/1 "2013-12-09T10:18:20Z")

</div>

Hi,  
I’m trying to extend the ZFS module to add support for user properties.

My plan was to add a new module argument, called (guess what)  
`user_properties` which accepts a list of dictionaries:

[{key: 'my.module.name:key-name', value: 'whatever'}, ...]

However, I get this error message:

> msg: this module requires key=value arguments

Even though I can pass an empty list or a list with string items, like  
['a', 'b', 'c'].

Is there a way to do this?

Thank you.

---

<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:** [December 9, 2013, 1:57pm UTC](https://forum.ansible.com/t/passing-nested-arguments-to-a-module/14102/2 "2013-12-09T13:57:18Z")

</div>

(This is really a question for ansible-devel list)

In the argument\_spec of the module that defines the argument, just do

type=‘dict’

It will accept complex arguments as well as quoted key=value pairs.

module\_name:  
foo:  
x: 1  
y: “bar”  
baz: “glorp”

Is how complex args are passed

Or

module\_name: ‘foo=“x=1 y=bar” baz=“glorp”’

This is exactly how the ec2 module in 1.4/1.5 processes and passes instance tags, if you want to take a look.

It also knows how to parse inline JSON, so it is very much a “do what you mean” kind of input.

---

<div class="post-metadata">

**Author:** ![Giorgio\_Valoti](https://avatars.discourse-cdn.com/v4/letter/g/a88e57/32.png) [@Giorgio\_Valoti](https://forum.ansible.com/u/Giorgio_Valoti)\
**Post date:** [December 9, 2013, 4:03pm UTC](https://forum.ansible.com/t/passing-nested-arguments-to-a-module/14102/3 "2013-12-09T16:03:39Z")

</div>

Michael DeHaan \<michael@ansibleworks.com\> writes:

> (This is really a question for ansible-devel list)

Thank you for pointing it out, I wasn’t sure about that.

> In the argument\_spec of the module that defines the argument, just do
> 
> type='dict'
> 
> It will accept complex arguments as well as quoted key=value pairs.
> 
> module\_name:  
> &nbsp;&nbsp;foo:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x: 1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y: "bar"  
> &nbsp;&nbsp;baz: "glorp"
> 
> Is how complex args are passed
> 
> Or
> 
> module\_name: 'foo="x=1 y=bar" baz="glorp"'
> 
> This is exactly how the ec2 module in 1.4/1.5 processes and passes instance  
> tags, if you want to take a look.
> 
> It also knows how to parse inline JSON, so it is very much a "do what you  
> mean" kind of input.

Super. Thanks a lot.

---

<div class="post-metadata">

**Author:** ![Giorgio\_Valoti](https://avatars.discourse-cdn.com/v4/letter/g/a88e57/32.png) [@Giorgio\_Valoti](https://forum.ansible.com/u/Giorgio_Valoti)\
**Post date:** [December 10, 2013, 7:28am UTC](https://forum.ansible.com/t/passing-nested-arguments-to-a-module/14102/4 "2013-12-10T07:28:52Z")

</div>

Michael DeHaan \<michael@ansibleworks.com\> writes:

> In the argument\_spec of the module that defines the argument, just do
> 
> type='dict'
> 
> It will accept complex arguments as well as quoted key=value pairs.
> 
> module\_name:  
> &nbsp;&nbsp;foo:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x: 1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y: "bar"  
> &nbsp;&nbsp;baz: "glorp"
> 
> Is how complex args are passed
> 
> Or
> 
> module\_name: 'foo="x=1 y=bar" baz="glorp"'
> 
> This is exactly how the ec2 module in 1.4/1.5 processes and passes instance  
> tags, if you want to take a look.
> 
> It also knows how to parse inline JSON, so it is very much a "do what you  
> mean" kind of input.

It works perfectly with a single item:

zfs:  
&nbsp;&nbsp;&nbsp;state: present  
&nbsp;&nbsp;&nbsp;name: ...  
&nbsp;&nbsp;&nbsp;...  
&nbsp;&nbsp;&nbsp;user\_properties:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k: v  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...

But I can’t find a way to iterate over it. Ideally, I’d like to write  
something like:

zfs: {{ item }}  
with\_items: [{name: 'x', state: 'present', user\_properties: {...}},  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{name: 'y', state: 'present', mountpoint: '/path/to/mnt', ...} ]

When the property keys are variable but properties are all strings I can  
write something like this:

module\_name: state={{ item.state }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name={{ item.name }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ 'prop=%s' % item.prop if item.prop is defined else '' }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...

I don’t like it, it’s verbose, and there’s probably a better way to do  
it, but it works, if only with simple properties.

So my question becames how to iterate over a list of dictionaries,  
possibily nested, with different keys?

Thanks a lot.

---

<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:** [December 10, 2013, 4:49pm UTC](https://forum.ansible.com/t/passing-nested-arguments-to-a-module/14102/5 "2013-12-10T16:49:41Z")

</div>

You can definitely pass in with\_items with a list of hashes.

module\_name: foo={{ [item.name](http://item.name) }} bar={{ item.value }}  
with\_items:

- { name: ‘x’, value: ‘y’ }
- { name: ‘a’, value: ‘b’ }

etc

or with\_items: alist\_of\_hashes

etc

or as you have it, with

with\_items: [{ name: ‘x’, value: ‘y’ }, { name: ‘a’, value: ‘b’ }]

It seems like in your question instead of

zfs: {{ item }}

you might need to pass something more specific?

zfs: {{ item.zfs }}

??

am I misunderstanding the question ?

---

<div class="post-metadata">

**Author:** ![Giorgio\_Valoti](https://avatars.discourse-cdn.com/v4/letter/g/a88e57/32.png) [@Giorgio\_Valoti](https://forum.ansible.com/u/Giorgio_Valoti)\
**Post date:** [December 10, 2013, 5:47pm UTC](https://forum.ansible.com/t/passing-nested-arguments-to-a-module/14102/6 "2013-12-10T17:47:04Z")

</div>

Michael DeHaan \<michael@ansibleworks.com\> writes:

> You can definitely pass in with\_items with a list of hashes.
> 
> module\_name: foo={{ item.name }} bar={{ item.value }}  
> with\_items:  
> &nbsp;&nbsp;&nbsp;- { name: 'x', value: 'y' }  
> &nbsp;&nbsp;&nbsp;- { name: 'a', value: 'b' }
> 
> etc
> 
> or with\_items: alist\_of\_hashes
> 
> etc
> 
> or as you have it, with
> 
> with\_items: [{ name: 'x', value: 'y' }, { name: 'a', value: 'b' }]
> 
> It seems like in your question instead of
> 
> zfs: {{ item }}
> 
> you might need to pass something more specific?
> 
> zfs: {{ item.zfs }}
> 
> ??
> 
> am I misunderstanding the question ?

Maybe or, more probably, I can’t explain myself. 🙂

Starting from your example, let’s add an attribute only in the second item:

module\_name: foo={{ item.name }} bar={{ item.value }}  
with\_items:  
&nbsp;&nbsp;&nbsp;- { name: 'x', value: 'y' }  
&nbsp;&nbsp;&nbsp;- { name: 'a', value: 'b', extra: 'xtr' }

How should deal with it? Is adding

{{ 'extra=%s' % item.extra if item.extra is defined else '' }}

the preferred way?

Now let’s say that `extra` is a map:

module\_name: foo={{ item.name }} bar={{ item.value }}  
with\_items:  
&nbsp;&nbsp;&nbsp;- { name: 'x', value: 'y' }  
&nbsp;&nbsp;&nbsp;- { name: 'a', value: 'b', extra: {k: 'v'} }

If I use the `defined` check shown above the module gets a string, I  
believe.

I hope I didn’t mess up too much my argument 🙂

---

<div class="post-metadata">

**Author:** ![Giorgio\_Valoti](https://avatars.discourse-cdn.com/v4/letter/g/a88e57/32.png) [@Giorgio\_Valoti](https://forum.ansible.com/u/Giorgio_Valoti)\
**Post date:** [December 11, 2013, 6:05pm UTC](https://forum.ansible.com/t/passing-nested-arguments-to-a-module/14102/7 "2013-12-11T18:05:35Z")

</div>

Giorgio Valoti \<giorgio\_v@me.com\> writes:

> Michael DeHaan \<michael@ansibleworks.com\> writes:
> 
> > am I misunderstanding the question ?
> 
> Maybe or, more probably, I can’t explain myself. 🙂

Well, I guess I really can’t explain myself! 😃 No suggestions on this?

Thank you in advance.
