Skip to content

Instantly share code, notes, and snippets.

@dmccuk
Last active July 7, 2023 09:36
Show Gist options
  • Save dmccuk/c39f560feec55fdbbaf5a17c3c52a431 to your computer and use it in GitHub Desktop.
Save dmccuk/c39f560feec55fdbbaf5a17c3c52a431 to your computer and use it in GitHub Desktop.

Manage Windows Servers using Ansible

This is a real-time demo of how to set up your windows servers so they can be managed by ansible. I've created a YouTube companion video demo here: https://youtu.be/aPN18jLRkJI

Subscribe To Me On YouTube: https://bit.ly/lon_sub

The following is covered by this demo:

  • Setup a windows 2016 (or 2019/2021) server so ansible can manage it (over HTTPS)
  • Setup my Centos 8 server so it can manage windows servers using winrm
  • Create an inventory file to hold the windows connection variables
  • Prove the connection with win_ping
  • Create a basic ansible playbook to manage directory’s, files (templates), md5checksum & updates
  • Use ansible-vault to hide the password secret from the inventory file

AnsibleDocs:

Setup Windows. This is a useful link - https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html

Follow these steps to get your Windows 2016 server ready for Ansible.

  1. Remote desktop into your Windows server
  2. Go down to WINRM setup. Where going to run the powershell commands but first you need to run this:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

This is because the default version of TLS on powershell is TLS 1.0 but GitHub wants 1.2. Now you can carry on with the script. For Windows 2019/2021 the default version is already TLS1.2 so you won't need to to this.

  1. Run the powershell commands.
  2. That should be it. Let’s head back to out Centos 8 server and test it out.

Create the inventory file

vi hosts.ini

Add the following into your Inventory file:

[win] #This is the group name
35.177.240.58

[win:vars] # These are the group variables
ansible_user=Administrator
ansible_password="hvADJA(xnxEMiPPMc?I8HgjiMEKDkqek"
ansible_port=5986
ansible_connection=winrm
ansible_winrm_scheme=https
ansible_winrm_server_cert_validation=ignore
ansible_winrm_kerberos_delegation=true
  • Change The Server IP address to be your server's IP address
  • Change the ansible_password to be your server password for the user Administrator

Test connectivity

If we try to test connectivity, we should get an error because we don’t have winrm installed yet.

ansible -i hosts.ini win -m win_ping

Check the ansible docs for more information on winrm https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html

  1. Install winrm as per the docs, but adding pip3. pip3 install "pywinrm>=0.3.0" –user

  2. If you’re using a cloud provider like me, make sure you open incoming port 5986 on your windows server FW. Now run the win_png command again:

    ansible -i hosts.ini win -m win_ping

    You should see a pong response in green if successful. If it still doesn't work, make sure you're using the correct password.

Now we can move onto creating a playbook to manage our windows server:

Create the playbook

  1. Vi Windows.yml and add the following content. This is what the ansible will do:
  • We will create a directory on the remote Windows server called C:\Temp\folder
  • Create a file C:\Temp\folder\foo.txt
  • Use a template to populate the file foo.txt
  • Check the MD5sum of the file and display the MD5sum value

windows.yaml

---
- name: Manage Windows
  hosts: win
  tasks:
  - name: Create directory structure
    win_file:
      path: C:\Temp\folder
      state: directory

  - name: Touch a file
    win_file:
      path: C:\Temp\folder\foo.txt
      state: touch

  - name: Create a file from a Jinja2 template
    win_template:
      src: foo.txt.j2
      dest: C:\temp\folder\foo.txt

  - win_stat:
      path: C:\temp\folder\foo.txt
      get_checksum: yes
      checksum_algorithm: md5
    register: md5_checksum

  - debug:
      var: md5_checksum.stat.checksum

Create the temaplate file

vi foot.txt.j2

Add this content:

Hi, this server is caller "{{ ansible_hostname }}"

Ansible_hostname is an ansible fact that is available by default in Ansible

Now you have all the files you need, run the playbook like this:

ansible-playbook -i hosts.ini windows.yml

Ansible will run and create the directories and files we asked it to.


Remove the Password from the inventory file (Optional)

To make the Ansible code safe from a security point of view, we need to remove the password for the windows Administrator.

We'll use Ansible-vault to encrypt the password, and move the password into a specific variables file. We'll also create another file outside of our Ansible code to hold the vault password (The password used by Ansible to decrypt the password)

  1. Create a variable file to hold the password. I’ll do it in the default location. Win is the group name so if we create a win.yml, any variables will get picked up by the win group in the inventory :

mkdir group_vars

vi group_vars/win.yml

  1. Encrypt the password string:

ansible-vault encrypt_string 'Administrator_user_password' --name ansible_password

USE PASSWORD: Password123

Take the output and add it to group_vars/win.yml

  1. Because the variable is in the default location (group_vars) it will be picked up in the run because it’s called win.yml – it’s a group variable.

  2. Remove the password from the inventory file. * Delete the password line fro the hosts.ini file.

  3. Run the playbook.

ansible-playbook -i hosts.ini windows.yml --ask-vault-pass Enter the password to open the vault.

  1. Finally, add the vault password to a file and reference it in the ansible.cfg file.
vi open_vault.txt
Password123

vi ansible.cfg
[defaults]
vault_password_file= open_vault.txt
  1. Re-run Ansible but this time remove ask-vault-pass.

ansible-playbook -i hosts.ini windows.yml

You have now completed this exercise to manage a windows server with Ansible. Checkout my other Ansible Mini's to extend your knowledge even further.


ISSUES As people let me know about the problems they're having, I'll add them here to help others:

Issue:

I’m getting this error {“msg”:”winrm or requests is not installed: cannot import name certs”} can you please tell me what should I do to fix this!!

Checkout this article and see if it helps you to resolve your problem: https://access.redhat.com/solutions/3356681

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment