Windows Server mit Ansible automatisieren (Beispiel Windows Updates)

Es muss ja nicht immer gleich SCCM sein… Ich war auf der Suche nach einer Möglichkeit, möglichst viele meiner langweiligen Aufgaben für meine eignen Systeme zu automatisieren: Backup bzw. Spiegelung der Website auf das NAS, Installation von Updates (Windows / Linux), Installation von Testumgebungen. Eben immer wieder wiederholbarer, langweiliger, zeitfressender Kram, wie gemacht für die Automatisierung und zentrale Steuerung. Ich bin dann nach einigen Tests bei Ansible gelandet, um möglichst viele Aufgaben zu automatisieren. Mittlerweile (zugegeben nach einigen Fehlschlägen) läuft es rund, daher gibt es hier mal einen kleinen Einstieg in das Thema Automatisierung mittels Ansible. Da es mein erster Anwendungsfall war, habe ich mir für das erste Beispiel das Thema Windows Updates ausgesucht.

CentOS 8 Installation

Ich nutze normalerweise Debian für die meisten meiner Linux basierten Server, in der letzten Zeit habe ich allerdings immer mehr Gefallen an CentOS gefunden. Meine privaten Systeme stelle ich gerade von Debian auf CentOS um, daher setzt nun auch dieser Artikel auf CentOS als Betriebssystem für Ansible (falls sich jemand wundern sollte, warum nicht Debian zum Einsatz kommt).

Die Installation von CentOS ist selbsterklärend, daher gibt es hier nur ein paar Screenshots zu meinem Setup:

CentOS 8 Installation

Da ich CentOS als VM betreibe habe ich “Server” und “Gast-Agenten” ausgewählt:

CentOS 8 Installation

Während der Installation können Root-Password festgelegt und ein Benutzer erstellt werden:

CentOS 8 Installation

Nach ein paar Minuten ist CentOS fertig installiert:

CentOS 8 Installation

Nach der Installation wurden lediglich noch eine IP Adresse und DNS Server, sowie die Zeitsynchronisation via NTP konfiguriert. Nachdem die CentOS Installation abgeschlossen ist, kann Ansible installiert werden.

Ansible Installation

Für die Ansible Installation kann PIP (python installs packages) verwendet werden. Damit dies funktioniert, muss zunächst Python installiert werden. Die Installation von Python kann mit den folgenden Befehlen durchgeführt werden:

1
sudo dnf install python3 python3-pip python3-devel

Ansible Installation

Nach Python kann Ansible mit dem folgenden Befehl installiert werden:

1
sudo pip3 install ansible

Ansible Installation

Die Installation habe ich übrigens bewusst via PIP durchgeführt, bei der Installation von Ansible über das normale CentOS Repo, habe ich es nicht geschafft alle Komponenten erfolgreich lauffähig zu bekommen. Wenn die Installation mittels PIP erfolgte, gab es bei mir keine Probleme.

Ansible ist jetzt bereits installiert, damit später auch Windows Server mittels WinRM verwaltet werden können, ist noch das Paket PyWinRM erforderlich. Das Paket kann mit dem folgenden Befehl installiert werden:

1
sudo pip3 install pywinrm

Ansible Installation

Nachdem Ansible installiert wurde, kann es mit der Grundkonfiguration weiter gehen.

Ansible Grundkonfiguration

Da die Installation von Ansible mittels PIP durchgeführt wurde, fehlen noch zwei grundlegende Dateien für die Konfiguration von Ansible. Die erforderlichen Dateien können aber einfach runtergeladen und im entsprechenden Verzeichnis angelegt werden. Ansible lädt diese Dateien dann zur Laufzeit.

Um das Verzeichnis anzulegen und die Konfigurationsdateien runterzuladen können die folgenden Befehle verwendet werden:

1
2
3

Ansible Grundkonfiguration

Die Datei ansible.cfg muss zunächst nicht angepasst werden. In der Datei “hosts” werden später die zu verwaltenden Server angegeben.

Ansible Authentifizierung mittels Kerberos

