Juste un autre outil: apprendre à connaître la configuration du service avec la configuration de l'état souhaité 

La configuration de l'état souhaité (DSC) est un outil de gestion de la configuration du serveur. Avec lui, vous pouvez configurer le serveur (apporter des modifications au registre, copier des fichiers, installer et supprimer des composants), surveiller l'état actuel des paramètres et revenir rapidement aux paramètres de base.

DSC est intéressant pour ceux qui suivent l'approche DevOps. Cet outil s'intègre bien à l'infrastructure en tant que paradigme de code: les développeurs peuvent ajouter leurs exigences à la configuration et l'inclure dans le système de contrôle de version, et les équipes peuvent déployer le code sans utiliser de processus «manuels».

Avec Stanislav Buldakov de RaiffeisenbankNous avons combiné notre expérience avec le moteur DSC et l'avons divisé en 2 articles. Dans la première, nous analyserons les principes de base du travail et nous familiariserons avec les caractéristiques d'utilisation sur des exemples pratiques:

  • «Déballez la boîte» avec le moteur DSC, voyez quelles sont les ressources par défaut et montrez où trouver des ressources supplémentaires;
  • Voyons comment décrire la configuration dans DSC; 
  • Nous apprendrons comment l'agent intégré Local Configuration Manager applique les configurations sur le serveur, montrerons comment il est configuré à l'aide de méta-configurations;
  • Passons à des cas de configuration plus complexes: configurations partielles et configurations de stub.



DSC est un moteur léger et rapide. Par exemple, en l'utilisant, vous pouvez installer le .NET Framework 3.5 sur des machines virtuelles beaucoup plus rapidement. Voici ce qui l'aide à accélérer le processus de configuration du service:

  • « » Windows PowerShell. 
    DSC PowerShell Windows Management Framework. Linux . , PowerShell. 
  • , . 
    , , , . DSC. 
  • , .
    DSC , . .

Les configurations sont toujours effectuées de manière séquentielle, sans conditions ni branchement. Par conséquent, brièvement, l'algorithme d'opération DSC ressemble à ceci:

  1. Configurez le gestionnaire de configuration local (LCM) . Il s'agit de l'agent intégré chargé d'appliquer les configurations au serveur. Nous lui disons comment les configurations déclarées devraient fonctionner et dans quel ordre. 
  2. Si des ressources supplémentaires sont nécessaires, installez-les et connectez-les à l'avance.
  3. Sous une forme déclarative, nous écrivons l'ordre de configuration. 
  4. Nous diffusons la configuration au format du fichier MOF.
  5. Nous envoyons la configuration au serveur fraîchement déployé ou existant cible.
  6. LCM reçoit la configuration (fichier MOF) ainsi que les instructions de configuration du LCM lui-même.
  7. La configuration est immédiatement appliquée par notre équipe.


Un schéma simplifié de l'architecture DSC.

Nous allons commencer notre connaissance du moteur en étudiant les ressources prédéfinies. Ensuite, essayez d'écrire la configuration.

Ressources DSC 


Les ressources DSC sont une sorte d'analogue des modules PowerShell. Tout serveur Windows possède déjà un ensemble prédéfini de ressources DSC; elles se trouvent dans le même répertoire que les modules PowerShell. La liste peut être obtenue via l'applet de commande Get-DscResourse. Voici à quoi ressemble cette liste sur Windows 10 1809:
 
PS C:\windows\system32> Get-DscResource | Sort-Object -Property Name | ft ImplementedAs, Name -a
 
ImplementedAs Name
------------- ----
   PowerShell Archive
   PowerShell Environment
       Binary File
   PowerShell Group
    Composite GroupSet
       Binary Log
   PowerShell Package
   PowerShell PackageManagement
   PowerShell PackageManagementSource
    Composite ProcessSet
   PowerShell Registry
   PowerShell Script
   PowerShell Service
    Composite ServiceSet
       Binary SignatureValidation
   PowerShell User
   PowerShell WaitForAll
   PowerShell WaitForAny
   PowerShell WaitForSome
   PowerShell WindowsFeature
    Composite WindowsFeatureSet
   PowerShell WindowsOptionalFeature
    Composite WindowsOptionalFeatureSet
   PowerShell WindowsPackageCab
   PowerShell WindowsProcess

