15/11/2024

Créer une configuration DSC avec des paramètres

I. Powershell DSC et les paramètres

Lorsque l’on écrit une configuration DSC, plutôt que de devoir toucher au code pour éditer des variables quand on veut l’utiliser, notamment pour indiquer une liste de nœuds cible, on peut s’appuyer sur le passage de paramètres pour simplifier l’utilisation de ses configurations. De la même manière que l’on peut le faire dans un script PowerShell standard, PowerShell DSC permet cela.

La technique dit du "AllNodes" est également très intéressante, et c'est pourquoi je vais vous la présenter.

II. Un paramètre : quel est l’objectif ?

Pour que ce soit concret, nous allons prendre un exemple et le mettre en pratique au sein d’une configuration DSC.

Ainsi, si par exemple on intègre une variable $Node à notre configuration et qu’elle contient le nom du nœud ciblé, et que cette variable est égale à « MonServeur », on écrira :

$Node = "MonServeur"

C’est bien de faire comme cela, mais si on veut utiliser le fichier de configuration sans devoir éditer son code, il va falloir passer par la création d’un paramètre. Ainsi, on peut créer un paramètre nommé « Node » et le rendre obligatoire, ce qui amènera à appeler la configuration de cette manière :

MaConfiguration -Node "MonServeur"

C’est mieux comme ça, non ? Alors maintenant on va voir comment ça s’écrit dans le code...

III. Comment déclarer un paramètre dans sa configuration DSC ?

La déclaration d’un paramètre avec PowerShell DSC est identique à celle d’un script PowerShell « standard », ce qui devrait vous rassurer si vous connaissez déjà cette notion.

Sinon, voyons ensemble comment procéder. Tout d’abord, il faut d’abord que notre paramètre soit contenu dans un bloc « param » que l’on définit comme ceci :

param()

Dans le cadre de DSC, bien entendu on positionne ce bout de code dans le bloc principal « Configuration ».

Ensuite, on va indiquer le type de données du paramètre (nombre, chaîne de caractères, etc) suivi de son nom sous la forme suivante : [type]$Nom

Ce qui donnera le code suivant, si l’on reprend notre paramètre « Node » qui est une chaîne de caractères :

param([string]$Node)

Enfin, sachez qu’il est possible d’ajouter une section [Parameter()] pour donner des propriétés particulières à ce paramètre. Par exemple, on peut le rendre obligatoire, ce qui nous intéresse fortement puisque si le nom du nœud n’est pas indiqué, le script ne pourra pas dérouler correctement.

L’option qui permet de rendre un paramètre obligatoire se nomme « mandatory », ce qui donnera :

param([parameter(mandatory=$true)][string]$Node)

Si l’on veut ajouter un second paramètre, le principe restera le même, on met tout dans le bloc « param() » et on indique une virgule à la fin de la ligne du premier argument, par exemple :

param([parameter(mandatory=$true)][string]$Node,
    [parameter(mandatory=$true)][string]$GUID
)

Pour utiliser un paramètre dans la configuration, il suffira de le nommer comme une variable.

Voici un exemple concret avec un paramètre qui contient une hash table avec des noms de serveurs cibles et qui vous montre comment placer le bloc de paramètre(s) :

Configuration ParamExemple{
    # Définir plusieurs noeuds (serveurs cibles)
    param(
       [string[]]$Nodes =@("WEB01"," WEB02","SQL01")
    )
    # Importer les ressources DSC
    Import-DscResource –ModuleName PSDesiredStateConfiguration
    # Noeud localhost
    Node $Nodes {
    # Configuration par les ressources à coder ici
    }
}

On peut imaginer créer des scripts de configuration générique et créer des paramètres pour les données amenées à changer, ce qui facilite l’utilisation des configurations. Dans cet exemple, la flexibilité se limite au nom du noeud.

Concrètement, vous verrez que l’on utilisera cette méthode dans un autre chapitre de ce cours, lorsque l’on mettra en place un serveur pull, pour générer à la volée les fichiers MOF d’une configuration du LCM de chaque nœud. Ainsi, on passera en paramètre le nom du nœud ainsi que son GUID obtenu directement depuis l’Active Directory. J’en ai déjà trop dit… Nous verrons ceci plus tard, pour le moment restez concentrés pour la suite. Mais avant d’en terminer avec le passage des paramètres, je vais évoquer la technique du « AllNodes ».

