Desired State Configuration (DSC)
Introduction
Depuis quelque temps, on entend beaucoup parler de systèmes de gestion de configuration. Ils permettent de configurer un ensemble de machines de manière idempotente et en un temps record. L’idempotence est la caractéristique d’une opération à toujours reproduire le même résultat, peu importe l’environnement. Dans le cas présent, il s’agit de toujours avoir la même configuration, quel que soit le nombre de machines. Microsoft a créé Desired State Configuration (DSC) dans ce but. Il existe d’autres solutions similaires, la plus connue aujourd’hui est sans doute Ansible, mais on trouve aussi Chef et Puppet.
DSC permet d’éviter les dérives de configuration. Si le cas se présente, il est capable de remédier à la situation. L’autre avantage sur la gestion de configuration est le temps gagné en termes de résolution d’incidents. Pourquoi plancher une journée entière sur un serveur en panne alors qu’il peut être redéployé et opérationnel en 15 minutes ? Cela représente un réel atout dans une stratégie de cloud. D’ailleurs, Microsoft l’a parfaitement compris, car DSC est utilisable depuis la plateforme de cloud Azure.
Historiquement, on utilisait les stratégies de groupes (GPO) pour mettre...
Versions et plateformes supportées par DSC
Historiquement, DSC est apparu avec la version 4.0 de PowerShell, sous Windows 8.1. La version du moteur DSC était alors 1.0. De plus, la version de DSC était liée à la version de PowerShell et suivait le même rythme de développement. On retrouve donc la version 1.1 du moteur DSC sur Window PowerShell V5.1, et la version 2.0 du moteur sur PowerShell 7.1. Récemment, les équipes DSC et PowerShell ont décidé de séparer la montée de version du moteur DSC de celle de PowerShell, et ce depuis PowerShell 7.2.
En quoi les versions 1.1 et 2.0 sont-elles si divergentes ? Pour le savoir il est possible de se référer à la documentation : https://learn.microsoft.com/en-us/powershell/dsc/overview?view=dsc-2.0#changes-from-dsc-11
Pour résumer :
-
Un grand nombre de cmdlet ont été supprimés.
-
Il est impossible d’utiliser un Pull Server (notion abordée plus loin).
-
Il n’y a pas l’agent local nommé Local Configuration Manager (LCM).
Pour comprendre l’écart entre les versions 1.1 et 2.0 il faut comprendre le but de la version 2.0. À l’origine, elle a été créée pour répondre à un besoin Azure : Azure Machine Configuration (anciennement Guest Configuration). L’idée...
Vue d’ensemble de la solution
Pour mieux appréhender la solution qu’est DSC, nous allons rapidement présenter chaque partie jouant un rôle essentiel dans le fonctionnement global. DSC a la particularité d’avoir été conçu spécialement autour de PowerShell. Ainsi, de l’écriture des configurations au déploiement de celles-ci, tout est réalisé par des commandes PowerShell. Microsoft ne propose pas d’interface graphique pour administrer la solution. Toutefois, on peut compter sur PowerShell ISE et Visual Studio Code pour nous aider dans la conception des configurations.
La plupart des éléments présentés dans ce chapitre sont limités à la version 1.1 du moteur DSC.
1. Terminologie
Terme |
Définition |
DSC Resource |
Composant appelé par DSC pour configurer un élément du système. L’élément peut être une clé de registre, d’un fichier, d’un paramètre DNS, etc. Les ressources sont contenues dans des modules PowerShell. |
DSC Configuration |
Script PowerShell qui définit un type particulier de fonction qui contient la description de la configuration. Les fichiers MOF sont générés lors de son appel. |
Node |
Système client DSC (nœud). |
PULL Server |
En mode PULL, il s’agit du serveur centralisant l’ensemble des configurations que viennent récupérer les postes clients. |
Local Configuration Manager (LCM ou gestionnaire local de configuration) |
Moteur d’exécution client de DSC. Il est chargé d’interpréter la configuration DSC reçue (PUSH) ou récupérée (PULL) pour l’appliquer sur l’hôte local. |
Métaconfiguration |
Nom de la configuration du LCM. |
MOF |
Format du fichier texte généré lors de l’appel d’une configuration. Ce type de fichier répond à la grammaire IDL définie par le DMTF. |
2. Considérations générales
Par défaut, les configurations sont appliquées avec le compte LocalSystem. Cela engendre de fortes contraintes s’il est nécessaire d’exécuter des commandes qui réclament des droits particuliers ou bien si la configuration doit accéder à des partages réseau....
Ressources DSC
Les ressources DSC contiennent les instructions de configuration d’un composant particulier. Le LCM utilise les ressources DSC pour configurer l’hôte sur lequel il se trouve en se basant sur un fichier MOF.
Il est primordial que les ressources dont a besoin un LCM soient disponibles localement dans le cas d’une configuration en mode PUSH, ou sur un PULL Server distant dans le cas du mode PULL.
Dans les sections qui suivent, nous allons voir comment trouver la bonne ressource et adapter sa syntaxe à notre besoin.
1. Lister des ressources présentes
Pour énumérer les ressources disponibles sur un système, on utilise la commande Get-DscResource.
Voici un exemple sur un système Windows Server 2016 disposant de PowerShell version 5.1 :
PS > Get-DscResource
ImplementedAs Name ModuleName
------------- ---- ----------
Binary File
Binary SignatureValidation
PowerShell PackageManagement PackageManagement
PowerShell PackageManagementSource PackageManagement
PowerShell PsModule PowerShellGet
PowerShell PsRepository PowerShellGet
PowerShell Archive PSDesiredStateConfig...
PowerShell Environment PSDesiredStateConfig...
PowerShell Group PSDesiredStateConfig... ...
Création d’une première configuration
Une configuration DSC se crée à l’aide du mot-clé configuration. Une configuration est très proche d’une fonction ou d’un workflow. Tous acceptent un nom et une définition de paramètres. De même que leur utilisation passe par l’appel de leur nom directement dans la console, comme une simple commande PowerShell.
1. Création rapide avec ISE
En début de chapitre, nous avons abordé de manière générique la syntaxe d’une configuration. Dans la section qui suit, nous allons rassembler tout ce que nous avons, configuration et ressources pour former une première configuration DSC. Puis nous approfondirons cette configuration en ajoutant de nouveaux éléments.
Pour commencer sereinement l’écriture d’une configuration, on utilise l’aide de PowerShell ISE et de ses snippets. Historiquement, on pouvait faire de même avec VSCode, mais les références à DSC dans les snippets proposées par PowerShell ne sont plus présentes. On voit là encore cette volonté de scission entre DSC et PowerShell.
Ouvrez PowerShell ISE. Dans un nouveau fichier, faites un clic droit et sélectionnez Start Snippets (Démarrer les extraits en français). Dans la liste déroulante qui s’affiche, cliquez sur DSC configuration (simple) :
Utilisation du snippet DSC Configuration dans PowerShell ISE
Le résultat :
configuration Name
{
# Possibilité d'évaluation des expressions pour obtenir
la liste des noeuds
# Exemple : $AllNodes.Where("Role -eq Web").NodeName
node ("Node1","Node2","Node3")
{
# Appel du fournisseur de ressources
# Exemple : WindowsFeature, File
WindowsFeature FriendlyName
{
Ensure = "Present"
...
Configuration du LCM
Le LCM est le moteur en charge d’appliquer les configurations DSC à destination de son système hôte (nœud).
La configuration est décrite dans un fichier MOF généré lors de l’appel d’une configuration script.
1. Configuration courante
Il est possible de configurer le LCM à travers un ensemble de métaconfigurations. Pour connaître la configuration courante du LCM, on utilise la commande Get-DscLocalConfigurationManager.
PS > Get-DSCLocalConfigurationManager
ActionAfterReboot : ContinueConfiguration
AgentId : 2B7CB1C9-70BD-11E8-80DB-00155D01
0108
AllowModuleOverWrite : False
CertificateID :
ConfigurationDownloadManagers : {}
ConfigurationID :
ConfigurationMode : ApplyAndMonitor
ConfigurationModeFrequencyMins : 15
Credential :
DebugMode : {NONE}
DownloadManagerCustomData :
DownloadManagerName :
LCMCompatibleVersions : {1.0, 2.0}
LCMState : Idle
LCMStateDetai : ...
Fichiers MOF
MOF (Managed Object Format) est un format de fichier défini par le DMTF. MOF s’appuie sur le format IDL (Interface Definition Language) pour structurer le fichier.
La syntaxe MOF est écrite de manière à être compréhensible à la fois par l’homme et la machine. Elle permet de définir des classes orientées objet ainsi que des instances.
1. Fichier MOF de configuration
Exemple du fichier MOF de la configuration ConfigBackup du nœud SRV2K22 :
/*
@TargetNode='SRV2K22'
@GeneratedBy=administrateur
@GenerationDate=06/15/2018 18:56:57
@GenerationHost=SRV2K22
*/
instance of MSFT_RoleResource as $MSFT_RoleResource1ref
{
ResourceID = "[WindowsFeature]WindowsBackup";
Ensure = "Present";
SourceInfo = "::5::9::WindowsFeature";
Name = "Windows-Server-Backup";
ModuleName = "PsDesiredStateConfiguration";
ModuleVersion = "1.0";
ConfigurationName = "ConfigBackup";
};
instance of MSFT_FileDirectoryConfiguration as
$MSFT_FileDirectoryConfiguration1ref
{
ResourceID = "[File]BackupFolder";
Type = "Directory";
Ensure = "Present";
DestinationPath = "C:\\Backup"; ...
Sécurité et contexte d’exécution (credentials)
Le LCM s’exécute avec le compte LocalSystem. Cela représente une forte contrainte lorsqu’une configuration nécessite de contacter une ressource réseau, comme un partage SMB. En effet, le nœud se voit refuser l’accès.
Pour pallier cette contrainte, plusieurs solutions sont possibles :
-
Modifier les droits du partage pour autoriser le compte Ordinateur en accès.
-
Passer des credentials à la configuration.
La première solution a un rayon d’action très limité. En effet, si l’on veut installer un contrôleur de domaine, des credentials de domaine sont nécessaires et la solution ne s’applique pas ici.
On peut alors opter pour la seconde solution. Seulement, étant donné que l’application d’une configuration passe par la génération d’un fichier MOF, ce dernier contient les informations d’identification, soit le nom du compte et le mot de passe. Deux choix s’offrent alors. Le premier consiste à inscrire le mot de passe en clair dans le fichier, avec tous les problèmes de sécurité que cela implique. Le second choix consiste à configurer des certificats pour crypter les mots de passe à l’intérieur du fichier MOF. La mise en place est toutefois beaucoup plus contraignante....
Sécurisation des credentials dans une configuration
Pour certaines ressources, il est nécessaire d’utiliser des credentials dans des configurations. Ce besoin peut se présenter si le nœud doit accéder à un partage réseau, ou encore si l’on doit le promouvoir contrôleur de domaine.
L’utilisation de credentials engendre un stockage du login et du mot de passe à l’intérieur du fichier MOF généré. Ce mot de passe peut se présenter de deux manières :
-
en clair, lisible par tous
-
chiffré à l’aide d’un certificat
Bien évidemment, le premier cas est réservé aux environnements de test. La mise en place du chiffrement doit se faire impérativement dans les autres environnements, car on peut douter qu’un manager apprécie le stockage en clair du mot de passe de l’administrateur du domaine, sur un environnement de production. D’autant plus si on utilise un serveur PULL, centralisant l’ensemble des configurations en un seul point.
1. Prérequis
La mise en place du chiffrement des mots de passe à l’intérieur des fichiers MOF nécessite un certain nombre de prérequis :
-
Les certificats doivent permettre le chiffrement de documents. Ils peuvent provenir d’une infrastructure de gestion de clés (PKI) comme Active Directory Certificate Service (AD CS) ou bien il peut s’agir de quelques certificats générés manuellement ou provenant d’un tiers. Idéalement, il faut un certificat de chiffrement par nœud.
-
Les certificats doivent être installés dans le magasin ordinateur (Cert:\LocalComputer\My) de chaque nœud.
-
La clé publique (dans un fichier .cert) de chacun des certificats doit être disponible sur le serveur générant les fichiers MOF.
-
L’empreinte (Thumbprint) de chaque certificat doit être disponible.
2. Étapes de réalisation
La mise en œuvre de la sécurisation des credentials passe par des étapes précises :
-
La mise en place des certificats de chiffrement sur chaque nœud, avec export...
Configuration d’un PULL Server
Le mode PULL présente de gros avantages comparativement au mode PUSH. En effet, dans un environnement de grande ampleur, réaliser les configurations de serveur en mode PUSH présente rapidement des limites.
L’objectif du mode PULL est de centraliser les configurations de chaque nœud et de faire en sorte qu’ils procèdent eux-mêmes au téléchargement de nouvelles configurations, et surtout au téléchargement automatique des ressources DSC nécessaires à l’application des configurations.
Le PULL Server Web apporte également la possibilité de mettre en place des rapports pour suivre l’état de conformité de chaque nœud.
1. Évolution du PULL Server
Depuis l’arrivée de PowerShell Core, Microsoft a quelque peu mis de côté les évolutions fonctionnelles de la fonctionnalité PULL Server Web de Windows Server. Il préconise aujourd’hui les solutions Azure Automation Desired State Configuration Service, et Azure Automanage Machine Configuration. Comme leur nom l’indique, elles sont disponibles seulement sur la plateforme Cloud Azure de l’éditeur. Si pour certaines raisons, il vous est impossible d’utiliser Azure pour créer un PULL Server Web, ou bien avec la fonctionnalité Windows Server, il reste la possibilité d’utiliser des projets communautaires. On en dénombre deux :
Malheureusement, ces projets semblent à l’arrêt depuis plusieurs années. Reste la possibilité d’utiliser un partage SMB, avec les limitations qui l’accompagnent.
Dans les sections qui suivent, nous avons choisi de mettre l’accent sur l’utilisation de Windows Server.
2. PULL Server sous partage SMB
Depuis la version 5.1 de PowerShell, il est possible de construire un PULL Server depuis un simple partage SMB. La mise en œuvre n’est pas couverte ici. Celle-ci est conseillée dans le cadre de petite structure avec très peu de besoins.
Avec un PULL Server SMB, il n’est pas possible de mettre en place un système de reporting des configurations. De même que les configurations basées sur le nom ne sont...
Test de conformité d’un nœud
La conformité est le maître mot sous DSC. Ce dernier offre donc la possibilité de vérifier la bonne application des configurations sur un nœud donné. En effet, l’utilisation seule de DSC ne suffit pas à dire que le système est conforme. Plusieurs facteurs entrent en jeu. D’une part, si la configuration du LCM n’est pas en mode autocorrection, alors n’importe qui ou n’importe quoi peut modifier directement la configuration. D’autre part, si le mode autocorrection est actif, le système peut très bien rencontrer un blocage technique pour procéder à la mise en conformité.
Pour tous ces cas, la commande Test-DscConfiguration offre la capacité de tester la configuration d’un système local ou distant. La valeur renvoyée par la commande est de type booléen.
Exemples
PS > Test-DscConfiguration
True
PS > Test-DscConfiguration -ComputerName SRV2K22
True
PS > $CimSession = New-CimSession -ComputerName SRV2K22
PS > Test-DscConfiguration -CimSession $CimSession
True
Application de la dernière bonne configuration connue
Il peut arriver qu’une nouvelle configuration pose un problème lorsqu’on procède à son application. Dans ce cas, il est possible de repasser rapidement à la configuration précédente. Pour cela, on utilise la commande Restore-DSCConfiguration. Aucun paramètre particulier à renseigner, sauf si l’on souhaite utiliser une session CIM pour agir sur un système distant.
PS > Restore-DscConfiguration
La commande va simplement chercher la configuration stockée sous C:\Windows\ System32\Configuration\backup.mof.
Principe avancé
Au début de DSC sous PowerShell version 4.0, il n’était pas possible d’appliquer plusieurs configurations sur un même hôte. On rencontrait alors de grandes difficultés pour mettre à jour une partie de la configuration, car les fichiers de configuration devenaient énormes. La solution de contournement mise en avant était la création de ressources dites composites. Ces dernières contiennent en réalité un sous-ensemble de ressources DSC préconfiguré dans une configuration. Il était alors possible de les appeler directement dans une configuration.
Depuis PowerShell versions 5.1, la contrainte de configuration unique a été levée. Il est maintenant possible de créer un ensemble de configurations avec des noms différents à destination d’un même hôte. Ces configurations sont appelées configurations partielles (ou partial configuration en anglais).
Ces deux solutions seront vues dans cette section. Dans l’ancienne version de cet ouvrage, il a été conseillé d’utiliser en priorité les configurations partielles. Il s’avère que les ressources composites sont plutôt à prioriser. Pourquoi ? Pour limiter les conflits entre configurations. Il est plus cohérent d’appliquer une configuration unique, validée par une équipe unique, plutôt qu’un ensemble de configurations disparates réparties entre plusieurs équipes qui ne communiquent pas forcément. Les risques de dérives seront bien moins présents et le contrôle de la configuration des nœuds sera plus efficient.
1. Ressource composite
Les ressources composites sont en réalité des configurations "déguisées". Elles regroupent un ensemble de paramètres génériques valant pour l’ensemble des nœuds. En effet, il n’est pas rare d’avoir tout un panel de configurations à mettre en place sur l’ensemble des serveurs. Cela peut inclure la configuration antivirus, les paramètres réseau (serveur DNS, passerelle, etc.), les variables d’environnement, clés de registre, etc. Un très bon exemple de ressource composite est le module CommonTasks...
Écriture d’une ressource personnalisée
Même si aujourd’hui les ressources créées par la communauté et mises à disposition sur la PowerShell Gallery sont assez importantes, elles ne couvrent pas tous les besoins. Dans cette optique, Microsoft permet de créer des ressources DSC personnalisées.
La ressource Script permet d’offrir une méthode de traitement personnalisé sur un nœud (voir la section Ressources DSC - Ressources intégrées). Toutefois, celle-ci manque de flexibilité.
Pour cette raison, on peut opter pour l’une des deux méthodes décrites ci-après. La première est présente depuis la version 4.0 de Windows PowerShell. Elle utilise une structure de modules particulière, ainsi qu’un fichier de schéma MOF décrivant une ressource. La seconde méthode a été introduite avec Windows PowerShell version 5. Elle se base sur les classes PowerShell (voir le chapitre Classes). Avec l’arrivée des nouvelles versions du moteur DSC, il est préconisé de développer ses ressources en se basant sur des classes. La DSC Community migre petit à petit l’ensemble de ses ressources sur cette écriture. La raison est que l’écriture MOF est abandonnée au profit des classes.
1. Ressource personnalisée avec un fichier MOF
a. Constitution d’une ressource basée sur un schéma MOF
Une ressource DSC basée sur un fichier de schéma MOF doit contenir un certain nombre de fichiers particuliers :
-
un fichier MOF portant l’extension .schema.mof décrivant la ressource,
-
un fichier module script au format PSM1 contenant le mécanisme de la ressource,
-
un manifeste de module (optionnel) portant l’extension .psd1.
Elle doit également être intégrée dans un module PowerShell avec une arborescence particulière :
$env:ModulePath
└─<ModuleName>
└─DSCResources
├─<ResourceName1>
├─<ResourceName1>.schema.mof
├─<ResourceName1>.psm1 ...
DSC sous Linux
C’est ici que l’on voit que DSC a pris un réel essor. Avoir la possibilité de configurer des machines Linux de manière centralisée depuis une machine Windows est un réel pas en avant. Ainsi, dans cette section sera décrite la mise en œuvre d’une configuration DSC pour un système Linux.
Le système Linux utilisé ici est Debian. Le système générant la configuration et l’appliquant est Windows 10.
1. Prérequis
Avant de se lancer dans la configuration, des éléments sont à mettre en place sur la machine Linux. Pour communiquer entre machines Windows, DSC utilise le standard CIM. L’équivalent de ce standard sous Linux est OMI (Open Management Infrastructure). Ce dernier n’est pas présent par défaut, il faut donc l’installer avant d’installer le package DSC. PowerShell Core doit également être installé (voir le chapitre PowerShell et la gestion des versions - Installation de PowerShell Core).
a. Installation du package OMI
Pour l’installation du package OMI, il est nécessaire d’avoir au préalable renseigné le dépôt Microsoft pour la distribution Linux. Il s’agit du même que pour PowerShell Core. La procédure est décrite dans le chapitre PowerShell et la gestion des versions - Installation de PowerShell Core.
Une fois le dépôt renseigné, il est possible de cibler directement le package OMI :
:~# sudo apt-get -y install omi
Ensuite, on vérifie la version d’OpenSSL installée :
:~# openssl version
OpenSSL 1.1.1l 24 Aug 2021
b. Installation du package DSC
Maintenant que le package OMI est en place, on peut installer le package DSC. En premier lieu, on choisit la bonne version en fonction de la version d’OpenSSL vu précédemment. Les différentes versions sont disponibles sur : https://github.com/Microsoft/PowerShell-DSC-for-Linux/releases
Ici, on choisit la version compatible 1.1.0 :
:~# https://github.com/microsoft/PowerShell-DSC-for-
Linux/releases/download/v1.2.4-0/dsc-1.2.4-0.ssl_110.x64.deb
Puis, on l’installe :
:~# dpkg -i ./dsc-1.2.4-0.ssl_110.x64.deb
Enfin, on vérifie le statut du service omid...
Maintenance et dépannage
1. Forcer la réapplication d’une configuration
Attendre 15 minutes, voire plus, pour qu’une configuration se réapplique est parfois long, d’autant plus si l’on a besoin du résultat pour corriger un bogue ou remettre en conformité d’urgence le serveur. Pour effectuer cette action, aucune commande PowerShell n’est disponible. Il existe quand même un moyen, en utilisant la méthode d’une classe WMI.
On dispose ainsi de la commande suivante :
Invoke-CimMethod -ClassName MSFT_DSCLocalConfigurationManager `
-Namespace root/Microsoft/Windows/DesiredStateConfiguration `
-MethodName PerformRequiredConfigurationChecks `
-Arguments @{Flags = [System.UInt32]1}
L’avantage de cette commande est qu’elle accepte les paramètres -ComputerName et -CimSession. Ainsi, il est possible d’exécuter la commande à destination d’un hôte distant.
2. État d’une configuration DSC
Pour diagnostiquer un problème de configuration, il est possible de faire appel à la commande Get-DscConfigurationStatus. Cette dernière renvoie l’état de toutes les configurations en cours.
Exemple
PS C:\Scripts> Get-DscConfigurationStatus
Status StartDate Type Mode Reboot ...