Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 1015 minIntermédiaire

Gérer Windows Server avec Ansible (WinRM, SSH)

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • dire ce qui change quand Ansible gère Windows ;
  • choisir entre WinRM et SSH ;
  • préparer Windows Server 2025 pour WinRM en HTTPS ;
  • écrire les variables de connexion d'un groupe Windows avec Kerberos ;
  • diagnostiquer une connexion qui échoue.

2 exercices corrigés

Ansible gère Windows Server sans agent, comme Linux : il s'y connecte en WinRM ou en SSH et exécute des modules écrits en PowerShell, rassemblés dans les collections ansible.windows, community.windows et microsoft.ad. Ce chapitre explique ce qui change avec Windows, compare WinRM et SSH, prépare Windows Server 2025, écrit les variables de connexion avec Kerberos et présente les modules à connaître ; le chapitre 11 s'en sert pour automatiser le serveur de fichiers, le DHCP, le DNS et les comptes Active Directory de Sorbier.

Ce qui change avec Windows

LinuxWindows
ConnexionSSHWinRM (HTTP 5985, HTTPS 5986) ou SSH
Langage des modulesPython, exécuté par le Python du serveurPowerShell 5.1, fourni avec Windows ; pas de Python à installer
Modulesansible.builtin.*, ansible.posix.*…ansible.windows.win_*, community.windows.*, microsoft.ad.*
Élévation de privilègesbecome_method: sudobecome_method: runas (rarement utile : on se connecte avec un compte administrateur)
Chemins/etc/chrony/chrony.confD:\Partages\Compta : entre apostrophes en YAML, ou avec des / que Windows accepte
Nœud de contrôlePossibleImpossible (sauf à travers WSL) : Windows est seulement un nœud géré

Les modules Linux ne fonctionnent pas sur Windows : ansible.builtin.copy ne copie pas vers un serveur Windows, il faut ansible.windows.win_copy. Quelques modules font exception et marchent des deux côtés (ansible.builtin.setup, ansible.builtin.debug, ansible.builtin.set_fact, ansible.builtin.include_tasks), parce qu'ils s'exécutent sur le nœud de contrôle ou ont une version PowerShell.

WinRM ou SSH ?

Ansible propose deux façons de joindre un serveur Windows :

WinRMSSH
PrincipeLe service de gestion à distance de Windows (WS-Management), sur lequel repose aussi PowerShell RemotingLe serveur OpenSSH fourni par Microsoft
Ports5985 (HTTP), 5986 (HTTPS)22
Présence sur Windows Server 2025Service actif par défaut, écouteur HTTP configuréInstallé mais désactivé par défaut
AuthentificationKerberos, NTLM, certificat, CredSSP, BasicClé, mot de passe, Kerberos (GSSAPI)
Bibliothèque côté nœud de contrôlepywinrm (et pywinrm[kerberos] pour Kerberos)Aucune
Statut dans AnsibleHistorique, le plus documentéOfficiellement pris en charge depuis ansible-core 2.18, à partir de Windows Server 2022

WinRM reste le choix le plus courant dans un domaine Active Directory, avec Kerberos ; c'est celui de Sorbier. SSH est une alternative simple, surtout hors domaine : mêmes clés que pour Linux, un seul port à ouvrir. Ansible propose aussi le plugin psrp, qui passe par le même service que WinRM avec le protocole de PowerShell Remoting.

Préparer Windows Server 2025 pour WinRM en HTTPS

Sur Windows Server, le service WinRM tourne et un écouteur HTTP (5985) existe déjà. En HTTP, Kerberos chiffre les échanges ; mais un écouteur HTTPS chiffre tout le canal, quel que soit le mode d'authentification, et c'est la configuration recommandée. Il lui faut un certificat de machine : idéalement délivré par l'autorité de certification interne de Sorbier (inscription automatique par GPO, cours Cybersécurité des infrastructures) ; en laboratoire, un certificat auto-signé.

Sur chaque serveur Windows, dans une console PowerShell en administrateur, la procédure de la documentation d'Ansible, adaptée pour n'accepter que le bastion :

powershell
# Certificat auto-signé pour le laboratoire (en production : un certificat de l'AC interne)
$certParams = @{
    CertStoreLocation = 'Cert:\LocalMachine\My'
    DnsName           = "$env:COMPUTERNAME.ad.sorbier.example"
    NotAfter          = (Get-Date).AddYears(1)
    Provider          = 'Microsoft Software Key Storage Provider'
    Subject           = "CN=$env:COMPUTERNAME.ad.sorbier.example"
}
$cert = New-SelfSignedCertificate @certParams

