CONTROLLED DATA
Leidos Proprietary - US Citizens ONLY
The information contained herein is proprietary to Leidos, Inc. It may not be used, reproduced, disclosed, or exported without the written approval of Leidos.

This documentation contains all the details you will need to know to get started with using Ansible on Windows. 

Overview

Ansible con provision Windows systems as it does with Linux systems, but it only runs on Linux system. So you will need to have a Linux system that runs Ansible (which will be referred to as your Controller) to control your Windows systems (which will be referred to as your Windows Nodes).

Ansible connects and communicates with Linux nodes over SSH, and just like that, it communicates with Windows nodes over winrm (Windows Remote Management). You will need to make sure winrm is installed and configured before Ansible can connect and communicate with it. 

WinRM 

Windows Remote Management (WinRM) is the Microsoft implementation of WS-Management Protocol, a standard Simple Object Access Protocol (SOAP)-based, firewall-friendly protocol that allows hardware and operating systems, from different vendors, to interoperate.

That's the Microsoft Definition, but consider it as a simple webservice that runs on port 5985 (http) and 5986 (https) that uses the system's authentication scheme to authenticate your user. Once authenticated, it'll execute any PowerShell or cmd commands on the filesystem. Consider the following test function that you can use to test if you can connect to the machine and run ipconfig. You can use this debug your connectivity (more in this later).

Installing WinRM 

WinRM is a core service on your windows machine and it needs to be enabled first before Ansible can do anything with it. To do this, there is a simple PowerShell script you can run to get quickly started. 

https://bitbucket.sdosandbox.leidos.com/projects/GSMODSF/repos/dsf-infra-dssa/browse/provisioning/ps/ConfigureRemotingForAnsible.ps1

  1. Copy the contents of the file to your Windows Node(s)
  2. Open PowerShell as an Administrator
  3. Run ConfigureRemotingForAnsible.ps1

You can also check if everything is running properly with the following command:

winrm quickconfig

Ensure Everything is Running Properly

When winrm is up and running properly, it sets up the service and the listener, and sets the appropriate configurations. Here we will check if everything is running properly.

Check if the Listener is configured properly

First thing to check is the winrm configuration is setup properly. To do this, open PowerShell as an Administrator and run:

winrm enumerate winrm/config/Listener

Check if the WinRM Service is running:

get-service -ComputerName "$(hostname)" -Name winrm

Check if the WinRM service is configured properly

winrm get winrm/config

Authentication

If winrm is running properly, you can next have Ansible try to connect to the server. You can test if you are able to connect to the server with the ansible command, but before you do that, you will need to configure Kerberos on the Controller (where Ansible is run from), and pass specific variables to Ansible to use for authentication.

A Brief Discussion on Authentication

The protocols that both Ansible and winrm support for authentication are:

  • Basic
  • Certificate
  • Kerberos
  • NTLM
  • CredSSP

If you're in an environment managed by Active Directory, you will most likely need to use Kerberos. You can also try NTLM if it is enabled, but it is older and not as secure as Kerberos.

If you're only testing locally on a VM or you're not in an environment managed by Active Directory, you can use Basic. Certificate is like Basic but uses a Certificate based authentication. You probably won't need to do this in the Leidos Environment. CredSSP is not supported in the Leidos Environment.

The rest of this documentation will talk about Kerberos. If you want additional information about Basic, Certificate, NTLM or CredSSP, please refer to the Ansible documentation: 

https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html#authentication-options

Install Kerberos Client

You will need to install the Kerberos client on your Controller. You can do this from yum.

NOTE: If it is not available, make sure you have EPEL Repositories enabled or have your repository pointing to our Artifactory.

yum install krb5-workstation

Configuring Kerberos Client

You need to configure the Kerberos Client which Ansible uses to authenticate. Here is a sample configuration for what we are using in DEVINT, along with notes that you will help you. The file you will need to edit is /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 = true
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true
rdns = false
pkinit_anchors = /etc/pki/tls/certs/ca-bundle.crt
default_realm = CORP.LEIDOS.COM
default_ccache_name = KEYRING:persistent:%{uid}
[realms]
 CORP.LEIDOS.COM = {
    kdc = AUTHP-AD-CORP06.corp.leidos.com
 }


Couple of things to note here:

  • Things You Need: Before getting started with configuring your Kerberos Client, you will need to know:
    • Realm: Essentially the domain that your machines come under
    • KDC: This is optional, but it would be a good idea to know what your KDC is since we did get some weird errors without it.
  • Spaces and Case Matter: After each section in your configuration file (for example [logging]), each configuration is indented by 1 space. If your domain is capitalized, be sure to enter it in ALL CAPS.

