Dein erster produktiver Polycrate-Workspace: Eine Checkliste für den Start
TL;DR Ein sauber benannter, klar strukturierter Polycrate-Workspace ist die halbe Miete: ein …
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.
linux_group und windows_group an, kapselst Linux- und Windows-Playbooks in eigenen Blöcken und steuerst alles aus einem Workspace.config-Einträgen der workspace.poly – pro Block explizit (im Hybrid-Beispiel dieselben Werte zweimal, ohne YAML-Anker); in .poly-Dateien gibt es keine Jinja-Templating.artifacts/secrets/ und werden mitverschlüsselt; sensible Block-Konfiguration wie win_admin_password gehört in secrets.poly (nicht als artifacts/secrets/win_admin_password) – siehe Workspace-Verschlüsselung.polycrate workflows run … Befehlen, ohne lokal Ansible, Python oder pywinrm installieren zu müssen.Wenn du in einem größeren Unternehmen arbeitest, sieht deine Welt meistens so aus:
In vielen Teams landen diese Welten in getrennten Silos:
Polycrate dreht das um: ein Workspace, zwei Blocks (Linux und Windows), ein Inventory, ein Workflow. Und alles läuft in einem Container, der dir das klassische Dependency-Problem mit Ansible abnimmt:
In diesem Beitrag bauen wir genau so einen Hybrid-Workspace – inklusive Inventory, Blöcken, Playbooks, Secrets und Workflow.
Der Workspace ist der Dreh- und Angelpunkt. Hier definierst du:
configworkspace.poly unter config (z. B. Container-Image – siehe Konfiguration), nicht als freie Key-Value-Pipeline für beliebige AutomatisierungsvariablenIn workspace.poly und block.poly ist keine Template-Substitution (kein Jinja2) möglich; Werte sind literale YAML oder werden aus secrets.poly gemerged. Siehe Wichtige Einschränkungen.
workspace.poly – DNS/NTP je Block im jeweiligen config als literale Werte eintragen (hier dieselben Werte in linux-mgmt und windows-mgmt – keine YAML-Anker). SSH: Polycrate richtet für Ansible im Action-Container u. a. ANSIBLE_PRIVATE_KEY_FILE ein – du trägst kein ssh_private_key in die Block-config ein und kein ansible_ssh_private_key_file ins Playbook.
name: acme-corp-automation
organization: acme
blocks:
- name: linux-mgmt
from: registry.acme-corp.com/acme/infra/linux-mgmt:0.1.0
config:
dns_server: "10.0.0.10"
ntp_server: "time.acme-corp.com"
- name: windows-mgmt
from: registry.acme-corp.com/acme/infra/windows-mgmt:0.1.0
config:
dns_server: "10.0.0.10"
ntp_server: "time.acme-corp.com"
win_admin_user: "ACME\\ansible-svc"
workflows:
- name: hybrid-maintenance
steps:
- name: update-linux
block: linux-mgmt
action: update-linux
- name: update-windows
block: windows-mgmt
action: update-windowssecrets.poly (sensible Block-Konfiguration, wird mit workspace.poly gemerged – überschreibt bei gleichen Keys):
blocks:
- name: windows-mgmt
config:
win_admin_password: "…"Das WinRM-Passwort ist kein Artefakt-Pfad: Es steht als Eintrag unter blocks[].config in secrets.poly, nicht als Datei artifacts/secrets/win_admin_password. So beschreibt es die Workspace-Verschlüsselung für secrets.poly (sensible Block-Konfiguration) im Unterschied zu Dateien unter artifacts/secrets/.
Wichtig:
workspace.poly hat zwar ein config-Feld, das ist für Workspace-/Toolchain-Einstellungen gedacht (z. B. config.image), nicht für beliebige freie „globale“ Variablen wie DNS- oder Inventar-Parameter – die gehören in die Block-config (und ggf. secrets.poly).block.poly → workspace.poly → secrets.poly – Details in der Konfiguration.from: enthält die vollständige OCI-Registry-Referenz inklusive Versions-Tag; entpackt liegen die Blöcke unter blocks/registry.acme-corp.com/acme/infra/…/.hybrid-maintenance ruft nacheinander Linux- und Windows-Actions auf.Polycrate nutzt immer ein YAML-Inventory im Workspace-Root unter inventory.yml. Keine INI-Files, kein pro-Block-Inventory.
Wie im Multi-Server-Artikel beschrieben, stehen alle Hosts einmal unter all.hosts; unter children ordnen Sie sie nur noch Gruppen zu – damit nutzen Ansible und polycrate ssh dieselbe kanonische Hostliste. Gemeinsame Linux-Defaults legen Sie unter all.vars ab; WinRM-Einstellungen hängen an der Windows-Gruppe, weil sie nur dort gelten.
Unser Hybrid-Inventory mit zwei Gruppen:
all:
vars:
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
ansible_python_interpreter: /usr/bin/python3
hosts:
linux01.acme-corp.com:
ansible_user: ubuntu
linux02.acme-corp.com:
ansible_user: ubuntu
win01.acme-corp.com: {}
win02.acme-corp.com: {}
children:
linux_group:
hosts:
linux01.acme-corp.com:
linux02.acme-corp.com:
windows_group:
hosts:
win01.acme-corp.com:
win02.acme-corp.com:
vars:
ansible_connection: winrm
ansible_winrm_transport: credssp
ansible_winrm_server_cert_validation: ignoreEin paar Punkte dazu:
all.hosts (oder als Default in all.vars). Den Private Key für Ansible liefert Polycrate über Umgebungsvariablen im Container (ANSIBLE_PRIVATE_KEY_FILE u. a.) – ohne ssh_private_key in der workspace.poly und ohne ansible_ssh_private_key_file im Playbook.ansible_connection: winrm etc.) liegen in den vars der Gruppe windows_group.block.config.win_admin_user und block.config.win_admin_password (im Playbook gesetzt).Polycrate setzt die Umgebungsvariable ANSIBLE_INVENTORY beim Start der Action automatisch, du musst also kein -i inventory.yml an die Ansible-CLI anhängen – das übernimmt Polycrate für dich. Mehr dazu in der Ansible-Integration.
Hybride Umgebungen bedeuten auch hybride Authentifizierung:
artifacts/secrets/ (z. B. id_rsa) und wird mit dem Workspace verschlüsselt. Für Ansible verdrahtet Polycrate den Zugriff im Action-Container per Umgebungsvariable (ANSIBLE_PRIVATE_KEY_FILE) – ohne expliziten ssh_private_key-Eintrag in der workspace.poly und ohne ansible_ssh_private_key_file im Playbook.workspace.poly im Block-config stehen; das Passwort trägst du nicht dort ein, sondern in secrets.poly unter dem passenden Block (windows-mgmt), damit es beim Merge in block.config landet und nicht im Klartext versioniert wird (oder Zertifikate statt Passwort, je nach Setup).polycrate workspace encrypt verschlüsselt secrets.poly sowie Dateien unter artifacts/secrets/ (siehe Workspace-Verschlüsselung). Du aktivierst und verwaltest das über die CLI, z. B.:
# Secrets verschlüsseln (z. B. vor einem Git-Commit)
polycrate workspace encrypt
# Zum Arbeiten wieder entschlüsseln
polycrate workspace decryptIn Ansible-Playbooks (nicht in .poly-Dateien) greifst du dann auf block.config.* zu – die Werte stammen aus dem gemergeden block.poly + workspace.poly + secrets.poly.
Damit erreichst du zwei wichtige Dinge:
Beginnen wir mit dem Linux-Teil. Der Block kapselt alles, was du für Linux-Server tun möchtest – hier als Beispiel:
In block.poly muss name die vollständige Registry-URL sein – dieselbe Zeichenkette wie in from: im workspace.poly, ohne Versions-Tag (:0.1.0). Kurz: from: = name + : + Tag. Das ist nicht derselbe Bezeichner wie die Block-Instanz linux-mgmt im workspace.poly. Die Datei liegt unter blocks/registry.acme-corp.com/acme/infra/linux-mgmt/block.poly (Verzeichnisbaum = Registry-Pfad).
# name = from: ohne Tag (vollständiger Registry-Pfad)
name: "registry.acme-corp.com/acme/infra/linux-mgmt"
version: 0.1.0
kind: generic
config:
dns_server: ""
ntp_server: ""
actions:
- name: update-linux
description: Linux-Server aktualisieren und Basiskonfiguration setzen
playbook: linux_update.ymlDas zugehörige Ansible-Playbook blocks/registry.acme-corp.com/acme/infra/linux-mgmt/linux_update.yml:
- name: Linux-Server aktualisieren und Basis-Config setzen
hosts: linux_group
become: true
gather_facts: true
vars:
dns_server: "{{ block.config.dns_server }}"
ntp_server: "{{ block.config.ntp_server }}"
tasks:
- name: Paketliste aktualisieren (Debian-Familie)
ansible.builtin.apt:
update_cache: true
when: ansible_os_family == 'Debian'
- name: Pakete aktualisieren (Debian-Familie)
ansible.builtin.apt:
upgrade: dist
when: ansible_os_family == 'Debian'
- name: Pakete aktualisieren (RedHat-Familie)
ansible.builtin.yum:
name: "*"
state: latest
when: ansible_os_family == 'RedHat'
- name: DNS-Server in /etc/resolv.conf setzen
ansible.builtin.lineinfile:
path: /etc/resolv.conf
regexp: '^nameserver'
line: "nameserver {{ dns_server }}"
when: ansible_os_family in ['Debian', 'RedHat']
- name: NTP-Paket installieren (Debian-Familie)
ansible.builtin.package:
name: chrony
state: present
when: ansible_os_family == 'Debian'
- name: NTP-Server in chrony.conf konfigurieren
ansible.builtin.lineinfile:
path: /etc/chrony/chrony.conf
regexp: '^server'
line: "server {{ ntp_server }} iburst"
when: ansible_os_family == 'Debian'
- name: chrony neu starten
ansible.builtin.service:
name: chrony
state: restarted
enabled: true
when: ansible_os_family == 'Debian'Wesentliche Punkte:
hosts: linux_group – wir arbeiten auf den Linux-Hosts aus dem gemeinsamen Inventory, nicht auf localhost.ansible_os_family steuert OS-spezifische Tasks (when:-Bedingungen). So kannst du Debian, RedHat und Co. im selben Playbook behandeln.block.config.* aus der zusammengeführten Block-Konfiguration. SSH: Polycrate setzt im Container u. a. ANSIBLE_PRIVATE_KEY_FILE – ohne ssh_private_key in der workspace.poly und ohne ansible_ssh_private_key_file im Playbook. Hintergrund: Ansible-Integration.Ausführen kannst du die Action mit:
polycrate run linux-mgmt update-linuxDu musst dich nicht um die lokale Installation von Ansible, Python oder SSH-Client kümmern – Polycrate startet einen Container mit einer vollständigen Toolchain (inkl. Ansible, Python, SSH), wie in den Best Practices beschrieben.
Der zweite Block kümmert sich um Windows-Hosts:
blocks/registry.acme-corp.com/acme/infra/windows-mgmt/block.poly – name wieder als vollständiger Registry-Pfad ohne Tag, analog zum Linux-Block:
# name = from: ohne Tag (vollständiger Registry-Pfad)
name: "registry.acme-corp.com/acme/infra/windows-mgmt"
version: 0.1.0
kind: generic
config:
dns_server: ""
ntp_server: ""
win_admin_user: ""
win_admin_password: ""
actions:
- name: update-windows
description: Windows-Server aktualisieren und Basiskonfiguration setzen
playbook: windows_update.ymlDas Playbook blocks/registry.acme-corp.com/acme/infra/windows-mgmt/windows_update.yml:
- name: Windows-Hosts aktualisieren und Basis-Config setzen
hosts: windows_group
gather_facts: true
vars:
ansible_user: "{{ block.config.win_admin_user }}"
ansible_password: "{{ block.config.win_admin_password }}"
dns_server: "{{ block.config.dns_server }}"
ntp_server: "{{ block.config.ntp_server }}"
tasks:
- name: Erreichbarkeit prüfen
ansible.windows.win_ping: {}
- name: Windows Updates installieren
ansible.windows.win_updates:
category_names:
- CriticalUpdates
- SecurityUpdates
reboot: yes
- name: DNS-Server auf Netzwerkadapter setzen
ansible.windows.win_dns_client:
adapter_names: "*"
ipv4_addresses:
- "{{ dns_server }}"
when: ansible_os_family == 'Windows'
- name: Windows Time Service konfigurieren
ansible.windows.win_shell: |
w32tm /config /manualpeerlist:"{{ ntp_server }}" /syncfromflags:manual /reliable:yes /update
when: ansible_os_family == 'Windows'
- name: Windows Time Service neu starten
ansible.windows.win_service:
name: W32Time
state: restarted
when: ansible_os_family == 'Windows'Auch hier:
hosts: windows_group greift auf dieselbe inventory.yml zu wie der Linux-Block.ansible_user und ansible_password kommen aus der verschlüsselten Workspace-Konfiguration, nicht im Klartext aus dem Inventory.ansible_os_family == 'Windows' sichert OS-spezifische Tasks ab, falls du die Gruppe später erweitern und z. B. noch spezielle Appliances einhängen möchtest.Die Ausführung:
polycrate run windows-mgmt update-windowsDurch die Container-Ausführung sind alle Abhängigkeiten wie pywinrm bereits im Container enthalten. Mit plain Ansible müsstest du sicherstellen, dass auf jeder Admin-Maschine:
ansible.windows-Collection installiert sind,Mit Polycrate entfällt dieser Einrichtungsaufwand – das ist die Stärke des Container-Modells in Verbindung mit Ansible, wie in der Ansible-Integration beschrieben.
Der Charme eines gemeinsamen Workspaces zeigt sich im Workflow. In der workspace.poly haben wir bereits den Workflow hybrid-maintenance definiert:
workflows:
- name: hybrid-maintenance
steps:
- name: update-linux
block: linux-mgmt
action: update-linux
- name: update-windows
block: windows-mgmt
action: update-windowsDamit kannst du einen kompletten Wartungslauf so starten:
polycrate workflows run hybrid-maintenanceWas passiert:
update-linux des Blocks linux-mgmt aus.update-windows des Blocks windows-mgmt aus.Du kannst Workflows erweitern, z. B.:
Workflows sind damit die verbindende Schicht zwischen den Blöcken und sorgen dafür, dass du nicht wieder in einen unstrukturierten “Playbook-Wildwuchs” rutschst. Details findest du in der Dokumentation zu Workflows.
Zum Einordnen lohnt sich der Vergleich mit einem klassischen Setup:
Mit plain Ansible müsstest du typischerweise:
ansible-playbook-Befehle sie in welcher Reihenfolge ausführen sollen.Mit Polycrate bekommst du:
kubectl oder helm kommen in einer definierten Container-Toolchain. Kein Setup-Chaos auf Admin-Workstations.linux-mgmt- und windows-mgmt-Blöcke kannst du via OCI-Registry teilen – intern oder über PolyHub (Referenzschema wie registry.acme-corp.com/acme/infra/windows-mgmt:0.1.0; siehe PolyHub).block.poly, workspace.poly und Workflows (Best Practices).polycrate run windows-mgmt update-windows oder polycrate workflows run hybrid-maintenance reichen aus.Ansible bleibt das zentrale Automatisierungswerkzeug – Polycrate ergänzt es um Struktur, Wiederverwendbarkeit und Team-Fokus.
Ja. Das Inventory kann beliebig viele Gruppen enthalten, und deine Playbooks können über ansible_os_family oder andere Facts OS-spezifische Pfade gehen. Für MacOS- oder spezielle Appliances kannst du eigene Gruppen und entweder zusätzliche Blöcke oder weitere Actions in bestehenden Blöcken anlegen. Wichtig ist, dass du die Struktur beibehältst: klare Blöcke, klares Inventory, klare Workflows.
Die Workspace-Verschlüsselung von Polycrate basiert auf age und verschlüsselt sensible Dateien (wie SSH-Keys oder Passwörter) direkt im Repository. Damit erreichst du:
Die Details, inklusive Schlüsselverwaltung und Integration in bestehende Prozesse, sind in der Dokumentation zu Workspace-Verschlüsselung beschrieben.
Wir arbeiten regelmäßig mit Teams, die genau diese Situation haben: gewachsene Windows-Domänen, neue Linux-Workloads, dazu Compliance-Vorgaben. In einem Hybrid-Workshop erarbeiten wir:
Auf Wunsch integrieren wir auch existierende Tools (Monitoring, CMDB, Ticket-System) und helfen beim Aufbau eurer eigenen Block-Registry.
Weitere Fragen? Siehe unsere FAQ
Mit dem Hybrid-Workspace aus diesem Beitrag hast du drei Dinge erreicht:
linux-mgmt, windows-mgmt) kapseln OS-spezifische Playbooks, während ein Workflow (hybrid-maintenance) den Ablauf vorgibt.workspace.poly (bzw. secrets.poly für Passwörter); der SSH-Key als Datei unter artifacts/secrets/, WinRM-Passwort in secrets.poly – bei aktivierter Verschlüsselung committest du nur .age-Artefakte.Damit wird aus dem klassischen Patchday – oft eine Mischung aus manuellen Schritten, Remote-Desktop-Sessions und unstrukturierten Skripten – ein reproduzierbarer, dokumentierter Ablauf:
polycrate workflows run hybrid-maintenance)Als ayedo begleiten wir Teams genau auf diesem Weg: weg von isolierten Skripten und hin zu wiederverwendbaren, teilbaren Automatisierungsbausteinen. Ob du primär aus der Linux-, Windows- oder Compliance-Perspektive kommst – ein gemeinsamer Hybrid-Workspace ist ein starkes Fundament, auf dem du Schritt für Schritt weiter aufbauen kannst: zusätzliche Policies, Hardening, Monitoring-Integration oder Self-Service für andere Teams.
Wenn du deine eigene Hybrid-Infrastruktur auf diese Weise strukturieren möchtest und dabei von Erfahrungen aus anderen Umgebungen profitieren willst, ist unser Hybrid-Infrastruktur Workshop ein guter Einstiegspunkt.
TL;DR Ein sauber benannter, klar strukturierter Polycrate-Workspace ist die halbe Miete: ein …
TL;DR Plain Ansible ist ein starkes Werkzeug für Ad-hoc-Automatisierung, schnelle Skripte und …
TL;DR Du richtest WinRM einmal sauber mit HTTPS, Zertifikat und Firewall-Regeln ein und hast danach …