IV. AllNodes : séparer les données de la configuration, de la structure de la configuration

Lorsque l’on utilise la technique « AllNodes » pour créer une configuration DSC, on va séparer la configuration en deux :

Les données de la configuration : dans un bloc spécifique on regroupera les différentes valeurs que l’on souhaite donner aux paramètres des ressources que l’on va utiliser dans la configuration en elle-même. Ainsi dans ce bloc, on peut définir différents sous-blocs correspondant chacun à un nœud, et pour chaque nœud on va indiquer la valeur que l’on souhaite lui donner pour un paramètre spécifique.

Par exemple, on pourra dire que pour le nœud « WEB01 » le paramètre « Role » aura pour valeur « WebServer » et, pour le nœud « SQL01 » le paramètre « Role » aura pour valeur « SQLServer ». Le tout sans changer la configuration en elle-même.

L’objectif c’est aussi de pouvoir déclarer dans cette partie toutes les valeurs que l’on va utiliser dans les ressources, toutes ressources confondues, et de pouvoir les modifier facilement sans toucher à la structure de la configuration.

La structure de la configuration : dans un bloc spécifique on ajoutera toutes les déclarations des ressources que l’on souhaite utiliser, avec les différents paramètres, qui auront pour valeur des variables. Il est essentiel de s’appuyer sur des variables pour adapter la configuration selon le nœud.

Finalement, nous avons nos données d’un côté et les instructions de configuration de l’autre, ce qui fait qu’on pourra changer les valeurs au sein de la partie données, sans affecter la logique de la configuration en elle-même. A ce sujet, les données peuvent être stockées dans un fichier totalement à part, pour vraiment utiliser le fichier de configuration comme un template.

Sans rentrer dans les détails et ne pas m’attarder sur cette autre technique (je ne voudrais pas vous embrouiller), voici un exemple :

# Données de configuration
$ConfigData =
@{
    AllNodes = 
    @(
        @{
            NodeName = "*"
            Ensure  = "Present"
        },
        @{
            NodeName = "WEB01"
            Role     = "WebServer"
        },
        @{
            NodeName = "WEB02"
            Role     = "WebServer"
        },
        @{
            NodeName = "SQL01"
            Role     = "SQLServer"
        }
    );
}
# Structure de la configuration
configuration RoleInstallation
{
    Import-DscResource -ModuleName PSDesiredStateConfiguration -Name WindowsFeature
    node $AllNodes.NodeName
    {
        WindowsFeature Role
        {
            Name = $Node.Role
            Ensure = $Node.Ensure
        }
    }
}
RoleInstallation -ConfigurationData $ConfigData

La partie sous « Données de la configuration » contient différents sous-blocs, avec un bloc par nœud, et pour chaque nœud on définit des valeurs.

Dans cet exemple, je définis un rôle à installer sur chaque serveur sans pour autant que ce soit le même pour chaque serveur, c’est là tout l’intérêt. De manière générale, le premier sous-bloc avec la valeur « * » pour le nom du nœud (NodeName) permet d’indiquer des valeurs communes à tous les nœuds, traduisez « * » par « all » ou « tous ».

Toujours dans cet exemple, ceci permet de positionner le paramètre « Ensure » sur « Present » pour qu’on s’assurer que la fonctionnalité est installée sur chaque serveur.

Là où ça change par rapport à la génération des fichiers compilés (*.mof) avec la méthode traditionnelle, c’est qu’il faut préciser les données de configuration, d’où la nécessité de préciser le paramètre « ConfigurationData » suivi de la variable « ConfigData » qui contient nos données.

Nous avons vu deux façons d’injecter des données dans une configuration DSC, je vous conseille de vous exercer avec la première méthode avec les paramètres simples, avant de tenter l’écriture d’une configuration avec la technique « AllNodes ». Rendez-vous au prochain chapitre.

author avatar
Florian BURNEL Co-founder of IT-Connect
Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail