# Dynamic Inventory Error

**URL:** <https://forum.ansible.com/t/dynamic-inventory-error/20096>\
**Category:** Ansible Project\
**Created:** [December 29, 2015, 10:13pm UTC](https://forum.ansible.com/t/dynamic-inventory-error/20096 "2015-12-29T22:13:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Leon\_Pinkney](https://avatars.discourse-cdn.com/v4/letter/l/cdc98d/32.png) [@Leon\_Pinkney](https://forum.ansible.com/u/Leon_Pinkney)\
**Post date:** [December 29, 2015, 10:13pm UTC](https://forum.ansible.com/t/dynamic-inventory-error/20096/1 "2015-12-29T22:13:08Z")

</div>

Hi All,

I have been using Ansible for a few months now and have started to create some custom python scripts to enable me to implement tasks I haven’t otherwise been able to do within standard playbooks.

My inventory file is starting to grow and since all of the information in it is currently available from a DB, I started to look at dynamic inventory.

I wanted to start by understanding the JSON required to build an inventory, so came up with the following code in an effort to understand it. I realise that this is not a complete solution, it is purely for me to understand the required format of the data.

`  
inv = {  
“company”: {  
“hosts”: [  
“server”,  
“sensor”  
]  
},  
“\_meta”: {  
“hostvars”: {  
“server”: {  
“ansible\_ssh\_host” : “7.7.7.7”,  
“ansible\_ssh\_port” : “44”  
},  
“sensor”: {  
“ansible\_ssh\_host” : “7.7.7.7”,  
“ansible\_ssh\_port” : “33”  
}  
}  
}  
}  
inv = json.dumps(inv)

inventory = ansible.inventory.Inventory(inv)  
`

If I print inv, it comes out like so…

{“company”: {“hosts”: [“server”, “sensor”]}, “\_meta”: {“hostvars”: {“sensor”: {“ansible\_ssh\_host”: “7.7.7.7”, “ansible\_ssh\_port”: “44”}, “server”: {“ansible\_ssh\_host”: “7.7.7.7”, “ansible\_ssh\_port”: “33”}}}}

When I execute this code however, I get the following error.

Traceback (most recent call last):  
File “test\_inventory.py”, line 33, in   
inventory = ansible.inventory.Inventory(inv)  
File “/usr/local/lib/python2.7/dist-packages/ansible/inventory/ **init**.py”, line 93, in **init**  
all.add\_host(Host(tokens[0], tokens[1]))  
File “/usr/local/lib/python2.7/dist-packages/ansible/inventory/host.py”, line 32, in **init**  
self.set\_variable(‘ansible\_ssh\_port’, int(port))  
ValueError: invalid literal for int() with base 10: ‘“22”}’

I’ve tried removing the string quotes from the port number, but the problem persists. If I remove the ansible\_ssh\_port lines, I get no errors.

Can anyone offer any advice? I’m current running Ansible version 1.9.4 which I understand is the latest.

Thanks!

---

<div class="post-metadata">

**Author:** ![sivel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/sivel/32/1198_2.png) [@sivel](https://forum.ansible.com/u/sivel)\
**Post date:** [December 29, 2015, 10:44pm UTC](https://forum.ansible.com/t/dynamic-inventory-error/20096/2 "2015-12-29T22:44:56Z")

</div>

You cannot provide dynamic inventory JSON output, that would normally come from a script, directly to the Inventory class. The first argument for Inventory is the `host_list`, which can be 1 of 3 things:

1. Path to ini formatted inventory file
2. Path to executable dynamic inventory script
3. Comma separated hosts list that looks like “foo,bar,baz” or at minimum “foo,” with a trailing comma

Because your JSON has a comma in it, it get’s split, and then we try to loop through and split things out. At this point Ansible believes it finds a host called “ansible\_ssh\_host” with a port of “22” (including the quotes).

I have done what you are trying to do before, which required subclassing `Inventory` and overriding `parse_inventory` and subclassing `InventoryScript` and overriding ` __init__ ` and `get_host_variables` in order to allow my new classes to just accept a JSON string like you are trying to do.

In the end, it is just easier, using a callable script, and passing that to `Inventory`. So, basically move the `inv` assignment and do `print json.dumps(inv)` in a single script, and provide the path to that script to `ansible.inventory.Inventory`.

---

<div class="post-metadata">

**Author:** ![Leon\_Pinkney](https://avatars.discourse-cdn.com/v4/letter/l/cdc98d/32.png) [@Leon\_Pinkney](https://forum.ansible.com/u/Leon_Pinkney)\
**Post date:** [December 29, 2015, 10:45pm UTC](https://forum.ansible.com/t/dynamic-inventory-error/20096/3 "2015-12-29T22:45:47Z")

</div>

Just to add, if I change the line to:  
“ansible\_ssh\_port” : 22

I get:  
ValueError: invalid literal for int() with base 10: ‘22}’

I edited “/usr/local/lib/python2.7/dist-packages/ansible/inventory/host.py” and before line 32 added:  
print ‘\>\>’ + port + ‘\<\<’

Which outputs:

> > 22}\<\<

Clearly, the information isn’t being parsed correctly. Is it my code, or a bug?

---

<div class="post-metadata">

**Author:** ![pixel\_fairy](https://avatars.discourse-cdn.com/v4/letter/p/6f9a4e/32.png) [@pixel\_fairy](https://forum.ansible.com/u/pixel_fairy)\
**Post date:** [January 5, 2016, 4:51pm UTC](https://forum.ansible.com/t/dynamic-inventory-error/20096/4 "2016-01-05T16:51:50Z")

</div>

If your just trying to get the syntax of the json right, there are easier ways to test. heres the above as an inventory script.

`  
#!/usr/bin/env python  
import json

inv = {  
“company”: {  
“hosts”: [  
“server”,  
“sensor”  
]  
},  
“\_meta”: {  
“hostvars”: {  
“server”: {  
“ansible\_ssh\_host” : “7.7.7.7”,  
“ansible\_ssh\_port” : 44  
},  
“sensor”: {  
“ansible\_ssh\_host” : “7.7.7.7”,  
“ansible\_ssh\_port” : “33”  
}  
}  
}  
}

print(json.dumps(inv))

`

heres the output of some test commands with (with ansible 2.0rc8, but it should work the same with 1.9x)

`  
$ ansible -i leon.py all --list-hosts  
hosts (2):  
server  
sensor  
$ ansible -i leon.py sensor -m debug -a var=vars  
sensor | SUCCESS =\> {  
“vars”: {  
“ansible\_ssh\_host”: “7.7.7.7”,  
“ansible\_ssh\_port”: “33”,  
“group\_names”: [  
“company”  
],  
“inventory\_hostname”: “sensor”,  
“inventory\_hostname\_short”: “sensor”  
}  
}

`
