Ansible-Inventardateien an einem Remotestandort speichern

Ansible-Inventardateien an einem Remotestandort speichern

Ich versuche, eine Möglichkeit zu finden, Ansible-Inventardateien an einem anderen Ort als dem lokalen Speicherplatz des Servers (zum Beispiel Azure) zu speichern. Ist dies mit Ansible Dynamic Inventory möglich? Ich habe die Dokumentation zum dynamischen Inventar gelesen, aber für mich ist sie etwas verwirrend. Wahrscheinlich aufgrund mangelnden Wissens meinerseits.

Meine Frage ist also, vereinfacht ausgedrückt: Gibt es eine Möglichkeit, Ansible-Inventardateien an einem Remote-Speicherort zu speichern und Ansible aufzufordern, sie von dort aus zu lesen, wenn die Playbooks/Rollen ausgeführt werden? Wenn ja, welche Möglichkeit gibt es?

Antwort1

Ja, dies ist nur über eine dynamische Bestandsaufnahme möglich. Schreiben Sie ein Python-Skript wie:

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

Die URL, die entweder fest codiert ist oder eine Systemumgebungsvariable darstellt, sollte auf ein Inventar im JSON-Format verweisen.

Beachten Sie: Dynamische Inventare sind immer im JSON-Format und haben ein anderes Layout als INI- oder YAML-Dateien. Siehehttps://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html#developing-inventory-scripts

Sie können Ihr Ansible-Playbook dann über

ansible-playbook -i inventory.py ...

Beachten Sie: Das Inventarskript darf kein Python-Skript sein. Ein Bash-Skript würde auch funktionieren. Nur die JSON-Ausgabe ist erforderlich.

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

verwandte Informationen