TL;DR
- Active-Directory-Änderungen per GUI oder unversionierten PowerShell-Skripten sind fehleranfällig, schlecht nachvollziehbar und kollaborativ kaum nutzbar – mit Ansible und Polycrate werden sie reproduzierbar, versioniert und teamfähig.
- Wir bauen einen Polycrate-Block für AD-Management, der Benutzer, Gruppen und OUs mit den Modulen
community.windows.win_domain_user,community.windows.win_domain_groupundcommunity.windows.win_domain_ouverwaltet – inklusive CSV-basiertem Bulk-Onboarding und Offboarding-Playbook mit Audit-Log. - Jeder Lauf hinterlässt Spuren im Git-Repository (CSV, Playbooks, Audit-Logs) und wird mit
polycrate workspace syncautomatisch committet: Ein sauberer Audit-Trail für Compliance-Anforderungen wie die DSGVO, die seit dem 25.05.2018 gilt. - Polycrate kapselt Ansible komplett im Container, inklusive aller Windows-/AD-Dependencies; kein Python-/Ansible-Chaos mehr auf Admin-Notebooks und klar strukturierte Blöcke statt Playbook-Wildwuchs.
- ayedo unterstützt Sie dabei, solche AD-Automatisierungen als wiederverwendbare, compliance-fähige Bausteine in Ihrer Organisation zu etablieren – von der Konzeption bis zur Integration in bestehende Prozesse.
Warum AD-Automatisierung bisher so mühsam war
Wenn Sie heute ein klassisches Active Directory verwalten, sieht der Alltag oft so aus:
- Benutzer werden in der MMC per Hand angelegt
- Gruppenmitgliedschaften werden „mal eben“ angepasst
- Gelegentlich existieren PowerShell-Skripte – aber ohne zentrale Versionierung, ohne Tests, oft nur auf einem Admin-Laptop
Das funktioniert, solange Sie wenige Changes haben und die gleichen zwei Personen alles machen. Spätestens wenn Teams wachsen, Audits dazukommen oder mehrere Standorte entstehen, wird es schwierig:
- Keine Nachvollziehbarkeit: Wer hat wann welche Gruppe geändert? Warum ist dieser Benutzer in der „Domain Admins“-Gruppe?
- Kein Audit-Trail: Für Compliance (z. B. DSGVO, interne Richtlinien, ISO 27001) brauchen Sie nachvollziehbare Änderungen – GUI-Klicks sind schwer nachweisbar.
- Skript-Wildwuchs: Jeder schreibt eigene PowerShell-Skripte, mit minimalen Variationen. Fehler lassen sich kaum reproduzieren.
- Dependency-Chaos: Das PowerShell-Skript vom Kollegen läuft bei Ihnen nicht, weil Module fehlen oder Versionen nicht passen.
Mit plain Ansible wird zwar einiges besser – Sie bekommen Idempotenz, verständliche YAML-Playbooks und ein mächtiges Ökosystem. Aber:
- Sie müssen Ansible, Python und die passenden Collections (z. B.
community.windows) auf jeder Maschine sauber installieren. - Versionen unterscheiden sich von Admin zu Admin.
- Geteilte Playbooks landen „irgendwo“ in Git ohne klare Struktur – der nächste Wildwuchs.
Genau hier setzt Polycrate an.
Polycrate + Ansible: strukturiertes AD-Management mit Audit-Trail
Polycrate macht aus Ihren Ansible-Playbooks versionierte, teilbare Blöcke und löst dabei mehrere typische Probleme:
- Dependency-Problem gelöst: Ansible läuft immer in einem Polycrate-Container. Die benötigten Collections (z. B.
community.windows) werden im Container-Image definiert. Kein lokales Ansible, kein Python-Wirrwarr, weniger Supply-Chain-Risiko. Mehr dazu in der Ansible-Integration von Polycrate. - Sharable Automation: Ihr AD-Block ist ein eigenständiges Artefakt, das Sie in einer OCI-Registry oder im PolyHub teilen können. Teams binden ihn per vollständiger Registry-Referenz in
from:ein (siehe Workspace-Beispiel unten). - Guardrails statt Playbook-Wildwuchs: Durch das Block-Modell sind Actions (Onboarding, Offboarding, OU-Setup) klar getrennt. Kein „alles in einem riesigen Playbook“ mehr.
- Compliance-ready:
- Git-Versionierung des gesamten Workspaces, inklusive Audit-Logs.
- Automatische Commits über
polycrate workspace sync(siehe Git-Integration von Polycrate). - Workspace-Verschlüsselung mit age, um Passwörter und Inventories geschützt abzulegen (siehe Workspace-Verschlüsselung).
Wir bauen im Folgenden einen Workspace mit einem AD-Management-Block, der:
- OUs anlegt
- Benutzer aus einer CSV-Datei importiert
- Gruppen anlegt und Mitglieder pflegt
- Offboarding mit Deaktivierung, Gruppenentfernung und Audit-Log automatisiert
Workspace für AD-Management vorbereiten
Zuerst legen wir den Workspace acme-corp-automation an und definieren unseren AD-Block sowie das Inventory.
workspace.poly
name: acme-corp-automation
organization: acme
blocks:
- name: ad-mgmt
from: registry.acme-corp.com/acme/infra/ad-mgmt:1.0.0
config:
domain_name: "acme-corp.com"
default_ou: "OU=Users,DC=acme-corp,DC=com"
from: enthält die vollständige OCI-Registry-Referenz inklusive Versions-Tag am Ende der Zeile (wie bei Container-Images); ein separates version-Feld unter der Block-Instanz gibt es nicht. Im Block-Paket trägt block.poly denselben logischen Namen (ad-mgmt). Die Registry registry.acme-corp.com ist ein Beispiel (kein Bezug zu ayedos Produkt-Registry). Fehlt der Block lokal, kann Polycrate ihn beim ersten polycrate run … aus der Registry nachziehen; ausgepackt liegt er unter blocks/registry.acme-corp.com/acme/infra/ad-mgmt/. Mehr dazu im Beitrag Multi-Server-Management mit Ansible-Inventories.
Mehr zu Workspaces finden Sie in der Dokumentation zu Polycrate Workspaces.
Inventory für den Domain Controller
Polycrate erwartet ein YAML-Inventory im Workspace-Root als inventory.yml. Alle Hosts stehen unter all.hosts; unter children verweist die Gruppe domain_controllers nur noch per Hostname – gemeinsame WinRM-Einstellungen liegen in vars der Gruppe. Keine Passwörter im Inventory – ansible_password setzen Sie in den Playbooks aus secrets.poly / workspace.secrets.* (siehe Workspace-Verschlüsselung). Für einen Domain Controller dc01.acme-corp.com kann das so aussehen:
all:
hosts:
dc01.acme-corp.com: {}
children:
domain_controllers:
hosts:
dc01.acme-corp.com:
vars:
ansible_user: Administrator
ansible_connection: winrm
ansible_port: 5986
ansible_winrm_transport: credssp
ansible_winrm_server_cert_validation: ignore
Wichtig:
- Dieses Inventory wird von Polycrate verwendet, um die Windows-Hosts via WinRM anzusprechen (siehe auch Ansible-Dokumentation und das Muster in Multi-Server-Management mit Ansible-Inventories).
- Passwörter und weitere Secrets gehören in
secrets.polyund werden in den Playbooks als Variablen eingebunden, nicht als Klartext iminventory.yml. - Den gesamten Workspace schützen Sie mit
polycrate workspace encrypt(siehe Workspace-Verschlüsselung).
WinRM-Passwort für die Playbooks: In secrets.poly legen Sie z. B. ad_dc_password ab; in jedem Play gegen domain_controllers setzen Sie darunter vars: zusätzlich ansible_password: "{{ workspace.secrets.ad_dc_password }}" (die folgenden Beispiele enthalten das).
Der AD-Block: block.poly definieren
Unser Block blocks/registry.acme-corp.com/acme/infra/ad-mgmt/block.poly (nach dem Pull aus der Registry) kapselt alle AD-Aktivitäten:
name: ad-mgmt
version: 0.1.0
kind: generic
config:
domain_name: "acme-corp.com"
default_ou: "OU=Users,DC=acme-corp,DC=com"
users_csv: "users.csv"
audit_log: "audit.log"
actions:
- name: setup_ou_and_groups
playbook: setup_ou_and_groups.yml
- name: onboarding
playbook: onboarding.yml
- name: offboarding
playbook: offboarding.yml
config.*-Werte können Sie im Workspace bei Bedarf überschreiben.- Die Playbooks liegen im Block-Verzeichnis (Registry-Pfad unter
blocks/…). Laufzeitdaten wie CSV und Audit-Log legen Sie nicht im Block ab, sondern unterartifacts/blocks/<Block-Instanzname>/im Workspace – z. B.artifacts/blocks/ad-mgmt/users.csv. In Ansible zeigtblock.artifacts.pathauf genau dieses Verzeichnis (im Container:/workspace/artifacts/blocks/<name>/).
Weitere Details zu Blocken finden Sie in den Polycrate Blocke-Docs.
CSV-basiertes Bulk-Onboarding von AD-Benutzern
Beispiel-CSV für Benutzer
Legen Sie die Datei im Workspace unter artifacts/blocks/ad-mgmt/users.csv an (nicht im Block-Verzeichnis unter blocks/…). Polycrate stellt den Pfad in Playbooks als {{ block.artifacts.path }} bereit (entspricht artifacts/blocks/ad-mgmt/ im Workspace).
username;givenName;sn;password;enabled;ou_dn;groups
jdoe;John;Doe;Start123!;true;OU=IT,OU=Users,DC=acme-corp,DC=com;IT-Admins,VPN-Users
mroe;Maria;Roe;Start123!;true;;Sales,VPN-Users
ou_dnist optional – fehlt er, verwenden wirdefault_ou.groupsist eine durch Komma getrennte Liste.
Playbook: Onboarding mit win_domain_user und win_domain_group
Das Onboarding besteht aus zwei Plays:
- CSV im Polycrate-Container einlesen (localhost, erlaubt, weil nur Dateien gelesen werden)
- Benutzer und Gruppen auf dem Domain Controller pflegen
# blocks/registry.acme-corp.com/acme/infra/ad-mgmt/onboarding.yml
- name: Load users from CSV in Polycrate container
hosts: localhost
gather_facts: false
vars:
users_csv: "{{ block.artifacts.path }}/{{ block.config.users_csv }}"
tasks:
- name: Read users from CSV
community.general.read_csv:
path: "{{ users_csv }}"
delimiter: ";"
register: csv_users
- name: Normalize user list
ansible.builtin.set_fact:
ad_users: "{{ csv_users.list }}"
- name: Create OUs and groups on domain controllers
hosts: domain_controllers
gather_facts: false
vars:
ansible_password: "{{ workspace.secrets.ad_dc_password }}"
domain_name: "{{ block.config.domain_name }}"
default_ou: "{{ block.config.default_ou }}"
tasks:
- name: Ensure base OU exists
community.windows.win_domain_ou:
name: "{{ default_ou }}"
state: present
- name: Ensure department OUs from CSV exist
community.windows.win_domain_ou:
name: "{{ item.ou_dn }}"
state: present
loop: "{{ hostvars['localhost'].ad_users | map(attribute='ou_dn') | list | unique }}"
when: item.ou_dn is defined and item.ou_dn | length > 0
- name: Collect all group names from CSV
ansible.builtin.set_fact:
all_groups: >-
{{ hostvars['localhost'].ad_users
| map(attribute='groups')
| select('defined')
| map('split', ',')
| sum(start=[])
| map('trim')
| reject('equalto', '')
| list }}
run_once: true
- name: Ensure groups exist
community.windows.win_domain_group:
name: "{{ item }}"
scope: global
state: present
loop: "{{ all_groups | default([]) }}"
run_once: true
- name: Ensure AD users exist and are in the right groups
community.windows.win_domain_user:
name: "{{ item.username }}"
upn: "{{ item.username }}@{{ domain_name }}"
given_name: "{{ item.givenName }}"
surname: "{{ item.sn }}"
password: "{{ item.password }}"
enabled: "{{ (item.enabled | default('true')) | bool }}"
path: "{{ item.ou_dn | default(default_ou) }}"
state: present
groups: >-
{{ (item.groups | default(''))
| split(',')
| map('trim')
| reject('equalto', '')
| list }}
loop: "{{ hostvars['localhost'].ad_users }}"
run_once: true
Was passiert hier?
- CSV-Einlesen im Container:
community.general.read_csvläuft auflocalhostim Polycrate-Container. Es verändert keine Zielsysteme, daher isthosts: localhosthier korrekt. - OU-Management: Mit
community.windows.win_domain_oulegen wir zunächst eine Basis-OU an und dann ggf. zusätzliche OUs aus den CSV-Daten. - Gruppenverwaltung:
community.windows.win_domain_grouperstellt alle in der CSV referenzierten Gruppen. - Benutzerverwaltung:
community.windows.win_domain_userlegt Benutzer an oder aktualisiert sie idempotent, inklusive OU, Passwort, Status und Gruppen.
Mit plain Ansible ohne Polycrate müssten Sie:
- Ansible und alle Collections lokal installieren.
- Sicherstellen, dass
community.windowsüberall gleich verfügbar ist. - Playbooks und CSV manuell mit Git verknüpfen.
Mit Polycrate reicht ein strukturierter Block und ein reproduzierbarer Container.
Onboarding ausführen
Vom Workspace-Root aus:
cd ~/workspaces/acme-corp-automation
polycrate run ad-mgmt onboarding
Polycrate kümmert sich um:
- Start des Containers mit der richtigen Ansible- und Collection-Version
- Bereitstellung des Workspaces im Container
- Übergabe des Inventories
Offboarding-Playbook mit Audit-Log
Beim Offboarding wollen Sie:
- Benutzer deaktivieren
- Aus Gruppen entfernen
- Optional in eine „Disabled Users“-OU verschieben
- Einen nachvollziehbaren Audit-Eintrag schreiben
Offboarding-Playbook
# blocks/registry.acme-corp.com/acme/infra/ad-mgmt/offboarding.yml
- name: Disable AD user and clean up group memberships
hosts: domain_controllers
gather_facts: false
vars:
ansible_password: "{{ workspace.secrets.ad_dc_password }}"
domain_name: "{{ block.config.domain_name }}"
disabled_ou: "OU=Disabled Users,DC=acme-corp,DC=com"
username: "{{ username }}"
tasks:
- name: Ensure OU for disabled users exists
community.windows.win_domain_ou:
name: "{{ disabled_ou }}"
state: present
- name: Disable user and move to disabled OU
community.windows.win_domain_user:
name: "{{ username }}"
upn: "{{ username }}@{{ domain_name }}"
enabled: false
path: "{{ disabled_ou }}"
state: present
- name: Remove user from sensitive groups
community.windows.win_domain_group:
name: "{{ item }}"
state: present
members:
- "{{ username }}"
members_state: absent
loop:
- "IT-Admins"
- "Domain Admins"
- "VPN-Users"
- name: Write audit log entry in Polycrate workspace
hosts: localhost
gather_facts: false
vars:
audit_log: "{{ block.artifacts.path }}/{{ block.config.audit_log }}"
tasks:
- name: Append audit log entry
ansible.builtin.lineinfile:
path: "{{ audit_log }}"
line: "{{ lookup('ansible.builtin.pipe', 'date -u +%Y-%m-%dT%H:%M:%SZ') }};{{ username }};offboarded"
create: yes
insertafter: EOF
Hinweise:
- Der erste Play läuft auf den Domain Controllern und nutzt Windows-spezifische Module.
- Der zweite Play läuft wieder im Polycrate-Container (
localhost) und schreibt insaudit.logunter{{ block.artifacts.path }}(Workspace:artifacts/blocks/ad-mgmt/). Dieses File ist Teil des Workspaces und wird damit versioniert und verschlüsselt.
Offboarding für einen Benutzer ausführen
Den Benutzer über ein Extra-Var übergeben:
cd ~/workspaces/acme-corp-automation
polycrate run ad-mgmt offboarding -- -e "username=jdoe"
Der Doppelstrich -- trennt die Polycrate-Argumente von den Argumenten, die an ansible-playbook gehen.
Änderungen versionieren und Audit-Trail sicherstellen
Die eigentliche Stärke für Compliance entsteht durch die Kombination:
- Playbooks + CSV + Audit-Logs im Git-Repository
- Automatisierte Commits mit Polycrate
Nach einem Onboarding- oder Offboarding-Lauf:
- Wurde ggf.
users.csvgeändert (z. B. neue Benutzer). - Wurde
audit.logum einen Eintrag erweitert. - Sind Ihre Playbooks und Block-Definitionen unverändert oder angepasst.
Mit Polycrate halten Sie den Workspace synchron zu Git, z. B.:
cd ~/workspaces/acme-corp-automation
polycrate workspace sync
Polycrate:
- Erkennt Änderungen im Workspace.
- Erstellt einen Commit mit sinnvollem Commit-Text.
- Optional pusht es in Ihr zentrales Git-Repository (je nach Konfiguration).
Details dazu finden Sie in der Git-Integration von Polycrate.
Der Compliance-Vorteil gegenüber GUI-Klicks oder losen PowerShell-Skripten:
- Jede AD-Änderung ist über Playbooks und CSV-Daten nachvollziehbar.
- Jeder Lauf hinterlässt einen Commit mit Timestamp und Diff.
- Das
audit.logbietet eine zusätzliche, menschenlesbare Übersicht („wann wurde welcher Benutzer offboarded?“).
In Audits oder bei forensischen Analysen ist das Gold wert.
Block teilen und im Unternehmen standardisieren
Sie entwickeln den Block im Workspace unter dem registry-kompatiblen Verzeichnis, das zu Ihrer späteren from:-Referenz passt – z. B. blocks/registry.acme-corp.com/acme/infra/ad-mgmt/ (Registry-Host und Pfad wie in der OCI-Referenz ohne Versionstag), nicht unter einem verkürzten Pfad wie ./blocks/ad-mgmt/. Anschließend veröffentlichen Sie ihn in Ihrer OCI-Registry oder im PolyHub – andere Workspaces beziehen ihn dann mit vollständiger from:-Referenz und Versionstag, wie im ersten workspace.poly-Beispiel. Dasselbe Verzeichnisprinzip gilt für die Polycrate-Registry cargo (blocks/cargo.ayedo.cloud/…). Alternativ (oder zusätzlich) nutzen Sie z. B. cargo in from: – Beispiel:
blocks:
- name: ad-mgmt
from: cargo.ayedo.cloud/acme/infra/ad-mgmt:0.1.0
config:
domain_name: "acme-corp.com"
default_ou: "OU=Users,DC=acme-corp,DC=com"
Dadurch:
- Nutzen andere Teams exakt denselben, getesteten AD-Block.
- Sie können neue Versionen (z. B.
0.2.0) ausrollen, ohne bestehende Workspaces zu brechen. - Automatisierung wird zu einem unternehmensweiten Standardbaustein, nicht zu einer Sammlung individueller Skripte.
Mehr dazu in der Dokumentation zu Registry und PolyHub.
Häufige Fragen
Muss ich auf meinem Admin-Notebook noch Ansible oder zusätzliche Python-Pakete installieren?
Nein. Polycrate bringt ein Container-Image mit, in dem Ansible, Python und benötigte Collections wie community.windows bereits installiert sind. Sie führen nur polycrate run ... aus, Polycrate startet den Container, bindet den Workspace ein und ruft ansible-playbook im Container auf.
Vorteile:
- Alle Admins nutzen dieselbe Toolchain – keine Versions-Konflikte.
- Sie reduzieren das Risiko, dass jemand „mal eben“ ein Modul auf einem Notebook aktualisiert und damit Playbooks bricht.
- Sie haben eine klare Supply-Chain: Das Container-Image ist Ihr definierter „Control Node“.
Wie schütze ich Passwörter und sensible Daten im Workspace?
Der Workspace kann mit polycrate workspace encrypt über age verschlüsselt werden. Damit lassen sich Dateien wie:
secrets.polyund verschlüsselte Artefakte (AD-Credentials, keine Klartext-Passwörter iminventory.yml)- CSV-Dateien mit temporären Initialpasswörtern
- zusätzliche Secret-Files
verschlüsselt im Git-Repository ablegen. Nur berechtigte Personen mit den passenden Schlüsseln können den Workspace entschlüsseln.
Details finden Sie in der Dokumentation zur Workspace-Verschlüsselung.
Kann ich den AD-Block in mehreren Domains oder Umgebungen (z. B. Test/Prod) nutzen?
Ja. Über blocks.config im workspace.poly können Sie pro Workspace (oder sogar pro Umgebung) andere Parameter setzen, z. B.:
domain_namedefault_ou- andere CSV-Dateien
Für Test- und Produktionsumgebungen legen Sie einfach getrennte Workspaces an, die denselben Block aus der Registry referenzieren, aber andere Konfigurationen und Inventories haben. So bleibt die Logik identisch, während Ziele und Daten je Umgebung variieren.
Weitere Fragen? Siehe unsere FAQ
Compliance in der Praxis
Mit dem hier gezeigten AD-Block haben Sie einen wichtigen Schritt getan:
- AD-Benutzer, Gruppen und OUs werden deklarativ beschrieben, nicht per Hand geklickt.
- Bulk-Onboarding aus CSV, Offboarding mit Deaktivierung und Gruppenbereinigung – alles nachvollziehbar und wiederholbar.
- Durch Git-History,
polycrate workspace syncund das Audit-Log entstehen prüfbare Spuren, die bei Audits, Pen-Tests oder internen Kontrollen überzeugen. - Polycrate nimmt Ihnen den operativen Ballast: keine lokale Ansible-Installation, keine unkontrollierten Skripte, klare Struktur durch das Block-Modell.
Als ayedo begleiten wir Organisationen dabei, genau solche Automatisierungen systematisch aufzubauen – von der ersten AD-Action bis zu ganzen Landschaften aus standardisierten Polycrate-Blöcken. Ob Sie „nur“ das Onboarding/Offboarding verbessern oder ein umfassendes Policy-as-Code-Modell für Ihr Active Directory etablieren wollen: Wir bringen die Erfahrung aus Platform Engineering, Windows- und Compliance-Projekten zusammen.
Wenn Sie sehen möchten, wie dieses Setup in Ihrer Umgebung aussehen kann und welche Erweiterungen (z. B. automatische GPO-Zuordnung oder Integration in Ihr HR-System) sinnvoll sind, lohnt sich ein gemeinsamer Blick auf Ihre Anforderungen: