Introduction to Ansible
Welcome to this introduction to managing Windows from Ansible, unlike Microsoft's management solutions, it's free and agentless! Imagine a single tool that automates the setup, configuration, and maintenance of multiple Windows and Linux servers.
With its simplicity, Ansible lets you easily orchestrate your server infrastructure. No more manual tasks, no more sleepless nights—just smooth sailing through the seas of automation. Well, it will allow those repetitive tasks to be automated at least.
Aims for Ansible
This article aims to offer straightforward guidance on configuring Ansible for the management of a non-domain joined Windows Server via the execution of remote tasks.
Subsequent articles will expand upon this foundation by incorporating features such as Vault's password management, domain-joined servers, and Kerberos authentication.
What you will need to download
Visual Code for Linux https://code.visualstudio.com/docs/setup/linux
Windows WinRM Configurator Script https://github.com/AlbanAndrieu/ansible-windows/blob/master/files/ConfigureRemotingForAnsible.ps1
Ansible Documentation https://docs.ansible.com/ansible/latest/index.html
Ansible Host and Yaml Files https://github.com/Tenaka/Ansible/tree/main
Pick your Linux of Choice (Ubuntu Desktop)
I'll be opting for my less preferred Linux distribution, Ubuntu Desktop. However, I find it to be the most user-friendly choice for Microsoft-focused engineers. Rocky Linux is a viable alternative, though its configuration might involve additional steps.
I won't go into a detailed step-by-step installation of Linux, but simply download the ISO, mount it within your preferred VM solution and install, following the default setup.
Some Sort of Virtualization or Cloud
I'll be opting for Hyper-V as my preferred virtualization platform to host both Ubuntu and Windows Server 2022. Its seamless integration with both Windows Server and Windows 11 client eliminates any compatibility or migration concerns I may face moving images between the 2.
There are two recommended Hyper-V configurations for Linux installation. Opt for a Generation 2 VM to enable Secure Boot capability, and within the Security section of the VM, select 'Microsoft UEFI Certificate Authority'.
Post-deployment, run the following command from PowerShell, once the Linux VM is powered down, select the resolution that aligns best with your monitor.
Set-VMVideo Ansible2 -horizontalresolution:1900 -verticalresolution:1200 -ResolutionType Single
Update Ubuntu
After successfully deploying Ubuntu, it is crucial to install any updates to ensure the smooth execution of future installations by running the following command from a shell terminal.
sudo apt-get update -y && apt-get upgrade -y
Install Ansible
Ansible is installed with the following command.
sudo apt-get install ansible -y
List currently installed collections, as you will see there's support for OS, Cloud, Network devices and much more.
ansible-galaxy collection list
To update the Windows community collection that's installed by default.
ansible-galaxy collection install community.windows
To install the latest stable collection by Ansible, run the following
ansible-galaxy collection install ansible.windows
Before continuing type ip address in the terminal and record for later use.
Install Microsoft's Visual Code for Linux
To assist with writing Yaml and to minimise the moving of files Microsoft's Visual Code for Linux will be installed on Ubuntu. If you can't outdo them, it seems the strategy is to join them. Well played Microsoft.
Instructions can be found @ https://code.visualstudio.com/docs/setup/linux for Ubuntu and other distro's. For Ubuntu follow the next set of instructions.
sudo apt-get install wget gpg wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
sudo install -D -o root -g root -m 644 packages.microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list'
rm -f packages.microsoft.gpg
sudo apt install apt-transport-https
sudo apt-get update
sudo apt-get install code
Launch Visual Code once it's installed, then create a new directory in the Documents directory named Ansible.
That concludes the installation and configuration of Ubuntu and Ansible. Now, let's proceed to the setup of Windows.
WinRM and Windows Server Configuring Windows for remote management from Ansible is a little involved with instructions available from the Anisble website:
Nevertheless, there exists a pre-configured script accessible on Github:
To get up and running with this basic implementation download the 'ConfigureRemotingForAnsible.ps1' and execute the script from PowerShell with Administrative rights.
A cautionary note: the implemented configuration is open, granting remote WinRM access to any client. To address this, simply modify lines 417 and 423 by adding the specific remote IP of the Ansible server; in my case, it's 10.1.1.100. This updates the firewall from allowing any address to that of the one specified.
10.1.1.1 = Windows Server
10.1.1.100 = Ubuntu\Ansible
ln 417
netsh advfirewall firewall add rule profile=any name="Allow WinRM HTTPS" dir=in localport=5986 protocol=TCP action=allow remoteIP=10.1.1.100
ln 423
netsh advfirewall firewall set rule name="Allow WinRM HTTPS" new profile=any remoteIP=10.1.1.100
To assess WinRM access from another Windows client, input the following commands in PowerShell. Remember to update the password and AnsibleIP with your system's information. In case the Windows Firewall imposes the above RemoteIP restriction, include the test client's IP in the 'Allow WinRM HTTPS' remote scope firewall rule.
$username = "administrator"
$password = ConvertTo-SecureString -String "ChangeMe1234" -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
$session_option = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
Invoke-Command -ComputerName AnisbleIP -UseSSL -ScriptBlock { ipconfig } -Credential $cred -SessionOption $session_option
Confirm that the WinRM Service is running.
Get-Service WinRM
If the WinRM service isn't started execute the following to set the service to automatic and start.
Set-Service -Name WinRM -StartupType Automatic -ErrorAction SilentlyContinue
Get-Service -Name WinRM | Start-Service
To get the WinRM configuration execute the following:
winrm enumerate winrm/config/listener
Listener
Address = *
Transport = HTTP
Port = 5985
Hostname
Enabled = true
URLPrefix = wsman
CertificateThumbprint
ListeningOn = 10.1.1.1, 127.0.0.1, ::1, fe80::a81e:3b96:6d3b:3d6c%3
Listener
Address = *
Transport = HTTPS
Port = 5986
Hostname = WIN-JE1B7QU8B8R
Enabled = true
URLPrefix = wsman
CertificateThumbprint = FC24D87A798ECA4EA8BF4EE0C8CD7FD2CC51A67C
ListeningOn = 10.1.1.1, 127.0.0.1, ::1, fe80::a81e:3b96:6d3b:3d6c%3
Ansible Environment
In Ansible, host files and YAML are crucial in defining and organizing the infrastructure you intend to manage.
Host Files:
A host file in Ansible is where you specify the details of the servers or systems you want to manage.
It typically includes information like IP addresses, hostnames, and grouping of hosts based on certain criteria (e.g., development, production).
Host files help Ansible understand the inventory of systems it can control, making it an essential component for playbook execution.
Without Ansible Vault passwords are hardcoded and clear text within the Hosts file. Vault will be covered in a subsequent article.
[Windows]
10.1.1.1
[Windows: vars]
ansible_user=administrator
ansible_password="ChangeMe1234"
ansible_connection=winrm
ansible_winrm_scheme=https
ansible_port=5986
ansible_winrm_server_cert_validation=ignore
ansible_kerberos_delegation=false
YAML (YAML Ain't Markup Language):
YAML is a human-readable data serialization format often used for configuration files and data exchange between languages with different data structures.
In Ansible, YAML is used to write playbooks, which are scripts that define the tasks to be executed on the managed hosts.
It uses indentation to represent data hierarchy, making it easy to read. Writing can present a bit of a challenge as its hierarchal nature requires the structure to be indented and spaced correctly.
In this example, the contents from the Ansible directory are copied to the targeted Windows Administrator's Desktop.
---
- name: Copy
hosts: Windows
become: false
gather_facts: false
vars:
source: "/home/user/Documents/Ansible"
destination: "Desktop/"
tasks:
- name: copy ping
ansible.windows.win_copy:
src: "{{ source }}"
dest: "{{ destination }}"
Host and YAML files play a crucial role in making Ansible configurations clear, structured, and easy to manage. Host files define the inventory, while YAML defines the tasks and configurations to be applied to the hosts.
Host File and Initial Test
Ensure you're logged on to Ubuntu\Ansible and launch Visual Code.
Navigate to '/home/user/Documents/Ansible' and create a file named 'hosts.ini.
Taking the above host file as an example, incorporate the necessary details that match your Windows system and save the file.
Or download the examples provided: https://github.com/Tenaka/Ansible/tree/main
Let's create the most basic ping test to confirm access to Windows, create a file named 'ping.yml' and insert the following.
---
- name: Ping Windows Test
hosts: Windows
gather_facts: false
tasks:
- name: Ping targets
win_ping:
Launch a shell and CD to '/home/user/Documents/Ansible'.
Type and execute the following command
ansible-playbook -i hosts.ini ping.yml
Kudos on acing the Ansible setup for managing Windows!
File Copies To and Fro
Before delving into the YAML file, it's essential to acquaint yourself with the following path rules. The Windows path rules should be written in the following format.
Good
tempdir=C:\\Windows\\Temp
Works
tempdir='C:\\Windows\\Temp'
tempdir="C:\\Windows\\Temp"
Bad, but sometimes works
tempdir=C:\Windows\Temp
tempdir='C:\Windows\Temp'
tempdir="C:\Windows\Temp"
tempdir=C:/Windows/Temp
Fails
tempdir=C:\Windows\temp
tempdir='C:\Windows\temp'
tempdir="C:\Windows\temp"
Copies the contents of the Ansible directory to the Desktop of the target Windows server.
---
- name: Copy
hosts: Windows
become: false
gather_facts: false
vars:
source: "/home/user/Documents/Ansible"
destination: "Desktop/"
tasks:
- name: copy ping
ansible.windows.win_copy:
src: "{{ source }}"
dest: "{{ destination }}"
Copies a named file from the Windows Desktop up to the Ansible directory using 'fetch'.
---
- name: Copy
hosts: Windows
become: false
become_user: false
gather_facts: false
vars:
source: "Desktop/test1.txt"
destination: "/home/user/Documents/Ansible/test1.txt"
tasks:
- name: copy ping
ansible.builtin.fetch:
src: "{{ source }}"
dest: "{{ destination }}"
Further guidelines can be found @ https://docs.ansible.com/ansible/latest/os_guide/windows_usage.html
Basic Commands
This concludes the introduction by running a command line on the designated Windows server and saving the results to a text file.
---
- name: cmds
hosts: Windows
become: false
gather_facts: false
tasks:
- name: some cmd
win_command: cmd.exe /c whoami.exe > "Desktop\whoami.txt"
- name: ipconfig
win_command: cmd.exe /c ipconfig /all > "Desktop\ipconfig.txt"
Finally Done!
Thanks for your time reading this intro to managing Windows from Ansible. Creating each article demands time and effort, diverting me from other learning pursuits. Your comments and shares are highly valued and greatly appreciated.
Finally a big shout-out to Harv for opening my eyes to a life beyond SCCM.
Comments