Die Verwaltung von Windows Servern mit Ansible würde jetzt bereits mittels WinRM funktionieren, allerdings aktuell nur mit einem lokalen Benutzer auf dem jeweiligen Server. Die Verwendung von Active Directory Benutzerkonten und die Authentifizierung mittels Kerberos ist hier allerdings der elegantere Weg, zumal auch die Verwaltung einiger Dienste auf Windows Servern nur mit Active Directory Benutzern funktionieren (die Automatisierung von Exchange Servern wäre hier ein Beispiel).

Damit die Anmeldung von Ansible an Windows Servern mittels AD Benutzer und Kerberos funktioniert, müssen noch einmal ein paar Pakete nachinstalliert werden.

1
sudo dnf install gcc krb5-devel krb5-libs krb5-workstation

Ansible Authentifizierung mittels Kerberos

In der Datei /etc/krb5.conf muss nun die Verbindung zum Active Directory konfiguriert werden. In der Datei werden dazu in der Sektion “realms” die Domain Controller und in der Sektion “domain_realm” der Name des Active Directory.

In meiner Testumgebung sieht dies beispielsweise wie folgt aus (Groß/Kleinschreibung beachten):

Ansible Authentifizierung mittels Kerberos

Mit dem folgenden Befehl lässt sich nun testen, ob die Authentifizierung mittels Kerberos funktioniert:

1
kinit Administrator@FRANKYSWEBLAB.DE

Wenn der Befehl keine Fehlermeldung liefert, ist alles in Ordnung. Mit dem Befehl “klist” kann zusätzlich geprüft werden, ob ein Kerberos Ticket ausgestellt wurde:

Ansible Authentifizierung mittels Kerberos

Zum Schluss muss nun noch die Kerberos Unterstützung für PyWinRM installiert werden:

1
sudo pip3 install pywinrm[kerberos]

Ansible Authentifizierung mittels Kerberos

Ansible kann nun auch Active Directory Benutzer und Kerberos für die Authentifizierung am Windows Server verwenden.

Gruppen und Hosts erstellen

Server die via Ansible verwaltet werden sollen, müssen in der Datei /etc/ansible/hosts bekannt gemacht werden. Einzelne Server können innerhalb der Datei zu Hostgruppen zusammengefasst werden. Hier mal ein Beispiel meiner /etc/ansible/hosts Datei:

Gruppen und Hosts erstellen

In der Datei findet sich beispielsweise die Gruppe “exchangeserver”. Die Server ex1 und ex2 sind Mitglied der Gruppe exchangeserver (erster Kasten im Screenshot). Im zweiten Kasten finden Sie die Umgebungsvariablen für die Gruppe, der Einfachheit halber habe ich hier auch die Anmeldeinformationen hinterlegt. Des weiteren gibt es noch die Gruppe “windowsserver”, diese Gruppe enthält alle Hostgruppen mit Windows Systemen:

Gruppen und Hosts erstellen

Die relevanten Dateien habe ich am Ende des Artikels als Download zusammengefasst. Falls jemand dies also nachbauen möchte, muss hier nicht alles abgetippt werden.

Windows Systeme konfigurieren

Damit Ansible per WinRM auf die Windows Server zugreifen kann, muss WinRM entsprechend konfiguriert werden. Die Konfiguration von WinRM ist dank eines PowerShell Scripts sehr einfach möglich. Das Script kann hier runtergeladen werden:

Das Script muss als Administrator auf jedem Windows Server ausgeführt werden, der mittels Ansible verwaltet werden soll.

Windows Systeme konfigurieren

Das Script erstellt ein selbst signiertes Zertifikat und konfiguriert WinRM entsprechend. Die Verbindung vom Ansible Server zum Windows Server erfolgt über den Port 5986, die Windows Firewall wird automatisch konfiguriert, falls weitere Firewalls zum Einsatz kommen, müssen diese die Kommunikation via Port 5986 zulassen.

Verbindung testen

Die Vorbereitungen sind nun soweit abgeschlossen und es kann getestet werden, ob Ansible eine Verbindung zu den konfigurierten Windows Servern herstellen kann. Für den Test der Verbindung kann der folgende Befehl verwendet werden:

1
ansible GRUPPENNAME -m win_ping

Dieser Befehl führt das Module win_ping (WinRM basierter Test) zu den Mitgliedern einer Gruppe aus:

Verbindung testen

