Almacene archivos de inventario ansible en una ubicación remota

Almacene archivos de inventario ansible en una ubicación remota

Estoy tratando de encontrar una manera de almacenar archivos de inventario de Ansible en una ubicación que no sea el espacio local del servidor (digamos, por ejemplo, Azure). ¿Es esto algo que se puede lograr con Ansible Dynamic Inventory? He leído la documentación sobre el inventario dinámico, pero para mí es un poco confuso. Probablemente por falta de conocimiento por mi parte.

En pocas palabras, mi pregunta es: ¿Hay alguna manera de almacenar archivos de inventario de Ansible en una ubicación remota y pedirle a Ansible que los lea desde allí cuando ejecute los libros de estrategias/roles? Si es así, ¿qué es?

Respuesta1

Sí, esto sólo se puede hacer mediante un inventario dinámico. Escribe un script en 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()

La URL que esté codificada o sea una variable de entorno del sistema debe apuntar a un inventario con formato JSON.

Tenga en cuenta que los inventarios dinámicos siempre están en formato JSON y tienen un diseño diferente al de los archivos INI o YAML. Verhttps://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html#developing-inventory-scripts

Luego puedes llamarte ansible-playbook a través de

ansible-playbook -i inventory.py ...

Tenga en cuenta que el script de inventario no debe ser un script de Python. Un script bash también funcionaría. Sólo es necesaria la salida JSON.

#!/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

información relacionada