Configuring and Testing in the Connection with Ansible

When it comes to Ansible, you need to first configure your inventory file, your variables and your playbook. For this documentation, we're only going to do a ping with the win_ping module, and we're going to set the variables in the command line, so we don't need a variables file for the sake of this. The file we do need to edit is your inventory file. The following is a sample inventory file that was used along with some comments about it.


  • Domain Names Matter: Don't use IP addresses when you're setting up your inventory. Kerberos uses DNS to identify the server you're connecting to, so you'll need the Fully Qualified Domain Name (FQDN). Due to this, you can't also just put hostnames in your inventory file. You need the FQDN that you use to identify the server. 

The variables you need to configure while making the connection to the Windows server are specific to authentication with Kerberos. You will need the following variables set:

  • ansible_user: this is the user that Ansible will use to authenticate with Kerberos. Therefore, you will need to provide the domain name also, and not just the username.
  • ansible_password: The password for the user you're trying to authenticate with. Be sure to escape special characters, such as $, with a backslash (\), as such "foo\$bar"
  • ansible_winrm_transport: Since we're using kerberos, set this to kerberos. If you're using any other authentication protocol, specify that here.
  • ansible_winrm_server_cert_validation: This isn't good in a production environment but since we're in development and trying to figure this out, and don't have certs setup properly, be sure to ignore the server certification validation by setting this to ignore


Now let's test the connection. You will refer to the servers by their groupname, dssa-servers, in the command line. 

ansible dssa-servers \
  -i ./inventory \
  -m win_ping \
  -c winrm \
  -e "ansible_user=srvc-gsmo@CORP.LEIDOS.COM" \
  -e "ansible_password=PASSWORD_GOES_HERE"
  -e "ansible_winrm_transport=kerberos"
  -e "ansible_winrm_server_cert_validation=ignore"


If all goes well, you should see a result like this:

gsmldq-ag9-ws.corp.leidos.com | SUCCESS => {
"changed": false,
"ping": "pong"
}
gsmldq-ag9-dssa.corp.leidos.com | SUCCESS => {
"changed": false,
"ping": "pong"
}


Troubleshooting

If all didn't go well, you're in the right place. We're going to try to take an approach that lets us divide the components to their individual pieces and see where the problem might be, along with troubleshooting tools and what you need to do to fix it.

There are multiple places where things can go wrong. They can be:

  • Firewall Issues
  • Issues with configuring Kerberos
  • Issues with configuring Windows and winrm
  • Issues with configuring Ansible


I can't seem to connect to winrm on Port 5986.
  • You need to make sure that your controller and your servers can first talk with each other. Ansible communicates with Windows over port 5986, so be sure that this port is opened.
    • In the Leidos domain, you might need to setup a SIARRA request to open 5986.
    • Also check if your Windows Firewall is accepting incoming requests on port 5986
Firewall
Invalid Username or Password
  • Make sure you are using the right password for your user
  • Make sure that your username is not locked in Active Directory
  • Make sure you are enterring not just the username, but also with the user's domain. For example, don't use srvc-gsmo as your user, instead use srvc-gsmo@CORP.LEIDOS.COM
  • Make sure that your username and password are escaped properly and the case is set properly
  • On your Controller VM, you can run kinit and klist utilities to test if the connection can be made. kinit will prompt you for your username and password, and if successful, klist will show your authentication ticket that you received from Keberos to use for your authentication.


Kerberos
kerberos: (('Unspecified GSS failure. Minor code may provide more information', 851968), ('Server not found in Kerberos database', -1765328377))
  • Kerberos identifies your server by it's Fully Qualified Domain Name (FQDN). Be sure to use your FQDN when you're connecting to the server in your Ansible Inventory. For example:
Ansible
Everything looks good, but it doesn't look like winrm is responding

Ensure that winrm is configured Properly

  • Open up Group Policy Editor on your Windows Node
    • Start > gpedit.msc
  • Go to:
    • Computer Configuration > Policies > Administrative Templates: Policy definitions > Windows Components > Windows Remote Management (winrm) > winrm Service
  • Ensure that the configuration looks like this:


Ensure that winrm Service is running

get-service -ComputerName "$(hostname)" -Name winrm



Ensure that the Listener is configured properly


First thing to check is the winrm configuration is setup properly. To do this, open PowerShell as an Administrator and run:

winrm enumerate winrm/config/Listener


Ensure that the winrm service is configured properly

winrm get winrm/config


Make sure that the user, "srvc-gsmo" in DEVINT, is a member of the local Administrator group. If it is not, you'll get an error saying that "Server rejected the credentials".


Windows and winrm