Les noms des ressources permettent de comprendre avec quoi elles travaillent: 

  • Archive - avec des archives d'emballage et de déballage;
  • Environnement - avec variables d'environnement;
  • Fichier - avec fichiers;
  • Groupe - avec des groupes d'utilisateurs locaux;
  • Journal - avec journaux;
  • Package —– avec packages logiciels;
  • Registre —– avec les clés de registre et leur statut;
  • Service - avec les services et leur statut;
  • Utilisateur - avec des comptes d'utilisateurs locaux;
  • WindowsFeature — Windows Server;
  • WindowsProcess — Windows;
  • Script —  PowerShell- . 3 : SetScript — -, TestScript — , , GetScript — .

Le plus souvent, les ressources DSC prêtes à l'emploi ne sont pas suffisantes . Dans ce cas, vous pouvez écrire vos propres scripts pour tout ce qui va au-delà du module standard. Afin de ne pas réinventer la roue, vous pouvez utiliser des ressources DSC écrites par d'autres développeurs. Par exemple, à partir d'ici https://github.com/PowerShell/DscResources ou de PSGallery
 
Comment installer des ressources supplémentaires . Nous utilisons l'applet de commande Install-Module . L'installation de ressources consiste simplement à copier des fichiers de ressources le long d'un des chemins de la variable d'environnement $ env: PSModulePath . Les ressources installées ne sont pas automatiquement connectées lors de la compilation, donc plus tard nous les connecterons également dans la configuration elle-même.

Pour utiliser une ressource, vous devez l'installer localement et sur le serveur cible. Dans les infrastructures sur site, une politique de sécurité interdit généralement l'accès Internet aux serveurs. Dans ce cas, le serveur DSC ne pourra pas charger de ressources supplémentaires à partir de sources externes. Pour publier des archives avec des modules, nous déployons un référentiel NuGet local ou un serveur Web classique. Vous pouvez installer des ressources supplémentaires pour le serveur Web en décompressant le module dans le répertoire C: \ Program Files \ WindowsPowerShell \ Modules \.
C'est exactement ce que fait l'applet de commande Install-Module.

Dans le deuxième article, nous examinerons de plus près la différence entre le réglage des modes Push et Pull. 

Analyse de configuration simple


La configuration est une description simple et cohérente de ce qui doit être fait sur le serveur. Voici à quoi ressemble une configuration DSC simple: 

Configuration EnvironmentVariable_Path
{
param ()
Import-DscResource -ModuleName 'PSDscResources'
Node localhost
    {
        Environment CreatePathEnvironmentVariable
        {
            Name = 'TestPathEnvironmentVariable'
            Value = 'TestValue'
            Ensure = 'Present'
            Path = $true
            Target = @('Process', 'Machine')
        }
    }
}
EnvironmentVariable_Path -OutputPath:"C:\EnvironmentVariable_Path"

Pour son exemple, voyons en quoi consiste la configuration.

Le bloc de configuration est un type spécial de fonction PowerShell qui décrit ce que nous voulons obtenir. 

À l'intérieur du bloc contient: 

  • bloc param avec paramètres utilisables en interne; 
  • bloquer avec des appels PowerShell supplémentaires. Ici, au début de la configuration, nous exécutons toujours Import-Resource pour connecter des ressources supplémentaires;
  • blocs avec des paramètres pour des serveurs Node $ servername spécifiques

À l'intérieur du bloc Node , nous indiquons quelles ressources sur un serveur particulier nous allons configurer. Dans l'exemple ci-dessus, cela crée une variable d'environnement à l'aide d'une ressource d'environnement standard.

Regardons un peu plus en profondeur et examinons la syntaxe d'une ressource spécifique via la commande Get-DscResource -Name Environment -Syntax:
 

PS C:\windows\system32> Get-DscResource -Name Environment -Syntax
Environment [String] #ResourceName
{
    Name = [string]
    [DependsOn = [string[]]]
    [Ensure = [string]{ Absent | Present }]
    [Path = [bool]]
    [PsDscRunAsCredential = [PSCredential]]
    [Value = [string]]
}

