TL;DR
- Du legst mit Polycrate ein einziges
inventory.ymlim Workspace-Root an und verwaltest damit alle Linux-Server zentral – ohne eigenes Ansible-Setup auf deinem Laptop. - Pro Workspace gehört ein eigenes SSH-Schlüsselpaar (nicht dein persönlicher
~/.ssh/-Key): Polycrate legt es beiworkspace initmit--with-ssh-keysunterartifacts/secrets/ab und verdrahtet Ansible so, dass der Private Key ohneansible_ssh_private_key_fileim Inventory genutzt wird – anders als bei plain Ansible. - Ein Basis-Playbook übernimmt Paket-Updates, Dienst-Checks und Logrotation; ein eigener Hardening-Block kümmert sich um SSH-Härtung, Firewall (ufw) und fail2ban – idempotent und beliebig oft ausführbar.
- Im Vergleich zu
ansible-playbook -i inventory.yml hardening.ymlreicht mit Polycrate einpolycrate run linux-baseline hardening– inklusive Container-Toolchain und zentraleminventory.yml(reines YAML, kein Jinja2 im Inventory; siehe Ansible-Integration). - ayedo unterstützt dich mit Polycrate, Platform Engineering-Know-how und Workshops zu Polycrate und Automatisierung (z. B. Polycrate Essentials) dabei, dein Linux-Server-Management strukturiert und wiederholbar aufzusetzen.
Ausgangssituation: Viele Linux-Server, wenig Zeit
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:
- Unterschiedliche Python-/Ansible-Versionen auf den Admin-Workstations
- Inventories, die in zig Repos und Verzeichnissen liegen
- SSH-Keys, die lokal auf den Laptops verteilt sind
- Playbook-Wildwuchs ohne klare Struktur
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:
- Ein Workspace mit zentralem
inventory.yml - SSH: dediziertes Schlüsselpaar pro Workspace (
workspace init/--with-ssh-keys), nicht persönliche Keys aus~/.ssh/ - Ein Basis-Playbook für Updates, Dienst-Checks und Logrotation
- Einen Hardening-Block für SSH, ufw und fail2ban
- Ausführung gegen mehrere Servergruppen – idempotent und beliebig wiederholbar
Workspace anlegen und Inventory zentralisieren
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.polyund Playbooks)artifacts/secrets/– u. a. vom Workspace erzeugte SSH-Schlüssel (keine Kopien aus~/.ssh/)
Workspace-Grundlage
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-keys
Damit 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"
nameundorganizationsetztworkspace initbereits; unterblocksträgst du Block-Instanzen ein. Die Instanz wird übername:angesprochen (z. B.polycrate run linux-baseline …); üblich ist, dassnamedem Ordnernamen unterblocks/entspricht (der Pfad spiegelt die OCI-Referenz).- Der Block liegt in der Registry unter
cargo.ayedo.cloud. Ein vorherigespolycrate blocks pullist nicht nötig: Fehlt der Block lokal, erkennt Polycrate das beim Aufruf vonpolycrate run …und fragt, ob der Block aus der Registry automatisch installiert werden soll. Danach liegt die entpackte Struktur unterblocks/cargo.ayedo.cloud/ayedo/infra/linux-baseline/. Infrom:steht die vollständige Registry-Referenz inkl. Versions-Tag (OCI-Sharing statt kurzem Template-Namen; siehe Vererbung).
Zentrales Inventory: eine Wahrheit für alle Blöcke
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_allist unsere Standardgruppe für alle Linux-Server.- Untergruppen wie
webserversunddbserverserlauben dir gezielte Aktionen. inventory.ymlist statisches YAML – kein Jinja2/Templating (weder{{ … }}nochworkspace.secrets[…]). Jinja2 gilt in Polycrate für Ansible-Playbooks und Block-Templates, nicht für die Inventory-Datei; siehe Konfiguration und Ansible-Integration – Inventory.- Den SSH-Private-Key des Workspaces musst du nicht per
ansible_ssh_private_key_filesetzen: 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-Schlüssel sicher im Workspace
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:
- Eigenes Schlüsselpaar pro Workspace – nicht dein persönlicher Private Key aus
~/.ssh/. So bleiben Automatisierung und Nutzer-Identität getrennt (siehe Best Practices – SSH-Keys). - Schlüssel entstehen bei
polycrate workspace init --with-ssh-keysund liegen unterartifacts/secrets/(u. a.id_rsa,id_rsa.pub). - Polycrate stellt sie im Container bereit und verdrahtet Ansible automatisch mit dem Workspace-Key – du trägst dafür keinen
ansible_ssh_private_key_fileiminventory.ymlein. Pfade zu Secrets sind in Playbooks überworkspace.secrets[...]nutzbar, wenn du Dateien explizit referenzieren musst (nicht im Inventory).
Öffentlichen Schlüssel auf den Servern hinterlegen
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.
Basis-Playbook: Pakete aktualisieren, Dienste prüfen, Logs rotieren
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:
- Paket-Updates (Ubuntu-Server)
- Dienst-Status-Prüfung
- Logrotation (Sicherstellen, dass
logrotatesauber konfiguriert und aktiviert ist)
enthält.
Block-Struktur
Erzeuge den Blockordner:
mkdir -p blocks/linux-baseline
cd blocks/linux-baseline
Lege 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"
configdefiniert Block-Defaults, die du bei Bedarf im Workspace überschreiben kannst.actionssind benannte Einstiegspunkte – du musst dir keine komplizierten Ansible-CLI-Aufrufe merken.- Dieser Block ist lokal – du könntest ihn später in eine Registry pushen und in anderen Workspaces wiederverwenden (Stichwort: Sharable Automation über OCI-Registry und PolyHub).
Die allgemeine Block-Syntax ist in der Dokumentation zu Blöcken beschrieben.
Basis-Playbook base.yml
Jetzt 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:
hostsnutzt die im Block oder Workspace konfigurierte Zielgruppe (linux_all).- Alle Tasks sind idempotent:
aptmitstate: presentoderupgradeist wiederholbar.copyschreibt nur, wenn die Datei fehlt bzw. sich ändert.- Du kannst das Playbook beliebig oft laufen lassen, ohne Gefahr, etwas kaputt zu machen – ein Kernvorteil von Ansible.
Ausführen kannst du das Ganze mit:
cd "$HOME/.polycrate/workspaces/acme/acme-corp-automation"
polycrate run linux-baseline base
Polycrate 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.
Hardening als eigener Block-Action: SSH, UFW, fail2ban
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-Playbook 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: true
Hinweise:
- Für UFW nutzen wir das
community.general.ufw-Modul (über Ansible Galaxy). - Alle Änderungen an
sshd_configsind überlineinfileidempotent. - Auch fail2ban wird wiederholbar konfiguriert – ein erneutes Ausführen überschreibt die Config nicht unkontrolliert, sondern setzt definierte Inhalte.
Ausführung gegen alle Linux-Server:
cd "$HOME/.polycrate/workspaces/acme/acme-corp-automation"
polycrate run linux-baseline hardening
Mö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.
Polycrate vs. plain Ansible im Alltag
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.yml
Zusätzlich brauchst du auf deiner Workstation:
- Eine passende Ansible-Version (ggf. via
pip,apt,venv, …) - Python in der richtigen Version
- Eine sauber konfigurierte
ansible.cfg(z. B. für SSH-Args, Inventory-Pfad) - Sicheres Handling deines SSH-Keys auf dem lokalen System
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 hardening
Die Vorteile für dich als Linux-Admin:
- Kein lokales Ansible installieren – Polycrate führt Ansible immer im Container aus und löst damit das klassische Dependency-Problem.
- Eine zentrale
inventory.ymlund ein klar strukturiertes Block-Modell verhindern Playbook-Wildwuchs. - Workspace-Inhalte (inkl. Secrets) lassen sich für Ruhezustand und Team-Sharing absichern – siehe den Abschnitt Workspace verschlüsseln am Ende dieses Beitrags.
- Was du einmal als Block gebaut hast, kannst du versioniert in eine Registry pushen und in anderen Umgebungen wiederverwenden – intern oder über PolyHub, ganz im Sinne von sharable Automation.
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.
Häufige Fragen
Muss ich Ansible noch lokal installieren, wenn ich Polycrate nutze?
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.
Wie sicher sind meine SSH-Keys im Workspace?
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.
Kann ich meine bestehenden Ansible-Playbooks weiterverwenden?
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
Praktische Umsetzung
Mit dem gezeigten Setup hast du eine solide Grundlage geschaffen:
- Ein zentraler Workspace mit einheitlichem
inventory.ymlfür alle Linux-Server - Sauberes SSH-Key-Handling über
artifacts/secrets/und Polycrates automatische Ansible-Integration (ohne Key-Pfad im Inventory) - Ein Basis-Playbook für Updates, Dienst-Checks und Logrotation
- Ein Hardening-Playbook für SSH, UFW und fail2ban, gekapselt als Action im Block
linux-baseline - Eine einfache, wiederholbare Ausführung über
polycrate run, die Ansible im Container startet – ohne lokale Abhängigkeiten
Damit 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
Workspace verschlüsseln (nach getaner Arbeit)
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 encrypt
Wichtig: 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).