TL;DR
- Ansible kann Azure Entra ID (ehem. Azure AD) über die
azure.azcollectionvollständig automatisieren: Benutzer, Gruppen, App-Registrierungen und sogar die Dokumentation Ihrer Conditional Access Policies. - Mit Polycrate laufen alle Playbooks in einem reproduzierbaren Container: keine lokale Ansible-/Python-Installation, kein Versionschaos, kein “funktioniert bei mir”-Problem – die komplette Azure-Toolchain ist im Dockerfile.poly definiert.
- Ein dedizierter Service Principal dient als Automatisierungs-Account – mit klar begrenzten Rechten (Least Privilege) und sicher verschlüsselten Zugangsdaten im Workspace.
- Jede Änderung an Entra ID wird zu Code: Pull-Requests, Reviews und Git-History dienen als technischer Audit-Trail für Compliance, z.B. im Kontext von DSGVO oder internen Richtlinien.
- ayedo unterstützt Sie mit Polycrate, Best Practices und einem spezialisierten Azure-Automatisierungs-Workshop, in dem wir Ihr Entra-ID-Management gemeinsam industrialisieren.
Warum Entra ID automatisieren?
Für Windows-Admins und Azure-Admins hat sich das Zentrum der Identitätsverwaltung längst von klassischem On-Prem-AD zu Azure Entra ID verschoben. Benutzer, Gruppen und App-Registrierungen werden heute immer häufiger direkt dort gemanagt – oft aber noch per Portal-Klick.
Das funktioniert, bis eine der folgenden Situationen eintritt:
- Jemand ändert spontan eine Conditional Access Policy – und drei Wochen später weiß niemand mehr warum.
- Ein Kollege legt in der Nacht Benutzer an “damit es schnell geht” – ohne Change-Request, ohne Dokumentation.
- Das Onboarding neuer Mitarbeiter dauert, weil immer noch manuell Benutzer und Gruppenmitgliedschaften gepflegt werden.
Automatisierung mit Ansible löst genau diese Probleme:
- Alle Änderungen sind deklarativ beschrieben.
- Idempotenz sorgt dafür, dass der Zielzustand wiederholbar hergestellt wird.
- Git-Workflows liefern nachvollziehbare Change-Historie.
Mit Polycrate liegt diese Automatisierung nicht als lose Playbooksammlung auf mehreren Laptops, sondern als strukturierter Workspace, inklusive verschlüsselten Secrets und reproduzierbarer Container-Umgebung.
Polycrate + Ansible: saubere Umgebung für Azure-Automation
Bevor wir Benutzer und Gruppen in Entra ID anfassen, lohnt sich ein Blick auf das “Wie”.
Container statt lokaler Ansible-Installation
Das klassische Ansible-Problem für Azure kennen Sie vermutlich:
- Python-Versionen unterscheiden sich zwischen Teammitgliedern.
azure.azcollectionzieht eine halbe Azure-SDK-Landschaft nach sich.- Auf einem Host ist noch die alte Azure CLI, auf einem anderen gar keine.
Polycrate nimmt diesen Schmerz weg:
- Jede Action läuft im Polycrate-Container; optional erweitern Sie das Image per
Dockerfile.poly– dabei leiten Sie immer vom offiziellen Image ab (siehe unten). - Zusätzliche Ansible-Collections (wie
azure.azcollection) installieren Sie in genau dieser Erweiterung; Python undansible-corekommen aus dem Basis-Image. - Das gesamte Team arbeitet damit auf derselben Toolchain – egal ob Linux-, Mac- oder Windows-Workstation.
Details dazu finden Sie in der Ansible-Integration und den Best Practices.
azure.azcollection im Polycrate-Container installieren
Ein Dockerfile.poly muss immer vom offiziellen Polycrate-Image ausgehen (cargo.ayedo.cloud/library/polycrate), nicht von einem nackten python:-Image: Polycrate erwartet die mitgelieferte Toolchain, Mounts und Umgebung. Ein reines Python-Image würde als Action-Runtime nicht funktionieren. Hintergrund: Der Polycrate Container.
Zusätzliche Collections installierst du in einer dünnen Schicht darauf. Minimal könnte das so aussehen:
FROM cargo.ayedo.cloud/library/polycrate:latest
# requirements.yml für Collections (z. B. neben Dockerfile.poly im Workspace)
COPY requirements.yml /workspace/requirements.yml
# Azure Collection installieren (Ansible ist bereits im Polycrate-Base-Image)
RUN ansible-galaxy collection install -r /workspace/requirements.yml
WORKDIR /workspace
Die zugehörige requirements.yml:
---
collections:
- name: azure.azcollection
version: 1.18.0
Damit steht azure.azcollection im Polycrate-Container für alle Blöcke bereit – keine lokale Installation mehr nötig.
Workspace und Block für Entra-ID-Automation
Wir nutzen das Beispiel-Setup acme-corp-automation und legen einen dedizierten Block für Entra ID an.
workspace.poly: Block einbinden
name: acme-corp-automation
organization: acme
blocks:
- name: entra-id-mgmt
from: registry.acme.corp/blocks/entra-id-mgmt:0.1.0
config:
default_domain: "acme-corp.com"
azure_credentials_file: "artifacts/secrets/azure-sp.json"
Wichtig:
from:zeigt hier die Registry-Notation eines Blocks (<registry>/<pfad>:<version>).registry.acme.corpist nur ein fiktives Beispiel; in der Praxis nutzt du z. B.polycrate blocks pull …oder eure eigene OCI-Registry.- In
workspace.polyundblock.polygibt es kein Jinja2 –azure_credentials_fileist ein fester Pfad zur Datei unterartifacts/secrets/(nach Entschlüsselung im Container nutzbar). Im Ansible-Playbook greifst du weiter mit{{ block.config.azure_credentials_file }}zu. - Die Struktur und Arbeitsweise von Workspaces ist in den Workspace-Dokumentation beschrieben.
block.poly: Aktionen für Benutzer, Gruppen, Apps, Policies
Im Block-Verzeichnis blocks/entra-id-mgmt legen wir eine block.poly an:
name: entra-id-mgmt
version: 0.1.0
kind: ansible
config:
default_domain: ""
azure_credentials_file: ""
actions:
- name: users
description: "Benutzer in Entra ID verwalten"
playbook: users.yml
- name: groups
description: "Gruppen und Mitgliedschaften verwalten"
playbook: groups.yml
- name: apps
description: "App-Registrierungen und Service Principals verwalten"
playbook: apps.yml
- name: policies
description: "Conditional Access Policies dokumentieren (read-only)"
playbook: policies.yml
Unter config: stehen nur die erwarteten Schlüssel (hier mit leeren Defaults); kein Jinja2 in .poly-Dateien. Die konkreten Werte setzt du bei der Block-Instanz in workspace.poly (siehe oben).
Damit haben wir klare Guardrails:
- Jede Aufgabe ist eine klar benannte Action.
- Keine lose wachsende Playbook-Sammlung.
- Für Ihr Team entsteht eine einfache UX:
polycrate run entra-id-mgmt usersstatt komplexer Ansible-CLI-Aufrufe.
Mehr zu Blöcken und Actions finden Sie unter Blöcke und Actions.
Service Principal als Automatisierungs-Account
Für Entra-ID-Automation brauchen wir einen dedizierten Service Principal.
Rollen und Least Privilege
Je nachdem, was Sie automatisieren, benötigen Sie unterschiedliche Entra-Rollen. Ein gängiges Setup:
- Benutzer-Management: Rolle
User Administrator - Gruppen-Management: Rolle
Groups Administrator - App-Registrierungen: Rolle
Application Administratoroder feiner granulierte App-Registration-Berechtigungen
Best Practice:
- Einen eigenen “Automation”-Service-Principal anlegen.
- Nur die minimal notwendigen Rollen zuweisen.
- Zugangsdaten ausschließlich im Polycrate-Workspace verwenden (nicht lokal herumliegen lassen).
Zugangsdaten in einem Secret speichern
Legen Sie im Workspace die Datei artifacts/secrets/azure-sp.json an:
{
"client_id": "00000000-0000-0000-0000-000000000000",
"client_secret": "SUPER-GEHEIMER-WERT",
"tenant_id": "11111111-1111-1111-1111-111111111111",
"subscription_id": "22222222-2222-2222-2222-222222222222"
}
Konfigurieren Sie diese Datei über secrets.poly als zu verschlüsselndes Secret (Details in der Workspace-Verschlüsselung) und verschlüsseln Sie den Workspace anschließend:
polycrate workspace encrypt
Damit:
- Liegt die Datei verschlüsselt im Git-Repository.
- Stellt Polycrate sie im Container am konfigurierten Pfad (z. B.
artifacts/secrets/azure-sp.json) bereit. - Müssen Sie kein externes Tool wie Vault betreiben.
Benutzer verwalten mit azure_rm_aduser
Jetzt wird es konkret: Wir verwalten Entra-ID-Benutzer mit azure.azcollection.azure_rm_aduser.
users.yml: Benutzer anlegen, deaktivieren, löschen
Die Datei blocks/entra-id-mgmt/users.yml:
---
- name: Benutzer in Entra ID verwalten
hosts: localhost
connection: local
gather_facts: false
vars:
azure_credentials_file: "{{ block.config.azure_credentials_file }}"
default_domain: "{{ block.config.default_domain }}"
tasks:
- name: Azure Service Principal Credentials laden
ansible.builtin.include_vars:
file: "{{ azure_credentials_file }}"
name: azure
- name: Benutzer anlegen oder aktualisieren
azure.azcollection.azure_rm_aduser:
state: present
user_principal_name: "alice@{{ default_domain }}"
display_name: "Alice Example"
password: "InitialPassw0rd!"
account_enabled: true
force_password_change: true
tenant: "{{ azure.tenant_id }}"
client_id: "{{ azure.client_id }}"
secret: "{{ azure.client_secret }}"
auth_source: client_secret
register: alice_result
- name: Benutzer deaktivieren (Beispiel)
azure.azcollection.azure_rm_aduser:
state: present
user_principal_name: "bob@{{ default_domain }}"
display_name: "Bob Example"
account_enabled: false
tenant: "{{ azure.tenant_id }}"
client_id: "{{ azure.client_id }}"
secret: "{{ azure.client_secret }}"
auth_source: client_secret
- name: Benutzer löschen (Beispiel)
azure.azcollection.azure_rm_aduser:
state: absent
user_principal_name: "temp.user@{{ default_domain }}"
tenant: "{{ azure.tenant_id }}"
client_id: "{{ azure.client_id }}"
secret: "{{ azure.client_secret }}"
auth_source: client_secret
- name: Kurze Zusammenfassung ausgeben
ansible.builtin.debug:
msg: "Benutzerverwaltung abgeschlossen. Alice-Änderung: {{ alice_result.changed }}"
Wichtig:
hosts: localhostundconnection: localsind hier korrekt – das Playbook läuft im Polycrate-Container und spricht die Azure-APIs, nicht einen SSH-Host.- Die Credentials werden aus der verschlüsselten Datei geladen und nicht in der
block.polyoder im Playbook hinterlegt.
Ausführen der Action:
polycrate run entra-id-mgmt users
Mit plain Ansible müssten Sie dafür sorgen, dass lokal:
- Python, Ansible,
azure.azcollectionund alle Abhängigkeiten installiert sind. - Die Pfade zu Credential-Dateien auf jedem Admin-Laptop stimmen.
Mit Polycrate reicht es, den Workspace zu clonen, polycrate run zu nutzen, und alles läuft im definierten Container.
Gruppen und Mitgliedschaften mit azure_rm_adgroup
Gruppen sind das Herzstück von Berechtigungen in Entra ID. Das Prinzip ist identisch: deklarativ beschreiben, welche Gruppen existieren und welche Mitglieder dazugehören.
groups.yml: Gruppen und Mitglieder
---
- name: Gruppen in Entra ID verwalten
hosts: localhost
connection: local
gather_facts: false
vars:
azure_credentials_file: "{{ block.config.azure_credentials_file }}"
default_domain: "{{ block.config.default_domain }}"
tasks:
- name: Azure Service Principal Credentials laden
ansible.builtin.include_vars:
file: "{{ azure_credentials_file }}"
name: azure
- name: Sicherheitsgruppe "HR-Staff" sicherstellen
azure.azcollection.azure_rm_adgroup:
state: present
display_name: "HR-Staff"
mail_nickname: "hr-staff"
security_enabled: true
description: "HR Mitarbeiter"
tenant: "{{ azure.tenant_id }}"
client_id: "{{ azure.client_id }}"
secret: "{{ azure.client_secret }}"
auth_source: client_secret
register: hr_group
- name: Mitglieder in HR-Staff pflegen
azure.azcollection.azure_rm_adgroup:
state: present
display_name: "HR-Staff"
security_enabled: true
members:
# Beispiel UPNs, in der Praxis besser Object IDs verwenden
- "alice@{{ default_domain }}"
tenant: "{{ azure.tenant_id }}"
client_id: "{{ azure.client_id }}"
secret: "{{ azure.client_secret }}"
auth_source: client_secret
- name: Gruppe "Legacy-Group" löschen (falls noch vorhanden)
azure.azcollection.azure_rm_adgroup:
state: absent
display_name: "Legacy-Group"
tenant: "{{ azure.tenant_id }}"
client_id: "{{ azure.client_id }}"
secret: "{{ azure.client_secret }}"
auth_source: client_secret
Ausführen:
polycrate run entra-id-mgmt groups
So entsteht ein reproduzierbarer Zielzustand für Ihre Gruppen. Änderungen laufen über Pull-Requests und die Git-History dokumentiert, wann welche Gruppen angepasst wurden.
App-Registrierungen und Service Principals automatisieren
Viele Windows-/Azure-Teams haben Dutzende App-Registrierungen: Skripte, Automatisierungs-Accounts, Drittanbieter-Anwendungen. Diese manuell im Portal anzulegen, ist fehleranfällig.
apps.yml: App-Registrierung + Service Principal
---
- name: App-Registrierungen in Entra ID verwalten
hosts: localhost
connection: local
gather_facts: false
vars:
azure_credentials_file: "{{ block.config.azure_credentials_file }}"
tasks:
- name: Azure Service Principal Credentials laden
ansible.builtin.include_vars:
file: "{{ azure_credentials_file }}"
name: azure
- name: Anwendung "acme-hr-portal" registrieren
azure.azcollection.azure_rm_adapplication:
state: present
display_name: "acme-hr-portal"
identifier_uris:
- "api://acme-hr-portal"
reply_urls:
- "https://hr.acme-corp.com/auth/callback"
available_to_other_tenants: false
tenant: "{{ azure.tenant_id }}"
client_id: "{{ azure.client_id }}"
secret: "{{ azure.client_secret }}"
auth_source: client_secret
register: hr_app
- name: Service Principal für "acme-hr-portal" sicherstellen
azure.azcollection.azure_rm_adserviceprincipal:
state: present
app_id: "{{ hr_app.object_id }}"
tenant: "{{ azure.tenant_id }}"
client_id: "{{ azure.client_id }}"
secret: "{{ azure.client_secret }}"
auth_source: client_secret
- name: App-Details anzeigen
ansible.builtin.debug:
msg: "App acme-hr-portal registriert mit Object ID {{ hr_app.object_id }}"
Ausführen:
polycrate run entra-id-mgmt apps
Damit können Sie:
- App-Registrierungen für eigene Anwendungen konsistent anlegen.
- Service Principals gezielt für Automatisierung oder externe Integrationen bereitstellen.
- Änderungen sauber versionieren: z.B. neue Redirect-URLs oder zusätzliche Scopes.
Conditional Access Policies dokumentieren (read-only)
Conditional Access Policies sind sicherheitskritisch. Änderungen daran sollten nachvollziehbar und dokumentiert sein. Anstelle von manuellen Screenshots oder Excel-Listen können Sie diese mit Ansible auslesen und als JSON im Repository ablegen.
Ein vereinfachtes Beispiel für policies.yml, das die bestehenden Policies per Microsoft Graph ausliest und in einer Datei dokumentiert. Hier gehen wir davon aus, dass Sie ein Access-Token außerhalb des Playbooks erzeugen und im Secret ablegen (z.B. per kleinem Hilfsskript).
---
- name: Conditional Access Policies dokumentieren
hosts: localhost
connection: local
gather_facts: false
vars:
azure_credentials_file: "{{ block.config.azure_credentials_file }}"
tasks:
- name: Azure Service Principal Daten laden (inkl. access_token)
ansible.builtin.include_vars:
file: "{{ azure_credentials_file }}"
name: azure
- name: Conditional Access Policies via Microsoft Graph abrufen
ansible.builtin.uri:
url: "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies"
method: GET
headers:
Authorization: "Bearer {{ azure.access_token }}"
Content-Type: "application/json"
return_content: true
register: ca_policies
- name: Policies in Datei schreiben
ansible.builtin.copy:
dest: "artifacts/entra-id/conditional-access-policies.json"
content: "{{ ca_policies.content }}"
Ausführen:
polycrate run entra-id-mgmt policies
Der wichtige Punkt:
- Sie haben eine maschinenlesbare Momentaufnahme Ihrer Conditional Access Policies.
- Diese Datei landet im Git-Repo und jede Änderung ist differenzierbar.
- Bei Audits oder internen Reviews können Sie klar zeigen, wie sich Policies über die Zeit entwickelt haben.
Git als Audit-Trail für Entra-ID-Änderungen
Compliance-Anforderungen (z.B. aus der DSGVO, die seit dem 25.05.2018 gilt, oder aus internen Richtlinien) verlangen nachvollziehbare Prozesse:
- Wer hat wann welche Berechtigung geändert?
- Wie sah die Konfiguration zu einem bestimmten Stichtag aus?
- Welche Policies galten, als ein sicherheitsrelevantes Ereignis auftrat?
Mit Polycrate + Ansible + Git bekommen Sie das quasi “by design”:
- Jede Änderung an Benutzern, Gruppen, Apps oder Policies ist ein Commit.
- Pull-Requests, Reviews und Approvals bilden den Freigabeprozess ab.
- Durch die Workspace-Verschlüsselung bleiben Secrets geschützt, während der Rest offen revisioniert werden kann.
Statt manueller Excel-Listen oder Screenshots erhalten Sie eine saubere, technische Nachvollziehbarkeit.
Häufige Fragen
Brauche ich für diese Lösung zwingend Linux-Know-how?
Nein. Als Windows- oder Azure-Admin müssen Sie kein Linux-Experte sein. Polycrate kapselt die Linux-/Container-Seite in Dockerfile.poly. Sie arbeiten hauptsächlich mit YAML (Ansible-Playbooks, workspace.poly, block.poly) und führen Aktionen mit einfachen Befehlen wie:
polycrate run entra-id-mgmt users
Die Container-Laufzeit kümmert sich um Python, Ansible, azure.azcollection und alle Abhängigkeiten.
Was passiert, wenn Microsoft an den APIs oder Modulen etwas ändert?
Weil Ihre Automatisierung:
- Im Container läuft und
azure.azcollectionmit einer konkreten Version inrequirements.ymlgepinnt ist,
haben Sie einen stabilen Stand. Updates passieren kontrolliert:
- Sie passen die Collection-Version im Branch an.
- Sie bauen das neue Container-Image.
- Sie testen in einem Test-Tenant.
- Erst dann wird in Produktion gemerged.
So vermeiden Sie Überraschungen bei spontanen Modul- oder API-Änderungen.
Wie passt Polycrate in unsere bestehende Azure- und AD-Landschaft?
Polycrate ersetzt weder Ihr AD noch Azure selbst. Es ist die Schicht darüber, die:
- Ansible-Playbooks strukturiert (Block-Modell statt Playbook-Wildwuchs).
- Eine einheitliche Toolchain liefert (Container statt manueller Setups).
- Secrets handhabbar und verschlüsselt macht.
- Actions und Workflows bereitstellt, die auch Kolleg:innen ohne tiefes Ansible-Wissen ausführen können.
Sie können Polycrate schrittweise einführen – z.B. zunächst nur für Entra-ID-User-Management, später für weitere Azure- oder On-Prem-Aufgaben.
Weitere Fragen? Siehe unsere FAQ
Compliance in der Praxis
In diesem Beitrag haben Sie gesehen, wie Sie Entra ID mit Ansible und Polycrate strukturiert automatisieren:
- Benutzer, Gruppen und App-Registrierungen werden als Code beschrieben und wiederholbar angewendet.
- Die
azure.azcollectionläuft in einem klar definierten Container, der das klassische Dependency-Problem von Ansible auflöst. - Zugangsdaten Ihres Service Principals liegen verschlüsselt im Workspace, ohne dass zusätzliche Secret-Manager-Infrastruktur nötig ist.
- Conditional Access Policies lassen sich regelmäßig auslesen und als JSON im Repository dokumentieren – eine solide Basis für Audits und Sicherheitsreviews.
- Git wird zu Ihrem Audit-Trail: Pull-Requests, Reviews und die Commit-Historie machen Änderungen an Ihrer Identitätslandschaft nachvollziehbar.
Bei ayedo kombinieren wir genau diese Bausteine regelmäßig in Kundenprojekten: Polycrate-Workspaces, Ansible-Playbooks mit azure.azcollection, verschlüsselte Secrets und Git-basierte Prozesse. Für Windows- und Azure-Teams entsteht so ein Werkzeugkasten, mit dem sie eigenständig und sicher ihr Entra-ID-Management modernisieren können – ohne sich erst durch die komplette Cloud-Native-Welt kämpfen zu müssen.
Wenn Sie Ihre bestehende Entra-ID-Landschaft aufnehmen, automatisieren und gleichzeitig Compliance-Anforderungen sauber adressieren möchten, unterstützen wir Sie dabei in einem fokussierten Azure-Automatisierungs-Workshop – mit Ihrem Tenant, Ihren Richtlinien und Ihren Tools.