bundyboy
bundyboy

Reputation: 13

produce a YAML ansible inventory in python

I would like to write a YAML ansible inventory file from a python script. It seems that the expected format from ansible is with key pairs only, with a colon at the end of each host et no - in front such as:

pe:
  hosts:
      host1:
      host2:
      host3:
      host4:

I created a structure in python like this:

inventory_struct = {
    'pe': {
        'hosts': [],
    },
}

and I am adding hosts in the 'hosts' list. But when I write the inventory file with:

yaml.dump(inventory_struct, outfile, default_flow_style=False, allow_unicode=True)

I get this format which ansible does not recognize:

pe:
   -hosts:
    - host1
    - host2
    - host3

Error message when I run the playbook on this inventory:

Attempted to read "../inventories/inv-xyz555" as YAML: list indices must be integers, not AnsibleUnicode

Is there a way to dump the structure in the expected YAML format?

Thanks,

bundyboy

Upvotes: 1

Views: 4955

Answers (4)

theTuxRacer
theTuxRacer

Reputation: 13869

You can do something similar to

import yaml

def inventory():

  ip_list = {}
  ip_list['10.25.152.200'] = None
  ip_list['10.25.152.201'] = None

  inventory = dict(all = dict (
    children = dict(
      qa = dict(
        hosts = ip_list,
        vars = dict(
            ansible_ssh_user = 'foo',
            ansible_ssh_pass = 'bar'
          )
        )
      )
    )
  )

  return inventory

def main():
  with open('/tmp/inventory.yml', 'w') as outfile:
    yaml.dump(inventory(), outfile, default_flow_style=False)

if __name__ == "__main__":
    main()

Upvotes: 1

Traq
Traq

Reputation: 16

Just use replace to get rid of null string. For example: print(yaml.dump(inventory_struct, default_flow_style=False).replace('null', ''))

Upvotes: 0

shevron
shevron

Reputation: 3663

This is mostly about getting your Python dictionary right, not about YAML. YAML represents list items as values with a - prefix and object (dictionary) keys as strings with a : after them.

I think what you're looking for is something like this:

inventory_struct = {
    'pe': {
        'hosts': {
            'host1': '',
            'host2': '',
            'host3': '',
        },
    },
}

Upvotes: 0

bundyboy
bundyboy

Reputation: 13

I replaced the hosts list by a hosts dictionary with my hosts as keys and None as value, seems to do the trick. I get an Inventory file that looks like this:

pe:
  hosts:
    host1: null
    host2: null
    host2: null

Ansible does not seem to complain about the null.

Upvotes: 0

Related Questions