ansible.builtin.script inventory – Executes an inventory script that returns JSON
Note
This inventory plugin is part of ansible-core
and included in all Ansible installations. In most cases, you can use the short plugin name script
. However, we recommend you use the Fully Qualified Collection Name (FQCN) ansible.builtin.script
for easy linking to the plugin documentation and to avoid conflicting with other collections that may have the same inventory plugin name.
Synopsis
- The source provided must be an executable that returns Ansible inventory JSON
- The source must accept
--list
and--host <hostname>
as arguments.--host
will only be used if no_meta
key is present. This is a performance optimization as the script would be called one additional time per host otherwise.
Parameters
Parameter | Comments |
---|---|
always_show_stderr boolean | Toggle display of stderr even when script was successful Choices:
Configuration:
|
Notes
Note
- Enabled in configuration by default.
- The plugin does not cache results because external inventory scripts are responsible for their own caching.
- To write your own inventory script see (Developing dynamic inventory from the documentation site.
- To find the scripts that used to be part of the code release, go to https://github.com/ansible-community/contrib-scripts/.
Examples
# fmt: code ### simple bash script #!/usr/bin/env bash if [ "$1" == "--list" ]; then cat<<EOF { "bash_hosts": { "hosts": [ "myhost.domain.com", "myhost2.domain.com" ], "vars": { "host_test": "test-value" } }, "_meta": { "hostvars": { "myhost.domain.com": { "host_specific_test_var": "test-value" } } } } EOF elif [ "$1" == "--host" ]; then # this should not normally be called by Ansible as we return _meta above if [ "$2" == "myhost.domain.com" ]; then echo '{"_meta": {hostvars": {"myhost.domain.com": {"host_specific-test_var": "test-value"}}}}' else echo '{"_meta": {hostvars": {}}}' fi else echo "Invalid option: use --list or --host <hostname>" exit 1 fi ### python example with ini config #!/usr/bin/env python """ # ansible_inventory.py """ import argparse import json import os.path import sys from configparser import ConfigParser from inventories.custom import MyInventoryAPI def load_config() -> ConfigParser: cp = ConfigParser() config_file = os.path.expanduser("~/.config/ansible_inventory_script.cfg") cp.read(config_file) if not cp.has_option('DEFAULT', 'namespace'): raise ValueError("Missing configuration option: DEFAULT -> namespace") return cp def get_api_data(namespace: str, pretty=False) -> str: """ :param namespace: parameter for our custom api :param pretty: Human redable JSON vs machine readable :return: JSON string """ found_data = list(MyInventoryAPI(namespace)) hostvars = {} data = { '_meta': { 'hostvars': {}},} groups = found_data['groups'].keys() for group in groups: groups[group]['hosts'] = found_data[groups].get('host_list', []) if group not in data: data[group] = {} data[group]['hosts'] = found_data[groups].get('host_list', []) data[group]['vars'] = found_data[groups].get('info', []) data[group]['children'] = found_data[group].get('subgroups', []) for host_data in found_data['hosts']: for name in host_data.items(): # turn info into vars data['_meta'][name] = found_data[name].get('info', {}) # set ansible_host if possible if 'address' in found_data[name]: data[name]['_meta']['ansible_host'] = found_data[name]['address'] data['_meta']['hostvars'] = hostvars return json.dumps(data, indent=pretty) if __name__ == '__main__': arg_parser = argparse.ArgumentParser( description=__doc__, prog=__file__) arg_parser.add_argument('--pretty', action='store_true', default=False, help="Pretty JSON") mandatory_options = arg_parser.add_mutually_exclusive_group() mandatory_options.add_argument('--list', action='store', nargs="*", help="Get inventory JSON from our API") mandatory_options.add_argument('--host', action='store', help="Get variables for specific host, not used but kept for compatability") try: config = load_config() namespace = config.get('DEFAULT', 'namespace') args = arg_parser.parse_args() if args.host: print('{"_meta":{}}') sys.stderr.write('This script already provides _meta via --list, so this option is really ignored') elif len(args.list) >= 0: print(get_api_data(namespace, args.pretty)) else: raise ValueError("Valid options are --list or --host <HOSTNAME>") except ValueError: raise
Hint
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
Collection links
© 2012–2018 Michael DeHaan
© 2018–2024 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/script_inventory.html