Ansible für Proxmox

Nach den schnellen Erfolgen mit Ansible, wollte ich gleich den nächsten Schritt machen und via API-Zugang meine Proxmox Rechner steuern. Damit kann man dann virtuelle Maschinen und Container erstellen, starten, stoppen und löschen. Mit einem Befehl, der ein entsprechendes Playbook startet und alles automatisiert durchführt. Aber dazu muss man zuerst eine Verbindung zusammenbringen. Leichter wäre es mit dem direkten SSH-Zugang, der funktioniert auch gleich, wie mit den Containern und VMs, aber nachdem es einen API-Zugang gibt für Proxmox und man dort auch genauer die Berechtigungen für die API-Tokens festlegen kann, habe ich mir gedacht: Das machen wir, wird schon nicht so schwer sein. Aber naja, es war dann schwieriger als gedacht. Ich habe überlegt, den Beitrag zu löschen und noch einmal anzufangen. Ich habe mich dann doch zu sehr auf die “gschichtldruckerischen” Sprachmodelle gestützt. Von daher ist dieser ein guter Beitrag, wie man nicht an eine Sache rangehen sollte, das Nachfragen von generellen Infos zu technischen Themen funktioniert grundsätzlich schon gut mit den LLMs, aber wenn zu spezielle Dinge nachfragt, dann biegen die Chatbots gerne ins Fantastische ab. Also bei kritischen Dingen (oder beim Aufsetzen von Ansible für Proxmox) soll man immer die Angaben überprüfen, eine gescheite Anleitung finden und auch die Dokumentation selbst lesen. Wie auch immer, on with the show.

Vorbereitung und Sicherheit

Ich halte mich bei der Einrichtung grundsätzlich an dieses Video, leider sieht der Videomacher jedoch keinen Sinn und Zweck darin, seine Einstellungen zu erklären, oder auch nur Anhaltspunkte zu bekommen, welche Einstellung welche Konsequenzen haben könnte.

Für das Funktionieren von Ansible braucht es einen “API Token”, dieser findet sich unter “Datacenter” und “Permissions/API Tokens”, dort auf “Add” klicken, einen “Token ID” Namen vergeben und, wenn gewünscht ein Ablaufdatum:

Diesen API Token gut verwahren, denn er wird von Proxmox nur einmal angezeigt.

Danach muss man noch die Berechtigungen setzen unter “Permissions” auf “Add” klicken und dort “API Token Permission” auswählen, dort wird im Video von oben gesagt, dass er Root-Zugang und die Rolle des “PVEAdmin” vergibt:

Update: Achtung, unten erkläre ich weshalb ich einen eigenen User namens “ansible” für diese Rolle erstelle. Der Token bezieht sich also letztendlich auf “ansible@pam!pve-ansible”. Dafür habe ich auch den API Token neu erstellen müssen…

Ich würde gerne etwas mehr darüber wissen, welche Privilegien es gibt und welche für typische Ansible-Aufgaben (VMs und CT steuern) notwendig sind. Gemäß dem Prinzip des geringsten Privilegs, sollte man nämlich ganz genau überlegen, was hier was tun kann.

Also fragen wir einmal den Chatbot GPT-4o:

Diese Erklärung klingt vernünftig, hier findet sich auch die offizielle Dokumentation von Proxmox. Für das Erstellen von VMs und Containern braucht es “PVEAdmin”, also fügen wir den API Token mit diesen Rechten hinzu.

Als nächstes muss man noch die API Token Berechtigungen setzen. Das geht wieder unter “Datacenter” und “Permissions”. Dort Auf “Add” klicken und “API Token Permission” auswählen. Die Einstellungen dort sind wie folgt:

Ich habe aber gerade bemerkt, dass der Token mit dem root User verknüpft ist, das kann zu Problemen führen, wenn man den LLM’schen Ausführungen Glauben schenken mag:

Also noch ein eigener User für Ansible:

Der User “ansible” selbst sollte keine erhöhten Rechte benötigen.

Dann muss man noch unter “group_vars” die Datei “proxmox.yml” erstellen:

ansible_user: "{{ lookup('env', 'PROXMOX_API_USER') }}"
ansible_password: "{{ lookup('env', 'PROXMOX_API_TOKEN') }}"
ansible_connection: httpapi
ansible_httpapi_use_ssl: yes
ansible_httpapi_validate_certs: no

Diese "{{ lookup('env', 'PROXMOX_API_USER') }}" Einträge verwenden sog. Umgebungsvariablen, diese eignen sich besser als das direkte Eintragen von Usernamen und API Token, vor allem wenn man mit Git arbeitet und sein Werkl auf Github oder sonstwo, womöglich noch öffentlich, hochladen möchte. Alternativ kann man natürlich beide Einträge direkt in Anführungszeichen eintragen.

Im Projektordner (bei mir “ansible”) erstellt man eine Datei namens .env und fügt dort Folgendes ein:

PROXMOX_API_USER="ansible@pve!ansible_token"
PROXMOX_API_TOKEN="token"

Dann sollte man noch Git sagen, dass diese Datei ignoriert wird:

echo ".env" >> .gitignore

Die Umgebungsvariablen müssen jedoch auch geladen werden, so zumindest meint es der Sprachbot – tut mir leid, wenn das oft vorkommt, aber es geht halt um einiges schneller, als sich die Informationen aus allen Ecken des Internets zu holen oder eine Doku nach der anderen zu durchsuchen nach der Information die man sucht. Wie auch immer, es wird empfohlen mit direnv zu arbeiten:

Also zuerst direnv installieren und .envrc erstellen…

echo "source .env" > .envrc

… und mit direnv allow aktivieren. Testen kann man das mit:

echo $PROXMOX_API_TOKEN

Falls das nicht funktioniert kann man die Umgebungsvariablen auch manuell laden:

source .env

Anschließend muss man noch die Inventory-Datei anpassen:

[proxmox]
pve ansible_host=192.168.0.x ansible_connection=httpapi

API Verbindung testen

Als erstes werde ich den API-Zugang mit diesem einfachen Playbook testen:

---
- name: Proxmox Container Management
  hosts: proxmox
  gather_facts: no
  tasks:
    - name: Create a new container
      community.general.proxmox:
        api_host: "{{ ansible_host }}"
        api_user: "{{ lookup('env', 'PROXMOX_API_USER') }}"
        api_password: "{{ lookup('env', 'PROXMOX_API_TOKEN') }}"
        node: "proxmox_node_name"
        vmid: 349  # Proxmox VM ID for the container
        hostname: "debian4"
        ostemplate: "local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst"
        memory: 512
        swap: 512
        netif: '{"net0":"name=eth0,bridge=vmbr0,ip=dhcp"}'
        password: "debian"
        state: present
      delegate_to: localhost
 

Und funktionieren tut es nicht, kann es auch nicht, denn ein paar Sachen sind falsch eingerichtet und es fehlt auch das eine oder andere, aber das werde ich nächsten Beitrag herrichten, hoffentlich.