Im Screenshot ist zu sehen, wie die einzelnen Gruppen getestet werden können. Falls es hier zu Problemen kommt, dann mal als ersten prüfen, ob die Server via DNS aufgelöst werden und die Anmeldeinformationen korrekt sind. Ist die Verbindung erfolgreich, kann man sein erstes Playbook erstellen.

Playbook für Windows Updates erstellen

Playbooks dienen dazu eine Abfolge von Aktionen auf den Zielsystemen auszuführen. In diesem Abschnitt wird ein einfaches Playbook für die Installation von Windows Updates erstellt. Dieses Playbook dient erst einmal nur als Beispiel, wer sich ein wenig in Ansible einarbeitet, kann hier aber schnell komplexere Sachen umsetzen.

Zunächst kann eine Verzeichnisstruktur für die Playbooks erzeugt werden, so lassen sich die Playbooks später einfacher wiederfinden. In diesem Beispiel wird das Verzeichnis “ansible-playbooks” und das Unterverzeichnis “windows” angelegt. Im Ordner “windows” können dann alle Playbooks für Windows Systeme gespeichert werden. Die Verzeichnis Struktur ist hier natürlich frei wählbar:

1
2
mkdir /ansible_playbooks
mkdir /ansible_playbooks/windows

Jetzt kann das erste Playbook im Ordner “windows” angelegt werden. Mit dem Playbook werden in diesem Beispiel die Windows Updates auf den Windows Servern installiert:

1
touch /ansible_playbooks/windows/install_updates.yaml

Das erste Playbook bekommt den folgenden Inhalt:

Playbook für Windows Updates erstellen

Der erste Step installiert Windows Updates auf Servern der Gruppe “fileserver” (hosts: fileserver). Wenn es mehrere Hosts in der Gruppe Fileserver gibt, werden die Updates parallel auf den Servern installiert (strategy: free). Der Task definiert welche Aktion durchgeführt werden soll. In diesem Fall werden kritische und Sicherheitsupdates installiert und die Server bei Bedarf neu gestartet. Im nächsten Step sind dann die Domaincontroller dran, danach die Hosts der Gruppe “exchangeserver”.

Dieses einfache Playbook ist nur ein kleines Beispiel. Wenn man sich hier ein bisschen einarbeitet, lässt sich mittels Ansible vieles automatisieren. Auch dieses Beispiel findet sich am Ende des Artikels als Download.

Ich hab mir beispielsweise den Updatevorgang für meine private Umgebung automatisiert, dies läuft dann wie folgt ab:

  1. VMware Snapshots für alle virtuellen Server erzeugen, welche Updates erfordern
  2. Updates auf Windows und Linux Servern installieren
  3. Neustart der Server durchführen, wenn dies erforderlich ist
  4. E-Mail Benachrichtigung versenden
  5. 2 Tage später Snapshot löschen

Im Download am Ende des Artikels findet sich auch ein Beispiel, wie eine Exchange DAG aktualisiert werden kann.

Playbook ausführen

Zuvor angelegte Playbooks lassen sich mit dem Befehl “ansible-playbook” ausführen. In diesem Beispiel wird das zuvor angelegte Playbook ausgeführt:

1
ansible-playbook install_updates.yml

Ansible führt nun die Schritte aus dem Playbook auf den Servern aus:

Playbook ausführen

Wie man im Screenshot oben sehen kann, reicht nun ein Befehl aus, um alle Windows Server in der entsprechenden Reihenfolge mit Updates zu versorgen. Innerhalb des Playbooks lassen sich auch mehrere verschiedene Systeme ansprechen. Beispielsweise kann hier zuerst ein Exchange Server aus dem Loadbalancer Pool genommen und erst dann aktualisiert werden, oder es könnte vorher noch ein Snapshot erzeugt werden, oder oder oder…

Download

Wie versprochen findet sich hier der Download mit den entsprechenden Beispielen:

Die enthaltenen Dateien dienen nur als Beispiel und müssen an die eigene Umgebung angepasst werden. Vielleicht erleichtern die Beispiele ja dem ein oder anderen den Einstieg in Ansible.

Fazit

