Armazene arquivos de inventário ansible em um local remoto

Armazene arquivos de inventário ansible em um local remoto

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

informação relacionada