Created
February 7, 2024 16:11
-
-
Save dmorozov82/cc9d8a2d0e917fea4974af6e696850ae to your computer and use it in GitHub Desktop.
Build ansible inventory dynamically
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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