Dans cet exemple: 

  • Nom - le nom de la variable d'environnement.
  • Dans DependsOn, nous spécifions la dépendance à d'autres ressources. Il est important de se rappeler que l'opération ne sera pas effectuée tant que la ressource spécifiée ici n'est pas terminée. 
  • Dans Ensure, nous spécifions les conditions de configuration. Si une telle variable est absente, nous la créerons; s'il est présent, cette ressource ne sera pas configurée.
  • Le chemin d'accès spécifie si la variable d'environnement contient un chemin d'accès. 
  • Dans PsDscRunAsCredential, les informations d'identification spécifiées.
  • Valeur - la valeur de la variable d'environnement. 
  • La cible peut être indiquée pour laquelle la configuration est appliquée.

Comment démarrer la compilation . Nous appelons simplement la configuration par son nom avec les paramètres nécessaires. Le résultat sera un fichier mof, qui est ensuite utilisé par le moteur DSC pour configurer un serveur spécifique:
 
PS C:\windows\system32> EnvironmentVariable_Path -OutputPath:"C:\EnvironmentVariable_Path"
 
    Directory: C:\EnvironmentVariable_Path
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       25.02.2020     14:05           2172 localhost.mof

Configurer le gestionnaire de configuration local


Le gestionnaire de configuration local est responsable de l'application des configurations que nous avons compilées dans les fichiers mof. C'est lui qui contrôle la préservation de l'état défini dans la configuration. Si le système quitte cet état, LCM appelle le code dans les ressources pour restaurer l'état spécifié. 

Voyons les paramètres du gestionnaire de configuration local via Get-DscLocalConfigurationManager:
 
PS C:\windows\system32> Get-DscLocalConfigurationManager
 
ActionAfterReboot              : ContinueConfiguration
AgentId                        : 1FB3A2EE-57C9-11EA-A204-58A023EF3A48
AllowModuleOverWrite           : False
CertificateID                  :
ConfigurationDownloadManagers  : {}
ConfigurationID                :
ConfigurationMode              : ApplyAndMonitor
ConfigurationModeFrequencyMins : 15
Credential                     :
DebugMode                      : {NONE}
DownloadManagerCustomData      :
DownloadManagerName            :
LCMCompatibleVersions          : {1.0, 2.0}
LCMState                       : Idle
LCMStateDetail                 :
LCMVersion                     : 2.0
StatusRetentionTimeInDays      : 10
SignatureValidationPolicy      : NONE
SignatureValidations           : {}
MaximumDownloadSizeMB          : 500
PartialConfigurations          :
RebootNodeIfNeeded             : False
RefreshFrequencyMins           : 30
RefreshMode                    : PUSH
ReportManagers                 : {}
ResourceModuleManagers         : {}
PSComputerName                 :

  • RefreshMode contient le mode de fonctionnement LCM - Push ou Pull. Nous parlerons davantage des modes dans le deuxième article.
  • ConfigurationMode affiche le mode d'application de configuration actuel. Dans notre cas, c'est ApplyAndMonitor - appliquer et suivre les modifications. Les modes ApplyOnly sont également disponibles (LCM ne suivra pas les changements de configuration) et les modes ApplyAndAutocorrect (LCM suivra non seulement les changements, mais les ramènera également à la configuration de base).
  • RebootNodeIfNeeded - peut redémarrer le serveur une fois la configuration terminée, si nécessaire pour appliquer les paramètres. 
  • ConfigurationModeFrequencyMins - Fixe la fréquence à laquelle LCM vérifiera les changements de configuration.

Modifiez les paramètres LCM dans la méta-configuration. Voici son exemple:
 

Configuration LCMConfiguration
{
   Node Localhost
   {
       LocalConfigurationManager
       {
           RebootNodeIfNeeeded = $True
       }
   }
}
LCMConfiguration

