Polycrate API für Teams: Zentrales Monitoring und Remote-Triggering
TL;DR Die Polycrate API macht aus einzelnen Workspaces eine Team-Plattform: alle Workspaces, Action …
Diese Serie zeigt Schritt für Schritt, wie Ansible mit Polycrate zu einer strukturierten, teilbaren und compliance-fähigen Automatisierungsplattform wird – von den Grundlagen bis zu Enterprise-Szenarien.
inventory.yml im Workspace-Root an und verwaltest damit alle Linux-Server zentral – ohne eigenes Ansible-Setup auf deinem Laptop.~/.ssh/-Key): Polycrate legt es bei workspace init mit --with-ssh-keys unter artifacts/secrets/ ab und verdrahtet Ansible so, dass der Private Key ohne ansible_ssh_private_key_file im Inventory genutzt wird – anders als bei plain Ansible.ansible-playbook -i inventory.yml hardening.yml reicht mit Polycrate ein polycrate run linux-baseline hardening – inklusive Container-Toolchain und zentralem inventory.yml (reines YAML, kein Jinja2 im Inventory; siehe Ansible-Integration).Typischer Alltag als Linux-Admin: Dutzende (oder hunderte) Ubuntu-Server, Sicherheitsupdates im Nacken, Anfragen von Fachbereichen, Logs, die voll laufen – und eigentlich bräuchtest du schon wieder ein neues Skript für den nächsten Sonderfall.
Ansible hilft enorm, aber in der Praxis kennst du vermutlich diese Stolpersteine:
Polycrate setzt genau dort an: Es verpackt Ansible in einen Container, bringt eine komplette, reproduzierbare Toolchain mit und gibt dir mit Workspaces und Blöcken eine feste Struktur. Du brauchst lokal nur Polycrate – kein Ansible, kein Python-Chaos, keine globalen ansible.cfg-Experimente.
In diesem Beitrag bauen wir einen kleinen, aber praxistauglichen Setup:
inventory.ymlworkspace init / --with-ssh-keys), nicht persönliche Keys aus ~/.ssh/Der Einstiegspunkt in Polycrate ist der Workspace. Er bündelt:
workspace.poly – Konfiguration des Workspacesinventory.yml – das zentrale Ansible-Inventory für alle Blöckeblocks/ – deine Ansible-Blöcke (inkl. block.poly und Playbooks)artifacts/secrets/ – u. a. vom Workspace erzeugte SSH-Schlüssel (keine Kopien aus ~/.ssh/)Lege ein Verzeichnis an und initialisiere den Workspace mit der CLI – du musst workspace.poly und die SSH-Schlüssel nicht von Hand anlegen. Vorgehen und Flags sind in der Dokumentation zu Workspace initialisieren beschrieben; SSH-Schlüssel und Best Practices in SSH-Keys (Best Practices).
Als Ablageort ist $HOME/.polycrate/workspaces/ vorgesehen. Empfehlung (nicht zwingend): Ordnerhierarchie $HOME/.polycrate/workspaces/<organization>/<workspace>/ – die Segmente entsprechen organization und name in workspace.poly und helfen, Workspaces sauber zu trennen (siehe Best Practices – Verzeichnisstruktur).
mkdir -p "$HOME/.polycrate/workspaces/acme/acme-corp-automation"
cd "$HOME/.polycrate/workspaces/acme/acme-corp-automation"
polycrate workspace init --with-name acme-corp-automation --with-organization acme --with-ssh-keysDamit entstehen u. a. workspace.poly und (bei --with-ssh-keys) ein workspace-spezifisches Schlüsselpaar unter artifacts/secrets/. Ergänze anschließend in workspace.poly den Block für dieses Beispiel:
# workspace.poly (Ausschnitt – blocks ergänzen)
blocks:
- name: linux-baseline
from: cargo.ayedo.cloud/ayedo/infra/linux-baseline:0.3.1
config:
default_target_group: "linux_all"name und organization setzt workspace init bereits; unter blocks trägst du Block-Instanzen ein. Die Instanz wird über name: angesprochen (z. B. polycrate run linux-baseline …); üblich ist, dass name dem Ordnernamen unter blocks/ entspricht (der Pfad spiegelt die OCI-Referenz).cargo.ayedo.cloud. Ein vorheriges polycrate blocks pull ist nicht nötig: Fehlt der Block lokal, erkennt Polycrate das beim Aufruf von polycrate run … und fragt, ob der Block aus der Registry automatisch installiert werden soll. Danach liegt die entpackte Struktur unter blocks/cargo.ayedo.cloud/ayedo/infra/linux-baseline/. In from: steht die vollständige Registry-Referenz inkl. Versions-Tag (OCI-Sharing statt kurzem Template-Namen; siehe Vererbung).Das Inventory liegt immer im Workspace-Root als inventory.yml. Polycrate setzt die Umgebungsvariable ANSIBLE_INVENTORY automatisch; du musst keinen -i-Parameter mehr angeben.
Beispiel:
# inventory.yml
all:
children:
linux_all:
hosts:
srv01.acme-corp.com:
ansible_user: ubuntu
srv02.acme-corp.com:
ansible_user: ubuntu
webservers:
hosts:
srv01.acme-corp.com:
dbservers:
hosts:
srv02.acme-corp.com:Wichtige Punkte:
linux_all ist unsere Standardgruppe für alle Linux-Server.webservers und dbservers erlauben dir gezielte Aktionen.inventory.yml ist statisches YAML – kein Jinja2/Templating (weder {{ … }} noch workspace.secrets[…]). Jinja2 gilt in Polycrate für Ansible-Playbooks und Block-Templates, nicht für die Inventory-Datei; siehe Konfiguration und Ansible-Integration – Inventory.ansible_ssh_private_key_file setzen: Polycrate konfiguriert Ansible so, dass automatisch der Workspace-Key verwendet wird – ein praktischer Unterschied zu plain Ansible.Mit plain Ansible müsstest du oft pro Admin passende Key-Pfade in Inventory oder ansible.cfg pflegen. Mit Polycrate bleibt das Inventory schlank und der Schlüsselbezug ist in die Laufzeit integriert.
SSH ist der Standardweg, um Linux-Server mit Ansible zu erreichen. In vielen Teams liegen private Keys auf Laptops oder USB-Sticks – aus Sicht von Compliance und Security suboptimal.
Polycrate verfolgt einen anderen Ansatz:
~/.ssh/. So bleiben Automatisierung und Nutzer-Identität getrennt (siehe Best Practices – SSH-Keys).polycrate workspace init --with-ssh-keys und liegen unter artifacts/secrets/ (u. a. id_rsa, id_rsa.pub).ansible_ssh_private_key_file im inventory.yml ein. Pfade zu Secrets sind in Playbooks über workspace.secrets[...] nutzbar, wenn du Dateien explizit referenzieren musst (nicht im Inventory).Trage den öffentlichen Schlüssel dieses Workspaces (artifacts/secrets/id_rsa.pub) auf den Zielhosts in authorized_keys für den gewünschten Benutzer ein. Den Private Key kopierst du nicht von deinem Benutzer-Account (~/.ssh/id_rsa o. ä.) in den Workspace.
Falls bei einem bestehenden Workspace noch keine Keys existieren: polycrate create ssh-keys – persönliche Private Keys nicht nach artifacts/secrets/ kopieren.
Details: SSH in Polycrate.
Jetzt zum eigentlichen Tagesgeschäft: Systeme aktuell halten und prüfen, ob alles läuft.
Wir legen einen Block linux-baseline an, der ein Basis-Playbook für:
logrotate sauber konfiguriert und aktiviert ist)enthält.
Erzeuge den Blockordner:
mkdir -p blocks/linux-baseline
cd blocks/linux-baselineLege eine block.poly an:
# blocks/linux-baseline/block.poly
name: linux-baseline
version: 0.1.0
kind: generic
config:
default_target_group: "linux_all"
services_to_check:
- ssh
- cron
actions:
- name: base
playbook: base.yml
description: "Pakete aktualisieren, Dienste prüfen, Logrotation sicherstellen"
- name: hardening
playbook: hardening.yml
description: "SSH-Hardening, UFW und fail2ban konfigurieren"config definiert Block-Defaults, die du bei Bedarf im Workspace überschreiben kannst.actions sind benannte Einstiegspunkte – du musst dir keine komplizierten Ansible-CLI-Aufrufe merken.Die allgemeine Block-Syntax ist in der Dokumentation zu Blöcken beschrieben.
base.ymlJetzt das Ansible-Playbook, das als Action base ausgeführt wird:
# blocks/linux-baseline/base.yml
- name: Linux Basis-Management
hosts: "{{ block.config.default_target_group }}"
become: true
gather_facts: true
vars:
logrotate_package: logrotate
tasks:
- name: Paket-Index aktualisieren
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Sicherheitsupdates installieren
ansible.builtin.apt:
upgrade: dist
register: upgrade_result
- name: Geänderte Pakete anzeigen
ansible.builtin.debug:
var: upgrade_result
when: upgrade_result is changed
- name: Logrotate-Paket sicherstellen
ansible.builtin.apt:
name: "{{ logrotate_package }}"
state: present
- name: Logrotate-Dienst sicherstellen (cron.daily)
ansible.builtin.stat:
path: /etc/cron.daily/logrotate
register: logrotate_cron
- name: Logrotate-Cron-Job anlegen, falls nicht vorhanden
ansible.builtin.copy:
dest: /etc/cron.daily/logrotate
content: |
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
owner: root
group: root
mode: "0755"
when: not logrotate_cron.stat.exists
- name: Wichtige Dienste prüfen
ansible.builtin.service_facts:
- name: Status der konfigurierten Dienste ausgeben
ansible.builtin.debug:
msg: "Dienst {{ item }} ist {{ ansible_facts.services[item + '.service'].state | default('unbekannt') }}"
loop: "{{ block.config.services_to_check }}"
when: "item + '.service' in ansible_facts.services"Wichtige Eigenschaften:
hosts nutzt die im Block oder Workspace konfigurierte Zielgruppe (linux_all).apt mit state: present oder upgrade ist wiederholbar.copy schreibt nur, wenn die Datei fehlt bzw. sich ändert.Ausführen kannst du das Ganze mit:
cd "$HOME/.polycrate/workspaces/acme/acme-corp-automation"
polycrate run linux-baseline basePolycrate startet dabei einen Container mit Ansible und der kompletten Toolchain. Du musst lokal kein Ansible installiert haben; das vermeidet das übliche Dependency-Problem (unterschiedliche Python-/Ansible-Versionen, systemweite Pakete, etc.). Siehe auch die Ansible-Integration von Polycrate.
Jetzt wird es sicherheitsrelevant: SSH absichern, Firewall aktivieren, fail2ban konfigurieren. Wir nutzen dafür dieselbe Block-Definition (linux-baseline), aber eine zweite Action hardening mit eigenem Playbook hardening.yml.
hardening.yml# blocks/linux-baseline/hardening.yml
- name: Linux Hardening
hosts: "{{ block.config.default_target_group }}"
become: true
gather_facts: true
vars:
sshd_config_path: /etc/ssh/sshd_config
allowed_ssh_users:
- ubuntu
ufw_allowed_ports:
- "22/tcp"
- "80/tcp"
- "443/tcp"
tasks:
- name: root-Login über SSH verbieten
ansible.builtin.lineinfile:
path: "{{ sshd_config_path }}"
regexp: "^PermitRootLogin"
line: "PermitRootLogin no"
state: present
create: false
backup: yes
- name: Passwort-Authentifizierung über SSH deaktivieren
ansible.builtin.lineinfile:
path: "{{ sshd_config_path }}"
regexp: "^PasswordAuthentication"
line: "PasswordAuthentication no"
state: present
create: false
backup: yes
- name: Erlaubte SSH-Benutzer setzen
ansible.builtin.lineinfile:
path: "{{ sshd_config_path }}"
regexp: "^AllowUsers"
line: "AllowUsers {{ allowed_ssh_users | join(' ') }}"
state: present
create: false
backup: yes
- name: SSH-Dienst neu starten
ansible.builtin.service:
name: ssh
state: restarted
- name: UFW installieren
ansible.builtin.apt:
name: ufw
state: present
update_cache: true
- name: Standard-Policy: eingehend deny, ausgehend allow
community.general.ufw:
direction: incoming
policy: deny
- name: Ausgehenden Traffic erlauben
community.general.ufw:
direction: outgoing
policy: allow
- name: Benötigte Ports erlauben
community.general.ufw:
rule: allow
port: "{{ item }}"
loop: "{{ ufw_allowed_ports }}"
- name: UFW aktivieren
community.general.ufw:
state: enabled
- name: fail2ban installieren
ansible.builtin.apt:
name: fail2ban
state: present
- name: Basis-Konfiguration für fail2ban setzen
ansible.builtin.copy:
dest: /etc/fail2ban/jail.local
content: |
[sshd]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/auth.log
maxretry = 5
owner: root
group: root
mode: "0644"
- name: fail2ban-Dienst neu starten und aktivieren
ansible.builtin.service:
name: fail2ban
state: restarted
enabled: trueHinweise:
community.general.ufw-Modul (über Ansible Galaxy).sshd_config sind über lineinfile idempotent.Ausführung gegen alle Linux-Server:
cd "$HOME/.polycrate/workspaces/acme/acme-corp-automation"
polycrate run linux-baseline hardeningMöchtest du nur die Webserver härten, kannst du im Workspace die Block-Config überschreiben:
# workspace.poly (angepasster Ausschnitt)
name: acme-corp-automation
organization: acme
blocks:
- name: linux-baseline
from: cargo.ayedo.cloud/ayedo/infra/linux-baseline:0.3.1
config:
default_target_group: "webservers"Damit greifen sowohl base als auch hardening auf die Gruppe webservers aus dem zentralen Inventory zu – ohne eine Zeile am Ansible-Playbook ändern zu müssen.
Wie würde das ohne Polycrate aussehen?
Mit plain Ansible hättest du typischerweise:
# Basis-Playbook
ansible-playbook -i inventory.yml base.yml
# Hardening
ansible-playbook -i inventory.yml hardening.ymlZusätzlich brauchst du auf deiner Workstation:
pip, apt, venv, …)ansible.cfg (z. B. für SSH-Args, Inventory-Pfad)Und wenn ein Kollege das gleiche Setup braucht, beginnt das Spiel von vorne: Versionen abgleichen, Pfade anpassen, eventuell andere OS-Distribution auf seinem Laptop.
Mit Polycrate reduziert sich das auf:
polycrate run linux-baseline base
polycrate run linux-baseline hardeningDie Vorteile für dich als Linux-Admin:
inventory.yml und ein klar strukturiertes Block-Modell verhindern Playbook-Wildwuchs.Polycrate bringt dir so Konzepte aus professionellem Platform Engineering in den Admin-Alltag, ohne dass du dich erst in Kubernetes oder komplexe CI/CD-Setups einarbeiten musst.
Nein. Polycrate führt Ansible immer innerhalb eines Containers aus. Die benötigten Binaries (Ansible, Python, zusätzliche Tools) sind Teil des Container-Images, das du über ein Dockerfile.poly oder ein Bash-Skript anpassen kannst. Damit vermeidest du die typischen Versionskonflikte zwischen verschiedenen Admin-Workstations. Details findest du in der Dokumentation zur Ansible-Integration von Polycrate.
Deine SSH-Keys liegen unter artifacts/secrets/. Optional kannst du den gesamten Workspace mit age verschlüsseln – wann und mit welchen Konsequenzen für polycrate run, steht im Abschnitt Workspace verschlüsseln am Ende dieses Beitrags. Grundlagen: SSH in Polycrate.
Ja. In den meisten Fällen kannst du bestehende Playbooks nahezu unverändert als Actions in einem Block hinterlegen – wie wir es mit base.yml und hardening.yml gemacht haben. Wichtig ist, dass du das zentrale inventory.yml im Workspace nutzt und keine lokalen Inventories oder hosts: localhost (mit connection: local) für SSH-basierte Serververwaltung verwendest. Den Rest übernimmt Polycrate: Container-Umgebung, SSH-Anbindung, Secret-Handling und die strukturierte Ausführung über Blöcke und Actions.
Weitere Fragen? Siehe unsere FAQ
Mit dem gezeigten Setup hast du eine solide Grundlage geschaffen:
inventory.yml für alle Linux-Serverartifacts/secrets/ und Polycrates automatische Ansible-Integration (ohne Key-Pfad im Inventory)linux-baselinepolycrate run, die Ansible im Container startet – ohne lokale AbhängigkeitenDamit hast du den Schritt von ad-hoc-Skripten und verstreuten Playbooks hin zu reproduzierbarer, strukturierter Automatisierung gemacht. Die Konzepte lassen sich leicht erweitern: zusätzliche Blöcke für Backup, Monitoring-Agent-Deployment, Compliance-Scans oder Integration in bestehende Tools und Prozesse.
ayedo unterstützt Teams genau bei diesem Übergang: von manueller Serverpflege hin zu einer durchdachten Automatisierungs- und Workspace-Struktur, die zu deinen bestehenden Prozessen, Sicherheitsanforderungen und Betriebsmodellen passt – egal ob du „nur“ ein paar Dutzend Linux-Server verwaltest oder gemeinsam mit einem zentralen Platform Engineering-Team eine größere Umgebung betreibst.
Wenn du deine eigene Umgebung strukturiert auf Polycrate und Ansible umstellen möchtest, konkrete Playbooks evaluieren oder ein gemeinsames Basis-Setup erarbeiten willst, ist unser Server-Automatisierung Workshop der passende Rahmen: Server-Automatisierung Workshop
Wenn du Block, Inventory und polycrate run erfolgreich eingerichtet hast, kannst du den Workspace für den Ruhezustand oder die Weitergabe mit eingebauter age-Verschlüsselung absichern:
polycrate workspace encryptWichtig: Ein verschlüsselter Workspace ist für die tägliche Arbeit mit Actions nicht geeignet: polycrate run … setzt einen entsperrten Workspace voraus. Verschlüsseln ist damit typischerweise der letzte Schritt, wenn du mit der Einrichtung fertig bist – oder du entschlüsselst vor Arbeitsbeginn explizit wieder (Details: Workspace-Verschlüsselung).
TL;DR Die Polycrate API macht aus einzelnen Workspaces eine Team-Plattform: alle Workspaces, Action …
TL;DR Polycrate protokolliert nicht nur Action Runs (Ansible-Playbooks), sondern auch SSH-Sessions, …
TL;DR Das Model Context Protocol (MCP) ist ein offener Standard: KI-Clients sprechen per JSON-RPC …