{{tag>Ansible Bash Python Wrapper CA}}
= Ansible inventory script - inventaire dynamique 1
Voir :
* https://goetzrieger.github.io/ansible-tower-advanced/9-advanced-inventories/
* https://docs.ansible.com/ansible/latest/plugins/inventory.html#inventory-plugins
* https://ansible.readthedocs.io/projects/awx/en/24.6.1/userguide/inventories.html#ug-customscripts
Voir aussi :
* https://docs.ansible.com/ansible/latest/reference_appendices/config.html
* https://www.redhat.com/sysadmin/ansible-plugin-inventory-files
* https://github.com/ansible-community/contrib-scripts/blob/main/inventory/ssh_config.py
In Ansible 2.10 and later, inventory scripts moved to their associated collections. Many are now in the [[https://github.com/ansible-community/contrib-scripts/tree/main/inventory|ansible-community/contrib-scripts repository]]. We recommend you use [[https://github.com/ansible-community/contrib-scripts/tree/main/inventory|Inventory plugins]] instead.
Source : https://docs.ansible.com/ansible/latest/inventory_guide/intro_dynamic_inventory.html#intro-dynamic-inventory
Nous allons coder un inventory script en bash en mode "hello world"
Voici le script bash avec des données codés en dures dedans, c'est moche mais c'est juste pour un PoC.
''inv.sh''
#! /bin/bash
set -euo pipefail
IFS=$' \t\n'
export LANG=C
SCRIPT_NAME="$(basename "$0")"
trap 'rm -f "$TMP_INV_INI"' EXIT
TMP_INV_INI="$(mktemp --suffix=_"${SCRIPT_NAME%%.*}".ini)"
mk_ini_tmp_inv() {
cat <<-EOF >"$TMP_INV_INI"
[all:vars]
os = linux
[web]
srv-web1 web=1
srv-web2 web=2
[db]
srv-db1 db=1
srv-db2 db=2
[plop]
test-ansible
EOF
}
arg_list() {
mk_ini_tmp_inv
ansible-inventory -i "$TMP_INV_INI" --list
}
arg_host() {
mk_ini_tmp_inv
ansible-inventory -i "$TMP_INV_INI" --host "$1"
}
usage() {
ansible-doc -t inventory script
}
while [ "${1-}" != "" ]; do
case $1 in
--list ) shift
arg_list
;;
--host ) shift
arg_host "$1"
;;
-h | --help ) usage
exit 0
;;
--) # End of all options
shift
break
;;
-*) echo "SCRIPT_NAME: invalid option" >&2
echo "Try '$SCRIPT_NAME --help' for more information." >&2
exit 1
;;
*)
usage
;;
esac
shift
done
Rendons le script exécutable
chmod +x inv.sh
Nous testons la sortie de notre script bash
./inv.sh --list
{
"_meta": {
"hostvars": {
"srv-db1": {
"db": 1,
"os": "linux"
},
"srv-db2": {
"db": 2,
"os": "linux"
},
"srv-web1": {
"os": "linux",
"web": 1
},
"srv-web2": {
"os": "linux",
"web": 2
},
"test-ansible": {
"os": "linux"
}
}
},
"all": {
"children": [
"db",
"plop",
"ungrouped",
"web"
]
},
"db": {
"hosts": [
"srv-db1",
"srv-db2"
]
},
"plop": {
"hosts": [
"test-ansible"
]
},
"web": {
"hosts": [
"srv-web1",
"srv-web2"
]
}
}
Nous testons de nouveau la sortie de notre script mais pour un host spécifique cette fois
./inv.sh --host srv-web1
{
"os": "linux",
"web": 1
}
A présent testons avec Ansible :
$ ansible -i inv.sh -m ping plop
[WARNING]: * Failed to parse /home/jean/tmp/inv.sh with script plugin: Inventory script (/home/jean/tmp/inv.sh) had an execution error:
[WARNING]: * Failed to parse /home/jean/tmp/inv.sh with ini plugin: /home/jean/tmp/inv.sh:3: Expected key=value host variable assignment, got: -euo
[WARNING]: Unable to parse /home/jean/tmp/inv.sh as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: plop
Ça ne marche pas. Ansible s'attend à trouver un inventaire au format ini et à la place il a du bash.
Les inventory script doivent être en Python. J'ai essayé de renommer ce script inv.sh en inv.py mais ça ne marche pas.
Nous allons coder un wrapper Python qui lance notre script bash.
''inv.py''
#! /usr/bin/env python3
import os
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--list', action='store_true')
parser.add_argument('--host')
args = parser.parse_args()
if args.list:
os.system('bash ./inv.sh --list')
elif args.host:
os.system(f'bash ./inv.sh --host {args.host}')
Rendons ce script Python exécutable
chmod +x inv.py
Et ça marche :
$ ansible -i inv.py -m ping plop
test-ansible | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
== Autres
Voir
Enabled Variable
Retrieve the enabled state from the given dict of host variables. The enabled variable may be specified using dot notation, e.g: 'foo.bar'