Idem pour la dernière version de WMF avec commentaires:


 
[DSCLocalConfigurationManager()]
Configuration LCMConfiguration
{
   param
   (
       [string[]]$Server = "localhost"
   )

 

#  LCM:
#  ,  
# : PUSH
#    30 
   Node $Server
   {
       Settings
       {
           RebootNodeIfNeeded = $True
           RefreshMode        = 'Push'
           RefreshFrequencyMins = 30
       }
   }
}


#   
LCMConfiguration -Server "localhost" -OutputPath "C:\DSC\MetaConfigurations\EnvironmentVariable_Path\"

Caractéristiques métaconfiguration . Lors de l'écriture d'une métaconfiguration, nous utilisons les mêmes blocs que pour une configuration DSC standard. L'exception est le bloc interne LocalConfigurationManager (v4) ou l'attribut DSCLocalConfigurationManager (v5) pour un serveur spécifique. Ils décrivent tous les paramètres nécessaires. 

La métaconfiguration est également compilée dans un fichier mof, mais pour l'utiliser, la cmdlet Set-DSCLocalConfigurationManager est utilisée, et non Start-DSCConfiguration.
 
PS C:\windows\system32> LCMConfiguration -OutputPath C:\EnvironmentVariable_Path\
 
    Directory: C:\EnvironmentVariable_Path
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       26.02.2020     20:05           1016 Localhost.meta.mof

 

PS C:\windows\system32> Set-DscLocalConfigurationManager -Path C:\EnvironmentVariable_Path\
PS C:\windows\system32> Get-DscLocalConfigurationManager
 
RebootNodeIfNeeded             : True

Théoriquement, rien ne nous empêche de combiner la configuration de LCM et les ressources conventionnelles au sein d'une même configuration. Mais pour simplifier, il est recommandé de séparer l'orthographe et l'application de la configuration et de la métaconfiguration.

Configurations partielles 


Configurations partielles - plusieurs configurations qui sont exécutées séquentiellement les unes après les autres. Ils sont utiles lorsque plusieurs équipes travaillent sur le service. Chacune des commandes indique les paramètres de sa partie du service, et la configuration partielle applique ensuite tous les paramètres de manière séquentielle. Dans les paramètres LCM, nous spécifions les configurations partielles dans PartialConfigurations

Dans les configurations partielles, nous devons considérer la logique DSC simple. Le moteur ne permet pas de branchement, des ressources supplémentaires sont donc nécessaires pour remplir diverses conditions. Nous analyserons cela avec quelques exemples. 

Supposons que nous voulons livrer la configuration au serveur de manière garantie et procéder selon l'algorithme suivant:

  1. Tout d'abord, vérifiez que les modules nécessaires sont installés sur le serveur.
  2. Nous effectuons la configuration, ce qui amènera le serveur à l'état souhaité.

Voici à quoi ressemble une métaconfiguration avec plusieurs configurations consécutives à l'intérieur:


#   
[DSCLocalConfigurationManager()]
configuration MetaPushConfig
{
param
   (
       [ValidateNotNullOrEmpty()]
       [string] $NodeName = 'localhost'
   )

 

   Node $NodeName
   {
 	
 #      LCM,    
       PartialConfiguration ModulesDownloadConfig
       {
               Description = 'Download and install modules'
               RefreshMode = 'Push'
       }

 

       #        
       PartialConfiguration ServerOSConfig
       {
               DependsOn = "[PartialConfiguration]ModulesDownloadConfig"
               Description = 'Configuration'
               RefreshMode = 'Push'
       }

 

       #   LCM
       Settings
       {
               RefreshMode        = 'Push'
               RefreshFrequencyMins = 30
               RebootNodeIfNeeded = $true
       }
   }
}

 
 

#  
MetaPushConfig -NodeName "NewServer.contoso.com" -OutputPath c:\DSC\MetaConfigurations

 

#      
$cred = (Get-Credential -UserName Administrator -Message "Enter admin credentials")

 

#  LCM   
Set-DscLocalConfigurationManager -ComputerName "NewServer.contoso.com" -Credential $cred -Path "c:\DSC\MetaConfigurations" -Verbose -Force

 