Nach ein bisschen Einarbeitungszeit und vielen Tests, gewöhnt man sich recht schnell an Ansible. Gerade die Möglichkeit nahezu alle Systeme zu automatisieren, bietet enormes Potenzial. Es lassen sich ja schließlich nicht Aktionen auf Windows- und Linux Servern ausführen, sondern auch nahezu jedes andere Gerät im Netzwerk steuern (Switches, Router, Firewalls, Loadbalaner, Hypervisor, “das Blech”, Klimaanlagen, Zutrittskontrolle, Datenbanken usw. usw. usw.) und beim eigenen Netzwerk ist ja noch nicht Schluss, auch die Schnittstellen von Azure, AWS und GCP lassen sich ansteuern. Die Möglichkeiten sind also ziemlich vielseitig…

Tipp: Es gibt auch ein grafisches Frontend für Ansible:

12 Gedanken zu „Windows Server mit Ansible automatisieren (Beispiel Windows Updates)“

  1. Wäre es denkbar das Thema hier mal nochmals zu vertiefen?

    WIr haben selbst nun eine Ansible AWX + GitLab Lösung, die unsere Windows + Linuxumgebung patcht/konfiguriert.
    Unter Windows nutzen wir Zertifikate + CredSSP per WinRM.

    Das ganze funktioniert SUPER!

    Natürlich muss man sich mit Ansible und den vielen Modulen beschäftigen und ausprobieren…
    Aber die Möglichkeiten sind unendlich..

    Vmware Guest Tools aktualisieren
    Windows Dienste vorher beenden, Downtime in einer Überwachungslösung setzen, Server neustarten, alle dienste wieder starten, Downtime wieder beenden.

    Windows Patche einspiele
    Windows Features aktivieren/Deaktivieren

    Konfigurationen global verteilen (DNS Änderung, NTP Zeitserver, RegKey…..)

    Verteilung von ThirdParty Software

    Leider ist es in dem Umfeld noch schwer, geeignete Schulungen zu finden, die den Fokus auch mal auf WINDOWS legen.

    Antworten
  2. Hi,

    ich weiß der Post ist schon älter, aber auch mich würde das Playbook für die Snapshots interessieren.

    Danke für das echt tolle Tutorial.

    Gruß
    Susie

    Antworten
  3. Tolles Tutorial, vielen danke!
    Mich würde noch interessieren, ob es bei einer Authentifizierung mittels (selbstsignierten) Zertifikat möglich ist, das Inventory File dynamisch zu gestalten?

    Aktuell kann ich nur auf einen Windows Host mittels Zertifikat zugreifen:
    ansible_winrm_cert_pem=/root/cert.pem
    ansible_winrm_cert_key_pem=/root/cert_key.pem

    Mein Ziel wäre es die Keys des Windows Host in eine externe Datenbank zu exportieren und diese später wiederrum im Inventory File zu nutzen.

    Gruß Julian

    Antworten
  4. Tolles Tutorial, danke!
    Mich würde noch interessieren, wie du die E-Mail Benachrichtigung gelöst hast. Hast du dazu evtl. einen Tipp?
    Danke und Gruss

    Antworten
  5. Hallo!

    SUPER Tutorial! Alles funktioniert, bis auf das Starten der Powershell CMDs, die ich von dem Download- exupdates.yml kopiert habe.
    Andere PS Scripts, die eine Datei auf dem Zielsystem anlegen, funktionieren
    Kann jemand helfen? Folgenden Fehler bekomme ich:

    TASK [Place DAG in maintanance mode] *******************************************
    fatal: [srvex01.meinedomäne]: FAILED! => {„changed“: true, „cmd“: „$ErrorActionPreference = ‚Stop’\nwrite-host \“Hallo Welt!\“\ntry {\nwrite-host \“Server: \“ $env:computername -backgroundcolor cyan\n$ExchangeServerName = $env:computername\nAdd-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn\n. $env:ExchangeInstallPath\\bin\\RemoteExchange.ps1\nConnect-ExchangeServer -auto -AllowClobber\n}\ncatch {\nwrite-error ‚Failed to connect to Exchange Server’\nexit 1\n}\ntry {\nSet-MailboxServer $ExchangeServerName -DatabaseCopyActivationDisabledAndMoveNow $True\n}\ncatch {\nwrite-error ‚Failed to set Exchange Server into Maintanance

    Original und modifizierte Version funktionieren nicht und ich bekomme auch keine Ausgabe auf meinem Ansible Server bzgl. write-host.

    Danke!

    Antworten
    • Ich habe die Lösung gefunden:
      den Text zwischen durch Eure Daten ersetzen.

      $ExchangeServerName = $env:computername
      $username = „“
      $password = ConvertTo-SecureString „“ -AsPlainText -Force
      $psCred = New-Object System.Management.Automation.PSCredential -ArgumentList ($username, $password)
      $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$ExchangeServerName/PowerShell/ -Authentication Kerberos -Credential $psCred
      Import-PSSession $Session -AllowClobber -DisableNameChecking

      und dann funktioniert auch der Rest von Franky’s Script

      Antworten
  6. Großartiges Tutorial!

    An der Lösung bzgl. VM Snapshot und Löschen im Nachgang wäre ich auch interessiert.

    Wobei mir ein bisschen mulmig wird, ist der Sicherheitsaspekt einer solchen Lösung. Gibt es bestimmte best practices zur Absicherung des genutzten Accounts? Ich denke ein Domänennutzer als lokaler Admin auf den verwalteten Systemen wäre ausreichend? Was könnte man darüber hinaus noch im Bereich Hardening unternehmen? Unterbindung des interactive Logon? Beschränkung der Anmeldezeiten? Hat sonst noch jemand gute Ideen zur Absicherung?

    Gruß

    Antworten
  7. Danke für das Tutorial.
    Funktioniert prima.

    Du hast geschrieben, dass du vor deinen Updates noch automatisch ein Snapshot der betroffenen VMs machst.
    Könntest du das Playbook bzw. die Anleitung dafür auch posten?

    Antworten
  8. Umfangreiches und tolles Tutorial. Vielen Dank.

    Eine Frage zu Ansible, wie sind die Erfahrungen hinsichtlich Zuverlässigkeit wenn es um WinRM Verbindungen geht von CentOS zu Windows Servern in der Domäne?
    Bei WinRM und Kerberos denke ich da an die vielen Updates und Umstellungen die MS da in letzter zeit gemacht hat und bis nächstes Jahr noch machen wird.. (LDAP Secure, Zero Netlogon Lücke, ….)
    Wäre „SSH“ da nicht „störungssicherer“?
    Und kann man mit etwaigen Addons Ansible auch zusätzlich zur einfachen Inventarisierung der Serverlandschaft heranziehen?
    Bin gerade auf der Suche nach einer Lösung.
    Im Idealfall eine zentrale Patchmanagementlösung inkl. Inventarisierung von Servern.
    Ein einfacher WSUS und händisches Updates installieren geht ab bestimmten RZ-Größen nicht mehr..

    Danke fürs Feedback – auch generell zu Ansible…

    Antworten
  9. Sehr schönes Tutorial,
    allerdings empfehle ich gleich mit AWX zu arbeiten (die freie Variante von Tower). Es ist einfach komfortabler das alles über den Browser zu steuern anstatt immer per SSH zu arbeiten.
    Ich würde ungeachtet von AWX auch den Server gleich mit in die Domäne nehmen und dann mit Domain Usern arbeiten, unter CentOS 8 wäre das:
    sudo dnf install realmd sssd oddjob oddjob-mkhomedir adcli samba-common samba-common-tools krb5-workstation authselect-compat
    realm join example.com -U administrator
    sudo authselect select sssd with-mkhomedir
    sudo systemctl restart sssd
    Einzelne User das Anmelden erlauben:
    realm permit user1@example.com
    Oder über Gruppen:
    realm permit -g ‚irgend eine gruppe‘

    Dann kann man die User oder Gruppen auch noch in ein Sudoers file eintragen.
    Vorteil der ganzen Sache, da man die meisten Pakete sowieso braucht, das man sich einfach mit Domainuser anmelden kann und (bei Putty) auch kein Passwort abgefragt wird.

    Um das ganze mit AWX noch weiter zu „pimpen“ kann man die Scripte dann noch aus einem Git Repo beziehen. Dann ist das alles höchst komfortabel und revisionssicher.

    Antworten

Schreibe einen Kommentar