Estou tentando encontrar uma maneira de armazenar arquivos de inventário Ansible em um local diferente do espaço local do servidor (digamos, por exemplo, Azure). Isso é algo que pode ser alcançado pelo Ansible Dynamic Inventory? Eu li a documentação sobre inventário dinâmico, mas para mim é um pouco confuso. Provavelmente por falta de conhecimento da minha parte.
Simplesmente falando, minha pergunta é: existe uma maneira de armazenar arquivos de inventário ansible em um local remoto e pedir ao ansible para lê-los de lá ao executar os playbooks/funções? Se assim for, o que é?
Responder1
Sim, isso só pode ser feito através de um inventário dinâmico. Escreva um script python como:
#!/usr/bin/env python
import os
import sys
import argparse
import json
import requests
class MyInventory(object):
def __init__(self):
self.inventory = {}
self.read_cli_args()
# Called with `--list`.
if self.args.list:
self.inventory = self.my_inventory()
# Called with `--host [hostname]`.
elif self.args.host:
# Not implemented, since we return _meta info `--list`.
self.inventory = self.host_inventory(self.args.host)
# If no groups or vars are present, return an empty inventory.
else:
self.inventory = self.empty_inventory('no args')
print(json.dumps(self.inventory, indent=2, sort_keys=True))
def my_inventory(self):
try:
if "INVENTORY_ENDPOINT" in os.environ:
url = os.environ.get('INVENTORY_ENDPOINT')
else:
url = 'https://myserver/inventory'
if "INVENTORY_USERNAME" in os.environ:
username = os.environ.get('INVENTORY_USERNAME')
else:
return self.empty_inventory('environment-variable INVENTORY_USERNAME not set')
if "INVENTORY_PASSWORD" in os.environ:
password = os.environ.get('INVENTORY_PASSWORD')
else:
return self.empty_inventory('environment-variable INVENTORY_PASSWORD not set')
headers = {
'Accept': 'application/json',
'User-Agent': 'dynamic-inventory-script/v1.0',
'Connection': 'close'
}
result = requests.get(url, timeout=5, auth=(username,password), headers=headers)
result.encoding = 'utf-8'
return json.loads(result.text)
except:
return {}
# Host inventory for testing.
def host_inventory(self, hostname):
return {
'_meta': {
'hostvars': {}
}
}
# Empty inventory for testing.
def empty_inventory(self,message):
return {
'_meta': {
'hostvars': {
'mesage': message
}
}
}
# Read the command line args passed to the script.
def read_cli_args(self):
parser = argparse.ArgumentParser()
parser.add_argument('--list', action = 'store_true')
parser.add_argument('--host', action = 'store')
self.args = parser.parse_args()
# Get the inventory.
MyInventory()
A URL que está codificada ou é uma variável de ambiente do sistema deve apontar para um inventário formatado em JSON.
Esteja ciente: os inventários dinâmicos estão sempre no formato JSON e têm um layout diferente dos arquivos INI ou YAML. Verhttps://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html#developing-inventory-scripts
Você pode então chamá-lo de ansible-playbook via
ansible-playbook -i inventory.py ...
Esteja ciente: o script de inventário não deve ser um script python. Um script bash também funcionaria. Somente a saída JSON é necessária.
#!/bin/sh
if [ -z "$INVENTORY_USERNAME" ]; then
echo "{}"
exit 0
fi
if [ -z "$INVENTORY_ENDPOINT" ]; then
INVENTORY_ENDPOINT="https://myserver/inventory"
fi
curl -s GET "$INVENTORY_ENDPOINT" -H "accept: application/json" --user $INVENTORY_USERNAME:$INVENTORY_PASSWORD &> /dev/stdout
#eof