Skip to content

Instantly share code, notes, and snippets.

@dmorozov82
Created February 7, 2024 16:11
Show Gist options
  • Save dmorozov82/cc9d8a2d0e917fea4974af6e696850ae to your computer and use it in GitHub Desktop.
Save dmorozov82/cc9d8a2d0e917fea4974af6e696850ae to your computer and use it in GitHub Desktop.
Build ansible inventory dynamically
#!/usr/bin/env python
"""
This is an example script for implementing dynamic inventory in Ansible.
It could have been written in bash, but python is much easier to read.
"""
import argparse
import json
# Example hosts store
store = {
"postgres-1": {
"metadatafromstore": {
"ip": ['172.16.1.1'],
'discs': ['/dev/vda', '/dev/sda'],
'users': ['grey'],
'mounts': {
"/": '/dev/vda',
"/opt/postgres/data": "/dev/sda",
},
}
},
"apache": {
"metadatafromstore": {
"ip": ['172.16.1.3'],
'discs': ['/dev/vda'],
'mounts': {
"/": '/dev/vda',
},
}
},
}
def get_host_vars(host):
data = {
'ansible_host': host,
'ansible_user': 'root',
}
if host in store:
metadata = store[host].get('metadatafromstore', {}) or {}
if metadata.get('ip'):
data['ansible_host'] = metadata['ip'][0]
if 'users' in metadata:
data['ansible_user'] = metadata['users'][0]
data.update(metadata)
return data
def get_vars(host, pretty=False):
"""
Function which return json data of host's variables.
"""
return json.dumps({}, indent=pretty)
def get_list(pretty=False):
"""
Function which return inventory data for hosts.
Example contains all variants of groups. Syntax as yaml inventory but with '_meta' section.
- 'hostvars' is all variables for hosts.
- 'all' is default group which should be always created.
- 'ungrouped' is testing group with hosts.
"""
hostvars, ungrouped = {}, []
for host in store:
ungrouped.append(host)
hostvars[host] = get_host_vars(host)
data = {
'_meta': {
'hostvars': hostvars
},
'all': {
'children': [
'ungrouped'
]
},
'ungrouped': {
'hosts': ungrouped
}
}
return json.dumps(data, indent=pretty)
# Parse arguments.
# Ansible require two: '--list' and output of all data and '--host [hostname] for getting variables about one host'
parser = argparse.ArgumentParser()
parser.add_argument(
'--pretty',
action='store_true',
default=False,
help="Pretty print JSON"
)
parser.add_argument(
"--list",
action='store', # also better use store_true
nargs="*",
default="dummy",
help="Show JSON of all managed hosts"
)
parser.add_argument(
"--host",
action='store',
help="Display vars related to the host"
)
args = parser.parse_args()
# Print output will be parsed via ansible as inventory (like a file).
if args.host:
print(get_vars(args.host, args.pretty))
elif len(args.list) >= 0:
print(get_list(args.pretty))
else:
raise ValueError("Expecting either --host $HOSTNAME or --list")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment