Ansible 인벤토리 파일을 원격 위치에 저장

Ansible 인벤토리 파일을 원격 위치에 저장

서버의 로컬 공간(예: Azure)이 아닌 위치에 Ansible 인벤토리 파일을 저장하는 방법을 찾으려고 합니다. 이것이 Ansible Dynamic Inventory로 달성할 수 있는 것입니까? 동적 인벤토리에 대한 문서를 읽었지만 제게는 약간 혼란스럽습니다. 아마도 내 쪽의 지식이 부족해서일 것이다.

간단히 말해서 제 질문은 다음과 같습니다. Ansible 인벤토리 파일을 원격 위치에 저장하고 플레이북/역할을 실행할 때 Ansible에서 해당 파일을 읽도록 요청할 수 있는 방법이 있습니까? 그렇다면 무엇입니까?

답변1

예, 이는 동적 인벤토리를 통해서만 수행할 수 있습니다. 다음과 같은 Python 스크립트를 작성합니다.

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

하드코딩된 URL 또는 시스템 환경 변수는 JSON 형식 인벤토리를 가리켜야 합니다.

주의하세요. 동적 인벤토리는 항상 JSON 형식이며 INI 또는 YAML 파일과 다른 레이아웃을 갖습니다. 보다https://docs.ansible.com/ansible/latest/dev_guide/developing_inventory.html#developing-inventory-scripts

다음을 통해 ansible-playbook을 호출할 수 있습니다.

ansible-playbook -i inventory.py ...

주의하세요. 인벤토리 스크립트는 Python 스크립트가 아니어야 합니다. Bash 스크립트도 작동합니다. 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

관련 정보