# Écouteur WinRM en HTTPS sur le port 5986
$httpsParams = @{
    Path                  = 'WSMan:\localhost\Listener'
    Address               = '*'
    CertificateThumbprint = $cert.Thumbprint
    Enabled               = $true
    Port                  = 5986
    Transport             = 'HTTPS'
    Force                 = $true
}
New-Item @httpsParams

# Pare-feu Windows : 5986 ouvert au seul bastion, sur le profil Domaine
$firewallParams = @{
    Action        = 'Allow'
    Description   = 'WinRM HTTPS depuis le bastion Ansible'
    Direction     = 'Inbound'
    DisplayName   = 'WinRM HTTPS (bastion Ansible)'
    LocalPort     = 5986
    Profile       = 'Domain'
    Protocol      = 'TCP'
    RemoteAddress = '192.168.10.210'
}
New-NetFirewallRule @firewallParams

# Vérifier les écouteurs
winrm enumerate winrm/config/Listener

RemoteAddress limite la règle au bastion : même si un poste du réseau découvre le port, il ne peut pas s'y connecter. Il faut aussi la règle du pare-feu réseau, du bastion vers les serveurs Windows en TCP 5986 (chapitre 2). Sur un parc de serveurs, la configuration de WinRM se déploie plutôt par GPO (écouteur, règle de pare-feu, inscription du certificat), comme le montre le cours Windows Server.

Les variables de connexion avec Kerberos

Le fichier inventaire/group_vars/windows/vars.yml :

yaml
---
ansible_connection: winrm
ansible_port: 5986
ansible_winrm_transport: kerberos
ansible_user: svc-ansible@AD.SORBIER.EXAMPLE
ansible_password: "{{ vault_mdp_svc_ansible }}"

et inventaire/group_vars/windows/vault.yml, chiffré par Ansible Vault (chapitre 9), contient vault_mdp_svc_ansible. Le port 5986 implique HTTPS. Le compte s'écrit avec le royaume Kerberos en majuscules, AD.SORBIER.EXAMPLE.

Kerberos impose trois choses au nœud de contrôle :

1. Les bibliothèques Kerberos et pywinrm avec sa prise en charge de Kerberos :

bash
sudo apt install krb5-user libkrb5-dev python3-dev
pipx inject ansible-core "pywinrm[kerberos]"

2. Le fichier /etc/krb5.conf, qui dit où trouver les contrôleurs du royaume :

ini
[libdefaults]
    default_realm = AD.SORBIER.EXAMPLE

[realms]
    AD.SORBIER.EXAMPLE = {
        kdc = srv-ad.ad.sorbier.example
        kdc = srv-ad2.ad.sorbier.example
    }

[domain_realm]
    .ad.sorbier.example = AD.SORBIER.EXAMPLE
    ad.sorbier.example = AD.SORBIER.EXAMPLE

3. Des noms, pas des adresses. Un ticket Kerberos est délivré pour un nom de service (HTTP/srv-fichiers.ad.sorbier.example) : avec une adresse IP, l'authentification échoue. Le bastion doit donc utiliser le DNS de l'Active Directory (192.168.10.177 et .181), et l'inventaire doit désigner les serveurs Windows par leur nom complet. Dans hosts.yml, la partie Windows devient :

yaml
    windows:
      children:
        controleurs:
          hosts:
            srv-ad:
              ansible_host: srv-ad.ad.sorbier.example
            srv-ad2:
              ansible_host: srv-ad2.ad.sorbier.example
        fichiers:
          hosts:
            srv-fichiers:
              ansible_host: srv-fichiers.ad.sorbier.example

Avec ansible_user et ansible_password dans les variables, le plugin WinRM obtient lui-même le ticket Kerberos ; pas besoin de lancer kinit. Il faut aussi que l'heure du bastion soit synchronisée avec celle des contrôleurs : Kerberos refuse un écart de plus de cinq minutes (le rôle socle y veille).