#  
Publish-DscConfiguration c:\DSC\Configurations\ModulesDownloadConfig -ComputerName "NewServer.contoso.com" -Credential $cred -Force
Publish-DscConfiguration c:\DSC\Configurations\ServerOSConfig -ComputerName "NewServer.contoso.com" -Credential $cred -Force

 

#    
Start-DscConfiguration -UseExisting -ComputerName "NewServer.contoso.com" -Credential $cred -Force -Verbose

La première partie de la configuration indique Télécharger et installer les modules : téléchargez et installez les ressources nécessaires. La deuxième partie de ServerOSConfig amène le serveur à l'état souhaité. Quelles sont les nuances avec la simplicité de DSC ici: 

  1. Si la première partie de la configuration a initialement renvoyé FALSE et s'est terminée complètement, LCM ne passera pas à la deuxième configuration. Selon la logique DSC, vous devez d'abord amener le serveur au premier état décrit. 
    Comment traiter: exécutez la configuration deux fois ou automatisez l'ensemble du processus dans un script.
  2. Si le serveur après l'installation d'un composant nécessite un redémarrage, la configuration n'ira pas plus loin jusqu'à ce que nous redémarrions nous-mêmes le serveur. Même si nous disons à LCM que RebootNodeIfNeeeded = $ True, l'agent attendra notre solution pendant la configuration.
    Comment traiter: la ressource xPendingReboot vient à la rescousse , qui contrôle la clé de registre au redémarrage. Cette ressource redémarre le serveur pour nous.

Voici un exemple de configuration pour télécharger et installer des ressources dans le scénario «Entreprise sanglante», lorsque le serveur n'a pas accès à Internet. Il suppose la présence d'un serveur Web, où les ressources pré-téléchargées sont disponibles pour tout le monde via le protocole http.


Configuration ModulesDownloadConfig
{
   param
   (
       [string[]]$Server
   )

 

   #   
   Import-DscResource -ModuleName "PSDesiredStateConfiguration"

 

   #  
   Node $Server
   {
       #  IE Security
       Registry DisableIEESC-Admin {
           Key = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
           ValueName = "IsInstalled"
           Ensure = "Present"
           ValueData = 0
           ValueType = "DWORD"
       }

 

       Registry DisableIEESC-User {
           Key = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
           ValueName = "IsInstalled"
           Ensure = "Present"
           ValueData = "0"
           ValueType = "DWORD"
       }

 

	
 #    ,    
       File CreateDistribDir {
           Ensure          = "present"
           DestinationPath = "C:\Install\PSModules"
           Type            = "Directory"
       }

 

	
 #   NetworkingDsc (<a href="https://www.powershellgallery.com/packages/NetworkingDsc/8.0.0-preview0004">https://www.powershellgallery.com/packages/NetworkingDsc/8.0.0-preview0004</a>),      
       Script NetworkingDscDownLoad {
           SetScript = { Invoke-WebRequest -Uri "http://repo.contoso.com/repo/modules/NetworkingDsc.zip" -OutFile "C:\Install\PSModules\NetworkingDsc.zip" }
           GetScript = { return @{ Result = Test-Path "C:\Install\PSModules\NetworkingDsc.zip"
               GetScript = $GetScript; SetScript = $SetScript; TestScript = $TestScript
               }
           }
           TestScript = { Test-Path "C:\Program Files\WindowsPowerShell\Modules\NetworkingDsc" }
       }

 

 #   NetworkingDsc  C:\Program Files\WindowsPowerShell\Modules
       Archive UnpackNetworkingDsc {
           Ensure = "Present"
           DependsOn = "[Script]NetworkingDscDownLoad"
           Path = "C:\Install\PSModules\NetworkingDsc.zip"
           Destination = "C:\Program Files\WindowsPowerShell\Modules\"
       }

 

 #   ComputerManagementDsc (<a href="https://www.powershellgallery.com/packages/ComputerManagementDsc/8.2.1-preview0001">https://www.powershellgallery.com/packages/ComputerManagementDsc/8.2.1-preview0001</a>),      
       Script ComputerManagementDscDownLoad {
           SetScript = { Invoke-WebRequest -Uri "http://repo.contoso.com/repo/modules/ComputerManagementDsc.zip" -OutFile "C:\Install\PSModules\ComputerManagementDsc.zip" }
           GetScript = { return @{ Result = Test-Path "C:\Install\PSModules\ComputerManagementDsc.zip"
               GetScript = $GetScript; SetScript = $SetScript; TestScript = $TestScript
               }
           }
           TestScript = { Test-Path "C:\Program Files\WindowsPowerShell\Modules\ComputerManagementDsc" }
       }

 

	
 #   ComputerManagementDsc  C:\Program Files\WindowsPowerShell\Modules
       Archive UnpackComputerManagementDsc {
           Ensure = "Present"
           DependsOn = "[Script]ComputerManagementDscDownLoad"
           Path = "C:\Install\PSModules\ComputerManagementDsc.zip"
           Destination = "C:\Program Files\WindowsPowerShell\Modules\"
       }

 

	
 #   xPendingReboot (<a href="https://www.powershellgallery.com/packages/xPendingReboot/0.4.0.0">https://www.powershellgallery.com/packages/xPendingReboot/0.4.0.0</a>),      
       Script xPendingRebootDownLoad {
           SetScript = { Invoke-WebRequest -Uri "http://repo.contoso.com/repo/modules/xPendingReboot.zip" -OutFile "C:\Install\PSModules\xPendingReboot.zip" }
           GetScript = { return @{ Result = Test-Path "C:\Install\PSModules\xPendingReboot.zip"
               GetScript = $GetScript; SetScript = $SetScript; TestScript = $TestScript
               }
           }
           TestScript = { Test-Path "C:\Program Files\WindowsPowerShell\Modules\xPendingReboot" }
       }

 

	
 #   xPendingReboot  C:\Program Files\WindowsPowerShell\Modules
       Archive UnpackxPendingReboot {
           Ensure = "Present"
           DependsOn = "[Script]xPendingRebootDownLoad"
           Path = "C:\Install\PSModules\xPendingReboot.zip"
           Destination = "C:\Program Files\WindowsPowerShell\Modules\"
       }
   }
}

