Proxmox PVE Pool als dynamisches Ansible Inventory nutzen

Ansible 17. Sep. 2021

Ich nutze nun seit einem Jahr Ansible um meine virtuellen Maschinen und LXC Container auf dem Laufenden zu halten. Für die Updates läuft auf meiner Ansible Maschine ein cron Job welcher alle 24 Stunden ausgeführt wird und ein Ansible Playbook ausführt, welches per APT die Hosts auf den neuesten Stand bringt. Damit ich jedoch nicht immer manuell das Inventory Datei pflegen muss, sobald sich etwas an meiner VM/LXC Flotte ändert, habe ich mir ein kleines Script-Triell gebaut, welches einen Proxmox Pool als Inventory nutzt.

Der besagte leider nicht beheizte und auch ohne Whirl-Pool

Das Triell besteht aus drei Scripts

  1. Python: get-ansible_ubuntu-pool-members.py
  2. Ansible Playbook: update-ansible_ubuntu-pool.yml
  3. Bash: update-ansible_ubuntu-pool.sh

Python: get-ansible_ubuntu-pool-members.py

# get-ansible_ubuntu-pool-members.py
## Needed modules
# pip install proxmoxer
# pip install requests
# pip install python-dotenv
# pip install numpy

## Needed access rights for proxmox user
# PVEAuditor

from dotenv import load_dotenv
import numpy as np
import os

load_dotenv()

PROXMOX_HOST = os.getenv('PROXMOX_HOST')
PROXMOX_USER = os.getenv('PROXMOX_USER')
PROXMOX_PASSWORD = os.getenv('PROXMOX_PASSWORD')

vm_array = ['[ansible_ubuntu]'] # here you can add static entries
pool = 'ansible_ubuntu'

from proxmoxer import ProxmoxAPI
proxmox = ProxmoxAPI(host=PROXMOX_HOST, user=PROXMOX_USER, password=PROXMOX_PASSWORD, verify_ssl=False)

for vm in proxmox.cluster.resources.get(type='vm'):
    if vm.get('pool') == pool and vm.get('status') == 'running':
        vm_array.append(vm['name'])

print(vm_array)
np.savetxt("inventory.txt", vm_array, fmt="%s")

Dieses kleine Pythonskript verbindet sich bei jeder Ausführung einmal mit meinem Proxmox PVE Host per API und holt sich die Namen aller Hosts in einem im Skript definierten Pool und erstellt eine „Inventory.txt“ Datei aus den Informationen:

[ansible_ubuntu]
dns01ubuntu
teamspeak01debian
pbs
ansible02ubuntu
gitlab01ubuntu
docker01ubuntu
omv01

Wie hier vielleicht schon zu erahnen ist, ergeben sich aus dieser Methode des Inventory Datei generieren ein paar Limitationen und Voraussetzungen, wenn du dieses Skript nutzen möchtest:

  • Deine Hosts müssen über den in Proxmox eingetragenen Namen erreichbar sein, heißt dieser muss gleich sein mit dem DNS Namen.
  • Dazu muss dein DNS-Server so eingestellt sein, dass dieser auch Namen auflöst ohne Domain-Suffix. Falls du dir nicht sicher bist, pingt einen deiner Hosts ohne Domain-Suffix an und schau, ob es funktioniert. Dabei muss z.B. "ping dns01ubuntu"  genauso funktionieren wie "ping dns01ubuntu.fritz.box". Falls du dnsmasq nutzen solltet, muss in deiner Konfiguration "domain-needed" auskommentiert werden.
# Never forward plain names (without a dot or domain part)
# domain-needed
  • Zudem muss die SSH Verbindung zu deinen Hosts bereits ohne Angeben eines extra Keys funktionieren. d.H. in meinem Beispiel muss „ssh [email protected]“ funktionieren, ohne dass ich ein Passwort oder ein extra Key angeben muss.
  • Für jeden deiner Hosts musst du den gleichen (sudo fähigen) User nutzen, in meinem Fall ist es der Ubuntu Nutzer. Solltest du für all deine Maschinen einen Usernamen nutzen, so musst du diesen in dem Playbook „update-ansible_ubuntu-pool.yml“ unter „remote_user“ ändern.
# .env
PROXMOX_HOST=yourpvehost:port
[email protected]
PROXMOX_PASSWORD=

Ich nutze im Skript Umgebungsvariablen, die ich in einer .env Datei deklariert habe, diese Datei muss im gleichen Verzeichnis wie das Pythonskript liegen.

Falls du einen extra Proxmox User für dieses Skript nutzen willst, muss dieser auf dem Pool die Berechtigung „PVEAuditor“ besitzen.

Ansible Playbook: update-ansible_ubuntu-pool.yml

# update-ansible_ubuntu-pool.yml
---
- hosts: ansible_ubuntu
  gather_facts: false
  remote_user: ubuntu
  become: yes
  tasks:
  - name: Update packages using apt
    apt:
      upgrade: dist
      update_cache: yes
      cache_valid_time: 86400 #One day

Dieses einfache Playbook wird mit der zuvor erstellten inventory.txt als Parameter gestartet und aktualisiert dann die Hosts aus der Datei bzw. des Proxmox PVE Pools. Natürlich lässt sich dieses Playbook beliebig erweitern, oder es können andere Playbooks mit der Inventory.txt als Parameter gestartet werden und so beliebige andere Aktivitäten auf den Hosts ausgeführt werden.

Bash: update-ansible_ubuntu-pool.sh

#!/bin/bash
#update-ansible_ubuntu-pool.sh
python3 ./get-ansible_ubuntu-pool-members.py
ansible-playbook ./update-ansible_ubuntu-pool.yml -i ./inventory.txt
#cleanup
rm ./inventory.txt

Dieses kleine BASH Skript, führt dann die beiden Skripte nacheinander aus und löscht im letzten Schritt die Inventory.txt Datei.

Ich habe dieses Skript-Triell für meine Anforderungen und für meine Umgebung gebaut, daher hat es auch ein paar Limitationen, die dafür sorgen könnten, dass es in deiner Umgebung ggf. nicht funktioniert. Falls du Fragen oder Verbesserungsvorschläge zu den Skripts oder diesem Post hast, schreib mir gerne auf Twitter unter @ncoschrdr.

- Nico  

Tags

Großartig! Das Abonnement wurde erfolgreich abgeschlossen.
Großartig! Schließen Sie als Nächstes die Kaufabwicklung ab, um vollen Zugriff zu erhalten.
Willkommen zurück! Sie haben sich erfolgreich angemeldet.
Erfolg! Ihr Konto ist vollständig aktiviert, Sie haben jetzt Zugang zu allen Inhalten.