La variante SSH. Sur Windows Server 2025, OpenSSH Server est déjà installé : active-le dans le Gestionnaire de serveur (page Serveur local, propriété d'accès SSH à distance, Remote SSH Access sur un système en anglais) ou en PowerShell avec Set-Service -Name sshd -StartupType Automatic -Status Running. Règle PowerShell comme shell par défaut (valeur DefaultShell de la clé HKLM:\SOFTWARE\OpenSSH), puis, dans l'inventaire :

yaml
ansible_connection: ssh
ansible_shell_type: powershell

Pour un compte administrateur, la clé publique se dépose dans C:\ProgramData\ssh\administrators_authorized_keys, pas dans le profil de l'utilisateur. Limite à connaître : avec une authentification par clé, la session n'a pas d'identité réseau (problème du « double saut ») et ne peut pas accéder à un partage d'un autre serveur.

Le premier contact

bash
ansible windows -m ansible.windows.win_ping
text
srv-ad | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
srv-ad2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
srv-fichiers | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Les erreurs les plus fréquentes :

Message (extrait)Cause probable
winrm or requests is not installedpywinrm absent de l'environnement d'Ansible : pipx inject ansible-core pywinrm
Server not found in Kerberos databaseConnexion par adresse IP, ou nom DNS qui ne correspond pas au compte d'ordinateur
Clock skew too greatPlus de cinq minutes d'écart entre le bastion et le contrôleur de domaine
certificate verify failedCertificat auto-signé ou d'une AC que le bastion ne connaît pas : installer le certificat de l'AC interne sur le bastion, ou ansible_winrm_ca_trust_path
connect timeout ou Connection refused sur 5986Écouteur HTTPS absent, ou flux bloqué par le pare-feu Windows ou réseau
the specified credentials were rejected by the serverMauvais mot de passe, compte sans droits d'administration, ou royaume mal écrit

Les modules Windows à connaître

BesoinModule
Rôles et fonctionnalités (AD DS, DHCP, serveur de fichiers)ansible.windows.win_feature
Servicesansible.windows.win_service
Mises à jour Windowsansible.windows.win_updates
Redémarrer et attendre le retouransible.windows.win_reboot
Installer un logiciel (MSI, EXE)ansible.windows.win_package
Copier un fichier, générer un fichier depuis un modèleansible.windows.win_copy, ansible.windows.win_template
Dossiers et fichiersansible.windows.win_file
Partages SMBansible.windows.win_share
Droits NTFSansible.windows.win_acl
Registreansible.windows.win_regedit
Pare-feu Windowsansible.windows.win_firewall_rule
Comptes et groupes locauxansible.windows.win_user, ansible.windows.win_group, ansible.windows.win_group_membership
DNS (enregistrements, zones)ansible.windows.win_dns_record, ansible.windows.win_dns_zone
DHCP (réservations, baux)ansible.windows.win_dhcp_lease
Active Directory : OU, groupes, utilisateurs, ordinateurs, jonction au domainemicrosoft.ad.ou, microsoft.ad.group, microsoft.ad.user, microsoft.ad.computer, microsoft.ad.membership
Créer une forêt, promouvoir un contrôleurmicrosoft.ad.domain, microsoft.ad.domain_controller
Exécuter du PowerShellansible.windows.win_powershell, ansible.windows.win_command, ansible.windows.win_shell

Exercices

Exercice 1 sur 2 Les variables d'un laboratoire Réussi À revoir

Dans ton laboratoire, un serveur srv-test (192.168.56.20) n'est pas dans un domaine. Il a un compte administrateur local ansible-local et l'écouteur HTTPS avec un certificat auto-signé. Écris le fichier host_vars/srv-test.yml, en rangeant le mot de passe dans le coffre. Dis pourquoi cette configuration ne doit pas aller en production.

Voir la réponseMasquer la réponse de l'exercice 1
yaml
---
ansible_host: 192.168.56.20
ansible_connection: winrm
ansible_port: 5986
ansible_winrm_transport: ntlm
ansible_winrm_server_cert_validation: ignore
ansible_user: ansible-local
ansible_password: "{{ vault_mdp_ansible_local }}"

avec vault_mdp_ansible_local dans un fichier chiffré par Ansible Vault. Kerberos n'est pas possible hors domaine, d'où NTLM, qui passe dans le canal HTTPS. En production : NTLM est un protocole ancien et affaibli, que Microsoft abandonne progressivement ; cert_validation: ignore accepte n'importe quel certificat, donc ne protège pas d'une interception de l'homme du milieu. Dans un domaine, on utilise Kerberos et un certificat de l'AC interne, que le bastion sait vérifier.

Tu avais trouvé ?

Exercice 2 sur 2 Diagnostiquer une connexion Réussi À revoir

Moussa ajoute srv-fichiers avec ansible_host: 192.168.10.178 et la configuration Kerberos du chapitre. win_ping échoue : « Server not found in Kerberos database ». Explique et corrige.

Voir la réponseMasquer la réponse de l'exercice 2

Kerberos délivre un ticket pour un nom de service. En se connectant par l'adresse IP, le client demande un ticket pour HTTP/192.168.10.178, qui n'existe pas dans l'annuaire, d'où l'erreur. Il faut ansible_host: srv-fichiers.ad.sorbier.example, et que le bastion résolve ce nom par le DNS de l'Active Directory. On vérifie avec getent hosts srv-fichiers.ad.sorbier.example sur le bastion, puis on relance ansible srv-fichiers -m ansible.windows.win_ping.

Tu avais trouvé ?

Chapitre terminé !

Fais les 2 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Automatiser Windows Server et Active DirectoryRevoir le sommaire du cours