À propos de la sécurité


Le gros inconvénient de DSC sur le terrain est le manque de comptes d'identification. Ce mécanisme stocke en toute sécurité les comptes sous forme de nom d'utilisateur + "hachage du mot de passe" et les paie au service, qui est responsable de l'authentification. Sans cela, DSC ne peut pas gérer les comptes pour le compte d'un autre service. Et si nous devons nous authentifier sous un compte avec des privilèges spéciaux, le processus d'automatisation est très compliqué. Ce sera par exemple le cas lors de l'entrée du serveur dans le domaine.

Tout à notre disposition:

  • les informations d'identification sont stockées en texte brut,
  • les informations d'identification cryptées ne fonctionnent que sur le PC où elles ont été générées.

En pratique, il existe plusieurs solutions. 


Les "stubs" sont bons lorsque la prévisibilité du comportement du serveur doit être assurée.
Nous faisons un «stub» après la configuration du serveur dans plusieurs cas, si nous avons utilisé:

  • redémarrage (ressource xPendingReboot) 
  • transfert d'informations d'identification 
  • d'autres ressources susceptibles d'affecter les performances du serveur concernant les redémarrages imprévus ou la sécurité.

Pour ce faire, créez et republiez des configurations SANS blocs contenant la ressource xPendingReboot et des configurations avec des informations d'identification.

Cette approche s'applique uniquement au scénario Push, car Pull est assez simple et n'implique pas de changement de configuration à la volée. Dans le prochain article debuldakovNous examinerons de plus près les paramètres et les fonctionnalités du travail dans les modes Push et Pull.

Et venez également discuter des nuances de la technologie DSC et des limites de son application le 28 mai à 18h00 lors de la première réunion en ligne de la communauté Raiffeisenbank DGTL Communications. Lors de la réunion, nous parlerons également de la façon de se faire des amis ELK et Exchange et de ce que Microsoft Endpoint Manager peut faire dans la gestion des appareils. Voici l'inscription pour le mitap .

All Articles