Managing Windows Updates with Ansible in Red Hat Enterprise Linux

Introduction

When looking for installation instructions of Ansible under RHEL, I have always have found two ways:

  1. With epel-release (Which I don't like just because I want to keep my system clean).
  2. From source code (Which I don't like either for the same reason).

Packages Installation

For me, the right approach for the installation is installing from the Official Red Hat Repository and following the instructions below:

Select the server-extras-beta repository (Here we will find the ansible packages)

subscription-manager repos --enable=rhel-7-server-extras-beta-rpms

Install some extra packages we will need later (in order to install some python packages and have Kerberos auth for Windows):

yum -y install gcc python-devel krb5-devel krb5-workstation

And go for Ansible installation:

yum install -y ansible

And now, the non-standard part. We will use pip in for the Kerberos Authentication support.

easy_install pip
pip install https://github.com/diyan/pywinrm/archive/master.zip#egg=pywinrm
pip install kerberos
pip install requests_Kerberos

Ansible Configuration

Edit the Ansible hosts file adding the Windows Servers and the Kerberos Authentication:

/etc/ansible/hosts

[windows]
server.domain.com
appserver.domain.com

[windows:vars]
ansible_ssh_user=user@DOMAIN.COM
ansible_ssh_pass=SecretPassword
ansible_ssh_port=5986
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore

Edit the Kerberos Configuration file and add your domain configuration

/etc/krb5.conf

# Configuration snippets may be placed in this directory as well
includedir /etc/krb5.conf.d/

[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log

[libdefaults]
dns_lookup_realm = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
default_realm = DOMAIN.COM
default_ccache_name = KEYRING:persistent:%{uid}
default_tgs_enctypes = arcfour-hmac-md5 des-cbc-crc des-cbc-md5
default_tkt_enctypes = arcfour-hmac-md5 des-cbc-crc des-cbc-md5

[realms]
DOMAIN.COM = {
  kdc = server.domain.com
  admin_server = server.domain.com
}

[domain_realm]
.domain.com = DOMAIN.COM
domain.com = DOMAIN.COM

Windows Configuration

Under the Windows Servers (Mine are 2012R2), we will download and run the following script as follows:

ConfigureRemotingForAnsible.ps1

powershell.exe -File ConfigureRemotingForAnsible.ps1 -ForceNewSSLCert

Server Test

In order to test our installation, we will ping our server with the command:

ansible server.domain.com -m win_ping

If everything goes right, we will have the following result:

server.domain.com | SUCCESS => {
  "changed": false,
  "ping": "pong"
}

Playbook for Windows Update

We just want to know if the server has updates available. The following playbook will do the job:

---
# windows-updates.yml

- hosts: windows
  serial: 1
  remote_user: user@DOMAIN.COM

  tasks:

    # Check of there are missing updates
      - block:
          - name: Check for missing updates.
            win_updates: state=searched
            register: update_count
          - name: List missing updates
            debug: var=update_count

Running the playbook

We will be able to run the playbook for a single server with the command:

ansible-playbook -l appserver.domain.com windows-updates.yml

We will have two possible results:

  1. If there are updates available

    PLAY [windows] ******************************************************************************************************************************************************************************************************************************
    TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
    ok: [appserver.domain.com]
    TASK [Check for missing updates.] ***********************************************************************************************************************************************************************************************************
    changed: [appserver.domain.com]
    TASK [List missing updates] *****************************************************************************************************************************************************************************************************************
    ok: [appserver.domain.com] => {
        "changed": false,
        "update_count": {
            "changed": true,
            "failed_update_count": 0,
            "found_update_count": 3,
            "installed_update_count": 3,
            "reboot_required": true,
            "updates": {
                "38c0bc96-f072-4bfc-9f5a-c704b1b0b30c": {
                    "id": "38c0bc96-f072-4bfc-9f5a-c704b1b0b30c",
                    "installed": true,
                    "kb": [
                        "890830"
                    ],
                    "title": "Windows Malicious Software Removal Tool for Windows 8, 8.1, 10 and Windows Server 2012, 2012 R2, 2016 x64 Edition - May 2017 (KB890830)"
                },
                "5ee9120d-5bfe-4093-8ad6-9e83a6b0f02b": {
                    "id": "5ee9120d-5bfe-4093-8ad6-9e83a6b0f02b",
                    "installed": true,
                    "kb": [
                        "4019114"
                    ],
                    "title": "May, 2017 Security and Quality Rollup for .NET Framework 3.5, 4.5.2, 4.6, 4.6.1, 4.6.2 on Windows 8.1 and Windows Server 2012 R2 for x64 (KB4019114)"
                },
                "d2281849-7314-4da5-bed1-9e8e4d74b4ed": {
                    "id": "d2281849-7314-4da5-bed1-9e8e4d74b4ed",
                    "installed": true,
                    "kb": [
                        "4019215"
                    ],
                    "title": "2017-05 Security Monthly Quality Rollup for Windows Server 2012 R2 for x64-based Systems (KB4019215)"
                }
            }
        }
    }
    PLAY RECAP **********************************************************************************************************************************************************************************************************************************
    appserver.domain.com   : ok=3    changed=1    unreachable=0    failed=0
  2. If the System is Up to Date

    server.domain.com | SUCCESS => {
        "changed": false,
        "found_update_count": 0,
        "installed_update_count": 0,
        "reboot_required": true,
        "updates": {}
    }
Last updated: July 25, 2023