It doesn't always have to be SCCM... I was looking for a way to automate as many of my boring tasks as possible for my own systems: Backing up or mirroring the website to the NAS, installing updates (Windows / Linux), installing test environments. Just repetitive, boring, time-consuming stuff, made for automation and central control. After a few tests, I ended up using Ansible to automate as many tasks as possible. In the meantime (admittedly after a few failures) things are running smoothly, so here is a brief introduction to the topic of automation using Ansible. As it was my first use case, I chose the topic of Windows updates for the first example.
CentOS 8 Installation
I normally use Debian for most of my Linux-based servers, but recently I've taken a liking to CentOS. I'm currently migrating my private systems from Debian to CentOS, so this article also uses CentOS as the operating system for Ansible (in case anyone is wondering why I'm not using Debian).
The installation of CentOS is self-explanatory, so here are just a few screenshots of my setup:
Since I run CentOS as a VM, I have selected "Server" and "Guest agents":
The root password can be set and a user created during installation:
After a few minutes CentOS is installed:
After the installation, only an IP address and DNS server, as well as time synchronization via NTP were configured. Once the CentOS installation is complete, Ansible can be installed.
Ansible installation
PIP (python installs packages) can be used for the Ansible installation. For this to work, Python must first be installed. Python can be installed using the following commands:
1 | sudo dnf install python3 python3-pip python3-devel
|
After Python, Ansible can be installed with the following command:
1 | sudo pip3 install ansible
|
Incidentally, I deliberately carried out the installation via PIP. When installing Ansible via the normal CentOS repo, I did not manage to get all components running successfully. When the installation was done via PIP, I had no problems.
Ansible is already installed, but the PyWinRM package is required so that Windows servers can also be managed later using WinRM. The package can be installed with the following command:
1 | sudo pip3 install pywinrm
|
Once Ansible has been installed, you can continue with the basic configuration.
Ansible basic configuration
As the installation of Ansible was carried out using PIP, two basic files for the configuration of Ansible are still missing. However, the required files can simply be downloaded and created in the corresponding directory. Ansible then loads these files at runtime.
The following commands can be used to create the directory and download the configuration files:
1 2 3 | sudo mkdir /etc/ansible
sudo wget https://raw.githubusercontent.com/ansible/ansible/devel/examples/ansible.cfg
-O
/etc/ansible/ansible.cfg
sudo wget https://raw.githubusercontent.com/ansible/ansible/devel/examples/hosts
-O
/etc/ansible/hosts
|
The ansible.cfg file does not need to be adapted initially. The servers to be managed are specified later in the "hosts" file.
Ansible authentication using Kerberos
The administration of Windows servers with Ansible would already work using WinRM, but currently only with a local user on the respective server. However, the use of Active Directory user accounts and authentication via Kerberos is the more elegant way here, especially as the management of some services on Windows servers only works with Active Directory users (the automation of Exchange servers would be an example here).
In order for Ansible to log on to Windows servers using AD users and Kerberos, a few more packages need to be installed.
1 | sudo dnf install gcc krb5-devel krb5-libs krb5-workstation
|
The connection to the Active Directory must now be configured in the /etc/krb5.conf file. In the file, the domain controller is entered in the "realms" section and the name of the Active Directory in the "domain_realm" section.
In my test environment, for example, this looks like this (case-sensitive):
The following command can now be used to test whether authentication using Kerberos works:
1 | kinit Administrator
@FRANKYSWEBLAB
.EN
|
If the command does not return an error message, everything is OK. The "klist" command can also be used to check whether a Kerberos ticket has been issued:
Finally, the Kerberos support for PyWinRM must be installed:
1 | sudo pip3 install pywinrm
[kerberos]
|
Ansible can now also use Active Directory users and Kerberos for authentication on the Windows server.
Create groups and hosts
Servers that are to be managed via Ansible must be made known in the file /etc/ansible/hosts. Individual servers can be combined into host groups within the file. Here is an example of my /etc/ansible/hosts file:
For example, the file contains the group "exchangeserver". The servers ex1 and ex2 are members of the exchangeserver group (first box in the screenshot). In the second box you will find the environment variables for the group, for the sake of simplicity I have also stored the login information here. There is also the group "windowsserver", this group contains all host groups with Windows systems:
I have summarized the relevant files as a download at the end of the article. So if someone wants to rebuild this, not everything has to be typed out here.
Configure Windows systems
In order for Ansible to access the Windows servers via WinRM, WinRM must be configured accordingly. The configuration of WinRM is very easy thanks to a PowerShell script. The script can be downloaded here:
The script must be executed as an administrator on every Windows server that is to be managed using Ansible.
The script creates a self-signed certificate and configures WinRM accordingly. The connection from the Ansible server to the Windows server is made via port 5986, the Windows firewall is configured automatically, if other firewalls are used, they must allow communication via port 5986.
Test connection
The preparations are now complete and you can test whether Ansible can establish a connection to the configured Windows servers. The following command can be used to test the connection:
1 | ansible GROUP NAME
-m
win_ping
|
This command executes the module win_ping (WinRM based test) for the members of a group:
The screenshot shows how the individual groups can be tested. If there are any problems here, the first thing to check is whether the servers are resolved via DNS and the login information is correct. If the connection is successful, you can create your first playbook.
Create playbook for Windows updates
Playbooks are used to execute a sequence of actions on the target systems. In this section, a simple playbook is created for the installation of Windows updates. This playbook only serves as an example for the time being, but if you familiarize yourself a little with Ansible, you can quickly implement more complex things here.
First, a directory structure can be created for the playbooks, making it easier to find the playbooks later. In this example, the directory "ansible-playbooks" and the subdirectory "windows" are created. All playbooks for Windows systems can then be saved in the "windows" folder. The directory structure is of course freely selectable here:
1 2 | mkdir /ansible_playbooks
mkdir /ansible_playbooks/windows
|
The first playbook can now be created in the "windows" folder. In this example, the playbook is used to install Windows updates on the Windows servers:
1 | touch /ansible_playbooks/windows/install_updates.yaml
|
The first playbook will have the following content:
The first step installs Windows updates on servers in the "fileserver" group (hosts: fileserver). If there are several hosts in the fileserver group, the updates are installed in parallel on the servers (strategy: free). The task defines which action is to be carried out. In this case, critical and security updates are installed and the servers are restarted if necessary. In the next step, it is the domain controllers' turn, followed by the hosts in the "exchange servers" group.
This simple playbook is just a small example. If you familiarize yourself with it a little, you can automate many things using Ansible. This example can also be downloaded at the end of the article.
For example, I have automated the update process for my private environment, which then runs as follows:
- Create VMware snapshots for all virtual servers that require updates
- Installing updates on Windows and Linux servers
- Restart the servers if this is necessary
- Send e-mail notification
- Delete snapshot 2 days later
The download at the end of the article also contains an example of how an Exchange DAG can be updated.
Run playbook
Previously created playbooks can be executed with the command "ansible-playbook". In this example, the previously created playbook is executed:
1 | ansible-playbook install_updates.yml
|
Ansible now executes the steps from the playbook on the servers:
As you can see in the screenshot above, one command is now sufficient to provide all Windows servers with updates in the appropriate order. Several different systems can also be addressed within the playbook. For example, an Exchange server can be taken from the load balancer pool first and only then updated, or a snapshot could be created first, or or or or...
Download
As promised, the download with the corresponding examples can be found here:
The files included are for example purposes only and must be adapted to your own environment. Perhaps the examples will make it easier for some of you to get started with Ansible.
Conclusion
After a bit of familiarization and a lot of testing, you get used to Ansible quite quickly. The ability to automate almost all systems offers enormous potential. After all, you can not only execute actions on Windows and Linux servers, but also control almost every other device in the network (switches, routers, firewalls, load balancers, hypervisors, "the sheet metal", air conditioning systems, access control, databases, etc., etc., etc.) and it doesn't end with your own network, you can also control the interfaces of Azure, AWS and GCP. So the possibilities are pretty diverse...
Tip: There is also a graphical front end for Ansible:
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.
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
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
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
Hallo Philipp,
siehe hier:
https://docs.ansible.com/ansible/latest/collections/community/general/mail_module.html
Gruß,
Frank
Hallo Frank, perfekt, vielen Dank! :-)
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!
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
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ß
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?
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…
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.