I am trying to use the following json file as input to ansible host inventory but I get error when I run the playbook. JSON File:
{ "instances":{ "host": 10.66.70.33 } } Playbook:
hosts: "{{ instances.host }}"
remote_user: root #vars:
When I run the play book I get the following errors. I am not sure where I am doing wrong. I am new to Ansible. Please advice I guess i am doing some silly mistake.
[WARNING]: Could not match supplied host pattern, ignoring: all [WARNING]: provided hosts list is empty, only localhost is available ERROR! The field 'hosts' has an invalid value, which includes an undefined variable. The error was: 'instances' is undefined
I am running the playbook as follows:
ansible-playbook -i <path>/test.json <path>test_playbook.yml 3 Answers
Ansible's yaml plugin will actually parse a JSON file, and has done so for years.
It's barely documented but you can see in the parameters section of the yaml plugin docs, .json is listed as a valid extension.
The JSON format has the same semantics as the YAML format. Note: not the same format as the dynamic inventory!
So your JSON should look like,
{ "instances": { "hosts": { "10.66.70.33": null } } } Note: it's "hosts" rather than "host" and each address is a dictionary/hash key with the values being host-specific vars.
Taking the first example from Working with Inventory docs,
all: hosts: mail.example.com: children: webservers: hosts: foo.example.com: bar.example.com: dbservers: hosts: one.example.com: two.example.com: three.example.com: would look like,
{ "all": { "hosts": { "mail.example.com": null }, "children": { "webservers": { "hosts": { "foo.example.com": null, "bar.example.com": null } }, "dbservers": { "hosts": { "one.example.com": null, "two.example.com": null, "three.example.com": null } } } } } Those nulls are odd-looking but in the YAML example you'll see the trailing colon which does indeed mean each of those hosts are effectively dictionary/hash keys.
For the curious, the JSON-then-YAML loading code is in parsing/utils/yaml.py and the actual parsing is in parsing/inventory/yaml.py.
1It seems pure JSON it's not supported as inventory file. In the inventory plugin list I don't see JSON:
- advanced_host_list - Parses a ‘host list’ with ranges
- auto - Loads and executes an inventory plugin specified in a YAML config
- aws_ec2 - ec2 inventory source
- constructed - Uses Jinja2 to construct vars and groups based on existing inventory.
- host_list - Parses a ‘host list’ string
- ini - Uses an Ansible INI file as inventory source.
- k8s - Kubernetes (K8s) inventory source
- openshift - OpenShift inventory source
- openstack - OpenStack inventory source
- script - Executes an inventory script that returns JSON
- virtualbox - virtualbox inventory source
- yaml - Uses a specifically YAML file as inventory source.
On the other hand you can wrap that JSON in a simple python script as follows:
Make sure the script plugin is enabled in your
ansible.cfgfile:[inventory] enable_plugins = host_list, script, yaml, iniCreate wrapper script (inventory file), only reads your JSON and prints it in the console (I'm assuming the JSON and the wrapper script are in the same path):
#!/usr/bin/env python import os __location__ = os.path.realpath( os.path.join(os.getcwd(), os.path.dirname(__file__))) with open(os.path.join(__location__, "hosts.json")) as f: print f.read()Use the following in your JSON inventory (performance improvements):
{ "_meta": { "hostvars": { } }, "instances": { "hosts": ["10.66.70.33"] } }When running the playbook just be aware the group you want to target should be "instances", for example this is my playbook:
--- - hosts: instances tasks: - debug: msg: Hi there
Then just run the playbook as you did, specifying the python wrapper script, in my case this was:
ansible-playbook -i inventory/hostswrapper.py test-stkovfl.yml Hope it helps!
1late but i hope this could help you !
I took this info from here
Json inventory is almost exactly as Yaml inventory. You should keep in mind these json keys:
- hosts: json array to define your hosts. Notice the plural
- vars: json object to define vars with its values at group level
- children: allows you to define an inner hostgroup
- _meta: to define metadata like host specific variables
for example:
{ "all": { # group called `all` "hosts": ["webmin.mydomain.com"], # hosts that compose `all` group "vars": { # vars for `all` hosts "vendor": "vultr" # var definition called `vendor` }, "children": { # inner group definition "ipc": { # called `ipc` ... "hosts": ["ipc-appserver-01", "ipc-db-01"], # hosts that compose `ipc` group "vars": { # vars only for `ipc` hosts "os": "centos7.6" # var def for `ipc` group called `os` } } # you could define more inner host groups } }, "_meta": { # metadata "hostvars": { "ipc-appserver-01": { # vars only for `ipc-appserver-01` host "role": "php" # var called `role` } } } }