The orchestration of Windows environments within a Linux-based automation framework necessitates a robust, secure, and scalable authentication mechanism. While NTLM is often the default for small-scale labs, enterprise-grade deployments demand the implementation of Kerberos. Kerberos provides a ticket-based authentication system that eliminates the need to transmit passwords across the network, leveraging a Key Distribution Center (KDC) to verify identities. When integrating Ansible with Windows via WinRM (Windows Remote Management), Kerberos becomes the gold standard for security, particularly when operating within an Active Directory (AD) domain. However, the transition from simple password authentication to Kerberos is fraught with technical hurdles, specifically regarding the Execution Environment (EE) in AWX and Ansible Automation Platform, the configuration of the GSSAPI, and the precise alignment of the krb5.conf file.
The Technical Architecture of WinRM Kerberos Authentication
WinRM operates as the primary gateway for Ansible to communicate with Windows hosts. In a standard setup, WinRM can use various transport mechanisms, but Kerberos is preferred for its mutual authentication and encryption capabilities. A critical technical nuance is that Kerberos provides its own layer of encryption. This means that while HTTPS (port 5986) is often used for security, Kerberos authentication is fundamentally safe even over HTTP (port 5985) because the session is encrypted by the Kerberos protocol itself.
The process involves a three-way handshake between the Ansible Controller (or Execution Environment), the KDC (usually the Active Directory Domain Controller), and the target Windows host. The controller requests a ticket from the KDC, which it then presents to the target host to prove its identity. For this to function, the environment running the Ansible code must have a valid Kerberos configuration and the necessary system libraries to handle GSSAPI (Generic Security Services Application Programming Interface) calls.
Prerequisites and System-Level Dependencies
To achieve a successful Kerberos handshake, the system initiating the connection must be equipped with specific binary dependencies and Python libraries. Without these, Ansible will trigger a catastrophic failure with the error: kerberos: the python kerberos library is not installed.
Mandatory System Packages
The underlying operating system (typically RHEL or a similar derivative) requires the development headers and libraries for Kerberos and GSSAPI. The following installation sequence is required:
sudo yum update
sudo yum -y install gcc python3.12-devel krb5-devel krb5-libs krb5-workstation
These packages provide the necessary C headers (krb5-devel) and the workstation tools (krb5-workstation) which include the kinit and klist commands, essential for manual testing and ticket management.
Python Environment Configuration
Once the system libraries are present, the Python environment must be configured to handle the Kerberos transport. This is achieved through the pywinrm library with the kerberos extension.
python3.12 -m pip install --user ansible
python3.12 -m pip install --user ansible-lint
python3.12 -m pip install --user pywinrm
python3.12 -m pip install --user "pywinrm[kerberos]"
The use of the [kerberos] extra in the pip install command ensures that the pywinrm package installs the required dependencies to interface with the system's Kerberos libraries.
Windows Host Configuration and WinRM Optimization
The target Windows machine must be explicitly configured to accept Kerberos requests and allow the specific domain user to execute commands.
Enabling WinRM and HTTP Listeners
The simplest method to enable WinRM is by executing winrm quickconfig on the host, although Enterprise environments typically utilize Group Policy Objects (GPO) for consistent deployment. It is essential to verify that the HTTP listener is active.
To verify the listener status, execute:
winrm enumerate winrm/config/Listener
The expected output should confirm that the Transport is HTTP and the Port is 5985.
Validating Kerberos Service Settings
The WinRM service must be configured to allow Kerberos authentication. This can be checked via the following command:
winrm get winrm/config/Service
In the output, the Auth section must explicitly show:
Kerberos = true
If this is set to false, the Windows host will reject any ticket-based authentication attempts from the Ansible controller, regardless of how correctly the controller is configured.
User Permissions and Access Control
By default, WinRM only permits connections from users within the local Administrators group. For a domain user such as [email protected] to connect, one of two conditions must be met:
- The user must be a member of the local Administrators group on the target host.
- The user must be granted specific Read and Execute permissions for WinRM.
Administrative permissions can be adjusted using the winrm configSDDL default command to modify the security descriptor for the service.
Implementing Kerberos in AWX and Kubernetes Environments
AWX runs Ansible inside containers (Execution Environments), which introduces a layer of abstraction. Since containers are ephemeral and isolated, they do not have inherent access to the host's /etc/krb5.conf or the Kerberos ticket cache.
The ConfigMap and Volume Mounting Strategy
To provide the Execution Environment (EE) with the necessary realm and KDC information, the krb5.conf file must be injected into the pod.
- Create a Kubernetes ConfigMap containing the
krb5.conffile. - Create a Container Group in AWX with a custom pod specification.
- Mount the
krb5.confConfigMap into the pod at the path/etc/krb5.conf.
This ensures that every single task execution has access to the domain configuration, allowing the kinit process to locate the KDC.
Kerberos Credential Management in AWX
Within the AWX UI, a specific Credential must be created for the domain user. The credential should map to the domain account (e.g., [email protected]) and be associated with the Job Template.
Inventory and Variable Configuration
The transition to Kerberos requires specific variables in the Ansible inventory to tell the winrm connection plugin how to behave.
Inventory Specification Table
| Variable | Value | Technical Purpose |
|---|---|---|
ansible_connection |
winrm |
Tells Ansible to use the WinRM protocol instead of SSH. |
ansible_winrm_transport |
kerberos |
Forces the use of Kerberos instead of NTLM or Basic auth. |
ansible_winrm_server_cert_validation |
ignore |
Prevents failure due to self-signed certificates on WinRM. |
ansible_port |
5986 or 5985 |
Defines the port (5986 for HTTPS, 5985 for HTTP). |
ansible_winrm_kinit_mode |
managed |
Instructs Ansible to handle the kinit process automatically. |
ansible_winrm_kinit_cmd |
kinit |
Specifies the binary used to acquire the Kerberos ticket. |
ansible_winrm_operation_timeout_sec |
60 |
Sets the timeout for WinRM operations to prevent hangs. |
ansible_winrm_read_timeout_sec |
90 |
Extends the read timeout for long-running Windows tasks. |
Example Inventory File
```ini [storageservers] SRV1.homelab.local
[storageservers:vars] ansibleconnection=winrm ansiblewinrmservercertvalidation=ignore ansibleport=5986 ansiblewinrmtransport=kerberos ansiblewinrmoperationtimeoutsec=60 ansiblewinrmreadtimeoutsec=90 ansiblewinrmkinitmode=managed ansiblewinrmkinitcmd=kinit ```
Manual Validation and Troubleshooting in Execution Environments
Before deploying a full Job Template, it is critical to verify that the EE can actually communicate with the KDC.
Testing with Podman and kinit
To simulate the EE environment, one can run a container and manually attempt to acquire a ticket. Because the default environment might not have a persistent filesystem for the cache, a temporary cache file should be created using the KRB5CCNAME variable.
podman run --rm -v "/etc/krb5.conf.d:/etc/krb5.conf.d:O" -it registry.redhat.io/ansible-automation-platform-23/ee-supported-rhel8:latest /bin/bash
Once inside the container:
export KRB5CCNAME=$(mktemp)
kinit [email protected]
After providing the password, verify the ticket with:
klist
The output will confirm the ticket cache location and the expiration time of the service principal. To further validate the connection to a specific target host, the kvno command can be used to request the key version number from the target.
Advanced Configuration: Using Variable Files
For flexible deployments, it is recommended to use separate variable files for WinRM settings. This prevents hardcoding credentials and transport settings in the main playbook.
The winrm_vars.yml Implementation
yaml
ansible_user: domainadmin@REALM
ansible_password: !unsafe 234%234{435lkj{{lkjsdf
ansible_connection: winrm
ansible_winrm_transport: kerberos
ansible_winrm_cert_validation: ignore
The use of the !unsafe tag is critical here. In Ansible, certain characters in passwords can be misinterpreted as Jinja2 templates. The !unsafe tag preserves the string exactly as written, ensuring that complex passwords containing characters like #, !, or % are passed correctly to the Kerberos authentication layer.
To test this configuration, use the following command:
ansible all -i "dc01" -m win_ping --extra-vars "@winrm_vars.yml"
Summary of the Integration Workflow
The successful deployment of Ansible WinRM Kerberos requires a synchronized effort across three layers: the infrastructure, the execution environment, and the Ansible configuration.
- Infrastructure Layer: Windows hosts must have WinRM enabled, Kerberos authentication set to
true, and the target user added to the local Administrators group or granted specific WinRM permissions. - Execution Environment Layer: The container must possess
krb5-devel,krb5-libs, andpywinrm[kerberos]. Thekrb5.confmust be mounted via a Kubernetes ConfigMap to provide the realm and KDC details. - Ansible Layer: The inventory must specify
ansible_winrm_transport=kerberosandansible_winrm_kinit_mode=managedto automate the ticket acquisition process.
Conclusion
The integration of Kerberos with Ansible WinRM is a complex but necessary requirement for secure enterprise automation. By shifting from password-based authentication to a ticket-based system, organizations reduce the risk of credential exposure and align with security best practices. The primary challenges lie in the "plumbing"—the mounting of configuration files in Kubernetes and the installation of specific GSSAPI libraries in the Execution Environment. When these are correctly implemented, as demonstrated through the use of custom pod specs in AWX and the precise configuration of pywinrm, Ansible gains the ability to manage Windows fleets with the same level of security and efficiency as Linux fleets. The ability to use !unsafe tags for complex passwords and the validation of tickets via kinit and klist within the EE ensures that the system is not only functional but verifiable.