Das Polycrate-Ökosystem: PolyHub, API, MCP und die Zukunft der Automatisierung
TL;DR Polycrate ist längst mehr als ein CLI-Tool: Mit PolyHub, API-Plattform und MCP entsteht 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.
block.config macht deine Helm-Values zum zentralen, versionierten Konfigurationspunkt – inklusive Jinja2-Template, das komplexe values.yaml-Strukturen sauber generiert.kubernetes.core.helm_repository, kubernetes.core.helm, kubernetes.core.helm_rollback bekommst du Upgrade-, Diff- und Rollback-Logik als wiederverwendbare Actions in einem Polycrate-Block.kubectl, Python, Ansible-Collections laufen im Container – keine lokalen Installationsorgien oder Versionskonflikte, Workspaces können verschlüsselt werden.Helm ist das Standardwerkzeug, um komplexe Anwendungen auf Kubernetes zu deployen. Viele Teams starten mit:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm upgrade --install postgres bitnami/postgresql -f values-prod.yamlSolange ein einzelner Admin sein Cluster verwaltet, ist das okay. Spätestens wenn mehrere Umgebungen, mehrere Personen und Compliance-Anforderungen dazukommen, tauchen typische Probleme auf:
values.yaml für prod?Genau hier spielt die Kombination aus Ansible und Polycrate ihre Stärken aus:
kubernetes.core.helm).block.config macht deine Helm-Values zu sauber versionierter Konfiguration, die sich über Workspaces, Teams und sogar via OCI-Registry teilen lässt.In diesem Beitrag baust du einen vollständigen Polycrate-Block, der ein PostgreSQL Helm-Chart deployt – inklusive:
dry_runUnd wir schauen ehrlich darauf, wann du trotzdem Helm direkt nutzen solltest.
Wir nehmen als Ausgangspunkt einen Workspace:
# workspace.poly
name: acme-corp-automation
organization: acme
blocks:
- name: postgres
from: registry.acme-corp.com/acme/helm/postgres-helm:0.1.0
config:
namespace: "databases-prod"
chart_version: "12.1.2"
postgres:
storage_size: "50Gi"Wichtige Punkte:
from: verweist auf einen Block in einer OCI-Registry (hier fiktiv registry.acme-corp.com/...; öffentlich z. B. cargo.ayedo.cloud oder PolyHub). Nach polycrate blocks pull liegt der Block unter blocks/registry.acme-corp.com/acme/helm/postgres-helm/ – die Version ist im from: gepinnt (:0.1.0).config unter dem Block-Eintrag überschreibt Defaults aus block.poly – so kannst du denselben Block z. B. für dev, stage, prod mit jeweils anderen Werten nutzen.workspace.poly-Struktur folgt den Workspaces-Best Practices.Für den Kubernetes-Zugriff legen wir die Kubeconfig in den Workspace:
artifacts/secrets/kubeconfig.ymlPolycrate lädt Dateien unter artifacts/secrets/ automatisch in workspace.secrets. Sensible Inhalte kannst du mit der integrierten Workspace-Verschlüsselung schützen, siehe Workspace-Verschlüsselung. Kein kubeconfig_path in workspace.poly oder block.poly nötig: Polycrate setzt im Action-Container KUBECONFIG und K8S_AUTH_KUBECONFIG auf die Workspace-Kubeconfig; kubernetes.core.helm* und andere Kubernetes-Module nutzen das automatisch.
Unser Block liegt unter blocks/registry.acme-corp.com/acme/helm/postgres-helm/. Die block.poly definiert Konfiguration und Actions (name = vollständiger Registry-Pfad ohne Tag):
# blocks/registry.acme-corp.com/acme/helm/postgres-helm/block.poly
name: registry.acme-corp.com/acme/helm/postgres-helm
version: 0.1.0
kind: generic
description: "Deploys a PostgreSQL Helm chart via Ansible and kubernetes.core modules"
config:
helm_release_name: "acme-postgres"
namespace: "databases"
chart_repo_name: "bitnami"
chart_repo_url: "https://charts.bitnami.com/bitnami"
chart_name: "postgresql"
chart_version: "12.1.2"
postgres:
username: "app"
database: "appdb"
storage_size: "10Gi"
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
actions:
- name: install
description: "Install or upgrade PostgreSQL release"
playbook: install.yml
- name: upgrade
description: "Upgrade PostgreSQL Helm release to configured chart_version"
playbook: upgrade.yml
- name: rollback
description: "Rollback PostgreSQL Helm release to previous revision"
playbook: rollback.yml
- name: diff
description: "Show diff of pending changes for PostgreSQL Helm release"
playbook: diff.ymlWichtige Details:
chart_repo_url, chart_version, postgres.*) sitzen in config und sind damit:
Über das Block-Modell verhindert Polycrate den typischen Playbook-Wildwuchs, den viele Teams mit plain Ansible erleben. Alles, was zu diesem Chart gehört, sitzt in einem Block: block.poly, Playbooks, Templates.
Statt eine statische values.yaml pro Umgebung zu pflegen, generieren wir sie aus block.config. Das Template liegt im Block:
# blocks/registry.acme-corp.com/acme/helm/postgres-helm/templates/values.yml.j2
global:
postgresql:
auth:
username: "{{ block.config.postgres.username }}"
database: "{{ block.config.postgres.database }}"
primary:
persistence:
size: "{{ block.config.postgres.storage_size }}"
resources:
requests:
cpu: "{{ block.config.postgres.resources.requests.cpu }}"
memory: "{{ block.config.postgres.resources.requests.memory }}"
limits:
cpu: "{{ block.config.postgres.resources.limits.cpu }}"
memory: "{{ block.config.postgres.resources.limits.memory }}"Damit erreichst du:
block.config und ggf. workspace.blocks[].config definiert.Mit plain Helm würdest du typischerweise values-dev.yaml, values-prod.yaml und Kopien davon verwalten – oft mit Copy&Paste-Abweichungen, die niemand mehr im Blick hat.
Die Ansible-Module aus kubernetes.core sprechen das Kubernetes-API an. Da es sich um API-Calls handelt, ist hier hosts: localhost mit connection: local korrekt – der Code läuft im Polycrate-Container, nicht auf einem Remote-Host.
# blocks/registry.acme-corp.com/acme/helm/postgres-helm/install.yml
- name: Install or upgrade PostgreSQL Helm release
hosts: localhost
connection: local
gather_facts: false
vars:
release_name: "{{ block.config.helm_release_name }}"
namespace: "{{ block.config.namespace }}"
chart_repo_name: "{{ block.config.chart_repo_name }}"
chart_repo_url: "{{ block.config.chart_repo_url }}"
chart_name: "{{ block.config.chart_name }}"
chart_version: "{{ block.config.chart_version }}"
values_file: "{{ block.artifacts.path }}/{{ release_name }}-values.yml"
tasks:
- name: Ensure Helm repository is configured
kubernetes.core.helm_repository:
name: "{{ chart_repo_name }}"
repo_url: "{{ chart_repo_url }}"
state: present
- name: Render Helm values from template
ansible.builtin.template:
src: "templates/values.yml.j2"
dest: "{{ values_file }}"
- name: Install or upgrade PostgreSQL Helm release
kubernetes.core.helm:
name: "{{ release_name }}"
chart_ref: "{{ chart_repo_name }}/{{ chart_name }}"
release_namespace: "{{ namespace }}"
chart_version: "{{ chart_version }}"
values_files:
- "{{ values_file }}"
create_namespace: true
wait: true
atomic: true
state: presentGerenderte Values landen unter {{ block.artifacts.path }} (typisch artifacts/blocks/<block-name>/), nicht unter einem festen /workspace/-Pfad – siehe Artefakte und Best Practices.
Einmal gebaut, läuft das mit einem simplen Polycrate-Aufruf:
polycrate run postgres installIm Hintergrund startet Polycrate einen Container mit einer konsistenten Toolchain (Ansible, Python, kubectl, Helm – konfigurierbar per Dockerfile), wie in der Ansible-Integration beschrieben. Kubeconfig: Polycrate setzt KUBECONFIG / K8S_AUTH_KUBECONFIG – die kubernetes.core.helm*-Module brauchen kein kubeconfig: pro Task. Kein pip install, kein helm-Binary-Chaos, keine globalen Python-Interpreter – das löst das klassische Dependency-Problem von Automatisierungs-Stacks.
Mit plain Ansible müsstest du im Team:
kubernetes.core auf allen Laptops/Runnern installieren.ansible.cfg und Python-Umgebungen synchron halten.Polycrate nimmt dir das ab und sorgt dafür, dass die Actions überall identisch laufen.
Ein Upgrade ist aus Sicht von Helm nur ein weiteres helm upgrade. Wir modellieren das als eigene Action:
# blocks/registry.acme-corp.com/acme/helm/postgres-helm/upgrade.yml
- name: Upgrade PostgreSQL Helm release to configured chart_version
hosts: localhost
connection: local
gather_facts: false
vars:
release_name: "{{ block.config.helm_release_name }}"
namespace: "{{ block.config.namespace }}"
chart_repo_name: "{{ block.config.chart_repo_name }}"
chart_repo_url: "{{ block.config.chart_repo_url }}"
chart_name: "{{ block.config.chart_name }}"
chart_version: "{{ block.config.chart_version }}"
values_file: "{{ block.artifacts.path }}/{{ release_name }}-values.yml"
tasks:
- name: Ensure Helm repository is configured
kubernetes.core.helm_repository:
name: "{{ chart_repo_name }}"
repo_url: "{{ chart_repo_url }}"
state: present
- name: Render Helm values from template
ansible.builtin.template:
src: "templates/values.yml.j2"
dest: "{{ values_file }}"
- name: Upgrade PostgreSQL Helm release
kubernetes.core.helm:
name: "{{ release_name }}"
chart_ref: "{{ chart_repo_name }}/{{ chart_name }}"
release_namespace: "{{ namespace }}"
chart_version: "{{ chart_version }}"
values_files:
- "{{ values_file }}"
create_namespace: true
wait: true
atomic: true
state: presentDer Upgrade-Workflow in der Praxis:
Du passt die Chart-Version in block.poly oder im Workspace an, z. B.:
# workspace.poly – Ausschnitt
blocks:
- name: postgres
from: registry.acme-corp.com/acme/helm/postgres-helm:0.1.0
config:
chart_version: "12.2.0"Commit & Push – die Änderung ist damit nachvollziehbar versioniert.
Upgrade ausführen:
polycrate run postgres upgradeDu kombinierst damit:
Möchtest du diesen Block mit anderen Teams teilen? Push ihn in eine OCI-Registry, z. B.:
registry.acme-corp.com/acme/helm/postgres-helm:0.1.0(Öffentlich oder gehostet z. B. cargo.ayedo.cloud/....) Über die Registry-Dokumentation und PolyHub kannst du solche Blöcke team- oder organisationsweit teilen. Das ist Sharable Automation statt lokalem Helm-Skript.
Bevor du ein Upgrade durchführst, willst du oft wissen: Was ändert sich konkret? Dafür nutzen wir dry_run:
# blocks/registry.acme-corp.com/acme/helm/postgres-helm/diff.yml
- name: Show pending changes for PostgreSQL Helm release
hosts: localhost
connection: local
gather_facts: false
vars:
release_name: "{{ block.config.helm_release_name }}"
namespace: "{{ block.config.namespace }}"
chart_repo_name: "{{ block.config.chart_repo_name }}"
chart_repo_url: "{{ block.config.chart_repo_url }}"
chart_name: "{{ block.config.chart_name }}"
chart_version: "{{ block.config.chart_version }}"
values_file: "{{ block.artifacts.path }}/{{ release_name }}-values.yml"
tasks:
- name: Ensure Helm repository is configured
kubernetes.core.helm_repository:
name: "{{ chart_repo_name }}"
repo_url: "{{ chart_repo_url }}"
state: present
- name: Render Helm values from template
ansible.builtin.template:
src: "templates/values.yml.j2"
dest: "{{ values_file }}"
- name: Run Helm dry-run to show diff
kubernetes.core.helm:
name: "{{ release_name }}"
chart_ref: "{{ chart_repo_name }}/{{ chart_name }}"
release_namespace: "{{ namespace }}"
chart_version: "{{ chart_version }}"
values_files:
- "{{ values_file }}"
dry_run: true
state: presentAusführung:
polycrate run postgres diffDie Ausgabe zeigt dir, was Helm ändern würde, ohne etwas zu deployen. Du kannst das in Logs archivieren, an Auditor:innen weitergeben oder als Voraussetzung für ein manuelles Approval nutzen.
Wenn ein Upgrade schiefgeht, möchtest du möglichst wenig nachdenken müssen. Die Rollback-Action kapselt das in einem Befehl:
# blocks/registry.acme-corp.com/acme/helm/postgres-helm/rollback.yml
- name: Rollback PostgreSQL Helm release
hosts: localhost
connection: local
gather_facts: false
vars:
release_name: "{{ block.config.helm_release_name }}"
namespace: "{{ block.config.namespace }}"
tasks:
- name: Rollback to previous revision
kubernetes.core.helm_rollback:
name: "{{ release_name }}"
namespace: "{{ namespace }}"Ausführung:
polycrate run postgres rollbackOhne Polycrate/Ansible würdest du typischerweise:
helm history aufrufen,helm rollback postgres 12 von Hand tippen.Mit Polycrate wird das zu einer Action, die:
Helm direkt von der CLI ist weiterhin ein wichtiges Werkzeug. Eine ehrliche Abwägung:
Helm direkt ist sinnvoll, wenn:
Helm via Ansible in Polycrate ist im Vorteil, wenn:
Polycrate bringt dazu:
polycrate run postgres install) statt langer Ansible-CLI-Befehle.Mehr dazu findest du in den Best Practices für Blocks und den Best Practices zur Nutzung von Polycrate.
Für automatisierte Deployments via Polycrate: nein. Polycrate führt Ansible-Playbooks in einem Container aus, der Helm, kubectl, Python und die benötigten Collections enthält. Du musst auf deiner Workstation nur Polycrate bereitstellen, nicht Helm selbst.
Für lokale Experimente, Debugging oder schnelles Ausprobieren eines neuen Charts ist ein lokales Helm aber weiterhin praktisch. Viele Teams nutzen beides: Lokal Helm-CLI, in Automatisierung und CI/CD Ansible+Polycrate.
Konfigurationswerte wie Benutzername, Datenbankname oder Ressourcenlimits können problemlos in block.config liegen. Für Passwörter solltest du einen anderen Weg wählen:
artifacts/secrets/ und greife über workspace.secrets[...] zu.Das Schöne: Du brauchst keinen externen Vault, wenn du ein leichtgewichtiges, aber sicheres Setup möchtest – Polycrate bringt die nötige Verschlüsselung schon mit.
Ja. Du definierst pro Umgebung einen eigenen Block-Eintrag in workspace.poly mit eigener config – derselbe Block-Typ aus der Registry, mit gepinntem from::
blocks:
- name: postgres-dev
from: registry.acme-corp.com/acme/helm/postgres-helm:0.1.0
config:
namespace: "databases-dev"
chart_version: "12.1.2"
- name: postgres-prod
from: registry.acme-corp.com/acme/helm/postgres-helm:0.1.0
config:
namespace: "databases-prod"
chart_version: "12.2.0"Die Logik (Playbooks, Template) bleibt gleich; Namespace, Chart-Version und Ressourcen unterscheiden sich pro Instanz. Pro Workspace gibt es genau eine Kubeconfig (artifacts/secrets/kubeconfig.yml) – Polycrate integriert sie automatisch für Ansible. Zwei Einträge wie oben sind sinnvoll für dev vs. prod im selben Cluster (andere Namespaces). Für getrennte Cluster nutzt du typischerweise eigenen Workspace pro Cluster mit eigener kubeconfig, kannst aber denselben Registry-Block in jedem Workspace referenzieren.
Weitere Fragen? Siehe unsere FAQ
Mit dem PostgreSQL-Beispiel-Block hast du gesehen, wie sich Helm-Deployments in einen strukturierten, wiederverwendbaren Baustein verwandeln:
block.config und ist damit versioniert und teamfähig.values.yaml aus diesem Config-Modell.Aus Sicht von Platform- und Kubernetes-Teams ist das ein wichtiger Schritt: Weg von individuell gepflegten Helm-Skripten, hin zu wiederverwendbaren, per Registry teilbaren Blöcken, die andere Teams sofort nutzen können – oder die in einer zentralen Block-Bibliothek (intern oder über PolyHub) bereitstehen.
ayedo unterstützt genau diesen Weg: von ersten Helm-Deployments über strukturierte Polycrate-Workspaces bis hin zu unternehmensweiten Automatisierungsbibliotheken. In unseren Projekten kombinieren wir Ansible, Polycrate und Kubernetes-Lösungen, um wiederverwendbare Bausteine für Datenbanken, Messaging, Monitoring oder Security aufzubauen – inklusive Governance, Compliance und Dokumentation.
Wenn du Helm heute schon einsetzt und den nächsten Schritt hin zu reproduzierbaren, teamfähigen Deployments gehen willst, ist ein gemeinsamer Deep-Dive oft der effizienteste Weg. In unserem Helm-Workshop entwickeln wir mit deinem Team konkrete Blocks, Workspaces und Upgrade-Strategien – direkt an euren realen Charts und Clustern.
Mehr dazu erfährst du im persönlichen Austausch: Helm-Workshop
TL;DR Polycrate ist längst mehr als ein CLI-Tool: Mit PolyHub, API-Plattform und MCP entsteht ein …
TL;DR Polycrate ist nicht nur ein Deployment-Tool: Mit polycrate ssh und Block-Actions für kubectl …
TL;DR In Polycrate bedeutet Multi-Cluster automatisch Multi-Workspace: Ein Workspace verwaltet genau …