Desired State Configuration (DSC)

Introducción

Desde hace algún tiempo, oímos hablar mucho de los sistemas de gestión de la configuración. Permiten configurar un conjunto de máquinas de forma idempotente y en un tiempo récord. La idempotencia es la característica de una operación que reproduce siempre el mismo resultado, sea cual sea el entorno. En este caso, significa tener siempre la misma configuración, sea cual sea el número de máquinas. Para ello, Microsoft creó la Desired State Configuration (DSC). Existen otras soluciones similares; la más conocida hoy en día es sin duda Ansible, pero también están Chef y Puppet.

El DSC evita la desviación de la configuración. Si esto ocurre, es capaz de remediar la situación. La otra ventaja con respecto a la gestión de la configuración es el ahorro de tiempo en la resolución de incidentes. ¿Por qué dedicar un día entero a un servidor averiado cuando este puede volver a desplegarse y estar operativo en 15 minutos? Esta es una ventaja real en una estrategia de nube. Y Microsoft lo ha entendido perfectamente, porque DSC puede utilizarse desde la plataforma en la nube Azure.

Históricamente, utilizábamos objetos de directiva de grupo (GPO) para establecer configuraciones, pero nos quedábamos atascados cuando se trataba de configurar máquinas fuera del dominio de Active...

Versiones y plataformas compatibles con DSC

Históricamente, DSC apareció con la versión 4.0 de PowerShell, bajo Windows 8.1. En aquel momento, la versión del motor de DSC era la 1.0. Además, la versión de DSC estaba vinculada a la versión de PowerShell y seguía el mismo ritmo de desarrollo. Como resultado, la versión 1.1 del motor DSC puede encontrarse en Window PowerShell V5.1, y la versión 2.0 del motor en PowerShell 7.1. Recientemente, los equipos de DSC y PowerShell decidieron separar la actualización de la versión del motor DSC de la de PowerShell, a partir de PowerShell 7.2.

¿Por qué son tan diferentes las versiones 1.1 y 2.0? Para averiguarlo, puede consultarse la documentación: https://learn.microsoft.com/en-us/powershell/dsc/overview?view=dsc-2.0#changes-from-dsc-11

Resumiendo:

  • Se ha eliminado un gran número de cmdlets.

  • No es posible utilizar un Pull Server (del que hablaremos más adelante).

  • No existe un agente local llamado Local Configuration Manager (LCM).

Para entender la diferencia entre las versiones 1.1 y 2.0, es necesario entender el propósito de la versión 2.0. Originalmente se creó para satisfacer un requisito de Azure: Azure Machine Configuration (anteriormente Guest Configuration). La finalidad de este servicio es permitir la creación de paquetes independientes que proporcionen. De este modo, un paquete de configuración...

Descripción general de la solución

Para comprender mejor la solución DSC, vamos a echar un vistazo rápido a cada una de las partes que desempeñan un papel esencial en su funcionamiento general. DSC es único en el sentido de que ha sido diseñado específicamente en torno a PowerShell. Así, desde la escritura de configuraciones hasta su despliegue, todo se realiza mediante comandos PowerShell. Microsoft no ofrece una interfaz gráfica para administrar la solución. Sin embargo, puede confiar en PowerShell ISE y Visual Studio Code para diseñar sus configuraciones.

La mayoría de los elementos presentados en este capítulo se limitan a la versión 1.1 del motor DSC.

1. Terminología

Término

Definición

DSC Resource

Componente llamado por el DSC para configurar un elemento del sistema. El elemento puede ser una clave del registro, un archivo, un parámetro DNS, etc.

Los recursos están contenidos en módulos PowerShell.

DSC Configuration

Script PowerShell que define un tipo particular de función que contiene una descripción de la configuración. Los archivos MOF se generan cuando se llama.

Node

Sistema cliente DSC (nodo).

PULL Server

En modo PULL, es el servidor que centraliza todas las configuraciones recuperadas por los puestos cliente.

Local Configuration Manager (Administrador de configuración local o LCM)

Motor de ejecución del cliente DSC. Se encarga de interpretar la configuración DSC recibida (PUSH) o recuperada (PULL) y aplicarla al host local.

Metaconfiguración

Nombre de la configuración LCM.

MOF

Formato del archivo de texto generado cuando se llama a una configuración. Este tipo de archivo cumple la gramática IDL definida por el DMTF.

2. Consideraciones generales

Por defecto, las configuraciones se aplican utilizando la cuenta LocalSystem. Esto crea severas restricciones si es necesario ejecutar comandos que requieren derechos especiales, o si la configuración necesita acceder a recursos compartidos de red. Descubriremos que es posible introducir credenciales para este tipo de requisitos.

El objetivo principal de DSC es establecer una configuración de tipo "ordenador", por lo que debe evitarse la configuración del entorno de usuario. En su lugar deben utilizarse GPOs.

3. Dos modos: PUSH y PULL

DSC tiene dos modos...

Recursos DSC

Los recursos DSC contienen las instrucciones de configuración de un componente concreto. El LCM utiliza recursos DSC para configurar el host en el que se encuentra, basándose en un archivo MOF.

Es esencial que los recursos requeridos por un LCM estén disponibles localmente en el caso de una configuración en modo PUSH, o en un servidor PULL remoto en el caso del modo PULL.

En las secciones siguientes, veremos cómo encontrar el recurso adecuado y adaptar su sintaxis a nuestras necesidades.

1. Lista de los recursos disponibles

Para listar los recursos disponibles en un sistema, utilice el comando Get-DscResource.

A continuación, se muestra un ejemplo en un sistema Windows Server 2016 con PowerShell versión 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...  ...

Crear una configuración inicial

Una configuración DSC se crea utilizando la palabra clave configuration. Una configuración es muy similar a una función o flujo de trabajo. Todas ellas aceptan un nombre y una definición de parámetros. También se pueden utilizar llamando a su nombre directamente en la consola, como un simple comando PowerShell.

1. Creación rápida con ISE

Al principio del capítulo, se explicó la sintaxis de una configuración de forma genérica. En la siguiente sección, reuniremos todo lo que tenemos, configuración y recursos, para formar una configuración DSC inicial. A continuación, llevaremos esta configuración un paso más allá añadiendo nuevos elementos.

Para empezar con buen pie a la hora de escribir una configuración, utilizamos PowerShell ISE y sus snippets. Históricamente, se podía hacer lo mismo con VSCode, pero las referencias a DSC en los snippets ofrecidos por PowerShell ya no están presentes. Aquí vemos de nuevo el deseo de dividir DSC y PowerShell.

 Abra PowerShell ISE. En un nuevo archivo, haga clic con el botón derecho y seleccione Start Snippets (Iniciar fragmentos en español). En la lista desplegable que aparece, haga clic en DSC configuration (simple):

images/09EXPIT03.png

Uso del snippet DSC Configuration en PowerShell ISE

El resultado:

configuration Name  
{  
    # Posibilidad de evaluar expresiones para obtener  
la lista de nodos  
    # Ejemplo: $AllNodes.Where("Role -eq Web").NodeName  
    node ("Nodo1", "Nodo2", "Nodo3")  
    {  
        # Llamar al proveedor de recursos  
        # Ejemplo: WindowsFeature, File  
        WindowsFeature FriendlyName  
       {  
           Ensure = "Presente"  
           Name = " Feature Name"  
        }  
 
       File FriendlyName...

Configuración del LCM

El LCM es el motor responsable de aplicar las configuraciones DSC a su sistema anfitrión (nodo).

La configuración se describe en un archivo MOF generado cuando se ejecuta una configuración de script.

1. Configuración actual

El LCM puede configurarse mediante un conjunto de metaconfiguraciones. Para conocer la configuración actual del LCM, utilice el comando 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                  :  ...

Archivos MOF

MOF (Managed Object Format) es un formato de archivo definido por el DMTF. MOF se basa en el formato IDL (Interface Definition Language) para estructurar el archivo.

La sintaxis MOF está escrita de tal forma que puede ser entendida tanto por el hombre como por la máquina. Se utiliza para definir clases e instancias orientadas a objetos.

1. Archivo de configuración MOF

Ejemplo del archivo MOF para la configuración ConfigBackup del nodo 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 = "Presente";  
 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";  ...

Seguridad y contexto de ejecución (credentials)

El LCM se ejecuta con la cuenta LocalSystem. Esta es una limitación importante cuando una configuración requiere acceder a un recurso de red, como un recurso compartido SMB. En efecto, se deniega el acceso al nodo.

Hay varias soluciones posibles a este problema:

  • Modificar los derechos de uso compartido para autorizar el acceso a la cuenta Ordenador.

  • Pasar las credenciales a la configuración.

La primera solución tiene un alcance muy limitado. Si desea instalar un controlador de dominio, se requieren credentials de dominio y la solución no se aplica aquí.

Puede optar entonces por la segunda solución. Sin embargo, dado que la aplicación de una configuración implica la generación de un archivo MOF, este último contiene la información de identificación, es decir, el nombre de cuenta y la contraseña. Existen dos opciones. La primera consiste en escribir la contraseña en texto plano en el archivo, con todos los problemas de seguridad que ello conlleva. La segunda opción es configurar certificados para encriptar las contraseñas dentro del archivo MOF. Sin embargo, configurar esto es mucho más restrictivo.

También puede optar por una sesión remota de PowerShell para llamar a la configuración localmente y generar el archivo MOF en el nodo. Esto reduce los riesgos, pero las contraseñas...

Protección de credentials en una configuración

Para algunos recursos, es necesario utilizar credentials en las configuraciones. Este puede ser el caso si el nodo necesita acceder a un recurso compartido de red, o si necesita ser promovido a controlador de dominio.

Cuando se utilizan credentials, el nombre de usuario y la contraseña se almacenan en el archivo MOF generado. Esta contraseña puede adoptar una de estas dos formas:

  • en un lenguaje claro y legible

  • cifrado mediante certificado

Obviamente, el primer caso está reservado a los entornos de prueba. El cifrado debe instalarse en todos los demás entornos, ya que es dudoso que un gestor aprecie que la contraseña del administrador del dominio se almacene en texto claro en un entorno de producción. Más aún si se utiliza un servidor PULL, que centraliza todas las configuraciones en un único punto.

1. Prerrequisitos

Configurar el cifrado de contraseñas dentro de los archivos MOF requiere una serie de requisitos previos:

  • Los certificados deben permitir el cifrado de los documentos. Pueden proceder de una infraestructura de gestión de claves (PKI), como Active Directory Certificate Service (AD CS), o pueden ser unos cuantos certificados generados manualmente o por terceros. Lo ideal es un certificado de cifrado por nodo.

Desde la versión 5 de PowerShell, es posible utilizar el comando New-SelfSignedCertificate para generar certificados autofirmados.

Configuración de un PULL Server

El modo PULL tiene grandes ventajas sobre el modo PUSH. En un entorno a gran escala, las configuraciones de servidor en modo PUSH alcanzan rápidamente sus límites.

El objetivo del modo PULL es centralizar las configuraciones de cada nodo y garantizar que ellos mismos descarguen las nuevas configuraciones y, sobre todo, que descarguen automáticamente los recursos DSC necesarios para aplicar las configuraciones.

El PULL Server Web también permite configurar informes para supervisar el estado de cumplimiento de cada nodo.

1. Evolución del PULL Server

Desde la llegada de PowerShell Core, Microsoft ha aparcado un poco las evoluciones funcionales de la funcionalidad PULL Server Web de Windows Server. Ahora recomienda las soluciones Azure Automation Desired State Configuration Service y Azure Automanage Machine Configuration. Como su nombre indica, solo están disponibles en la plataforma en la Cloud Azure del editor. Si por alguna razón no es posible utilizar Azure para crear un PULL Server Web, o con funcionalidad Windows Server, aún queda la opción de utilizar proyectos de la comunidad. Hay dos de ellos:

Por desgracia, parece que estos proyectos llevan varios años aparcados. Lo que queda es la posibilidad de utilizar la compartición SMB, con las limitaciones que conlleva.

En las secciones siguientes, hemos optado por centrarnos en el uso de Windows Server.

2. PULL Server bajo recurso compartido SMB

Desde la versión 5.1 de PowerShell, ha sido posible construir un PULL Server desde un simple recurso compartido SMB. La implementación no se cubre aquí. Se recomienda para estructuras pequeñas con muy pocos requisitos.

Con un PULL Server SMB no es posible establecer un sistema de informes de configuración. Tampoco son posibles las configuraciones basadas en nombres.

3. PULL Server Web

Entre la versión 4.0 y la versión 5.0, la configuración de un PULL Server Web algo ha cambiado. Sin embargo, una cosa sigue siendo la misma: el uso del recurso xDscWebService contenido en el módulo xPSDesiredStateConfiguration para facilitar su instalación. Para descargar el módulo xPSDesiredStateConfiguration, consulte la sección Instalación desde la PowerShell Gallery...

Prueba de conformidad de un nodo

La conformidad es un principio fundamental de DSC. DSC permite comprobar que las configuraciones se han aplicado correctamente a un nodo determinado. De hecho, el uso de DSC por sí solo no basta para afirmar que el sistema es conforme. Entran en juego varios factores. Por un lado, si la configuración de LCM no está en modo de autocorrección, cualquier persona o cosa puede modificar directamente la configuración. Por otro lado, si el modo de autocorrección está activo, es muy posible que el sistema se encuentre con un bloqueo técnico de conformidad.

En todos estos casos, el comando Test-DscConfiguration puede utilizarse para comprobar la configuración de un sistema local o remoto. El valor devuelto por el comando es de tipo booleano.

Ejemplos

PS > Test-DscConfiguration  
True  
PS > Test-DscConfiguration -ComputerName SRV2K22  
True  
PS > $CimSession = New-CimSession -ComputerName SRV2K22  
PS > Test-DscConfiguration -CimSession $CimSession  
True 

Aplicación de la última configuración correcta conocida

Puede ocurrir que una nueva configuración cause un problema al aplicarla. Si esto ocurre, puede volver rápidamente a la configuración anterior. Para ello, utilice el comando Restore-DSCConfiguration. No se requieren parámetros especiales, a menos que desee utilizar una sesión CIM para actuar sobre un sistema remoto.

PS > Restore-DscConfiguration 

El comando recupera directamente la configuración almacenada en C:Windows\System32\Configuration\backup.mof.

Principio avanzado

En los primeros días de DSC bajo PowerShell versión 4.0, no era posible aplicar varias configuraciones al mismo host. Esto dificultaba considerablemente la actualización de una  parte de la configuración, ya que los archivos de configuración se hacían enormes. La solución propuesta fue la creación de los llamados recursos compuestos. Estos contienen en realidad un subconjunto de los recursos DSC preconfigurados en una configuración. De este modo, podían invocarse directamente en una configuración.

Desde la versión 5.1 de PowerShell, se ha eliminado la restricción de una única configuración. Ahora es posible crear un conjunto de configuraciones con diferentes nombres para un único host. Estas configuraciones se denominan configuraciones parciales (o partial configuration en inglés).

Estas dos soluciones se analizarán en esta sección. En la versión anterior de este libro se recomendaba dar prioridad a las configuraciones parciales. Resulta que se debe dar prioridad a los recursos compuestos. ¿Por qué? Para limitar los conflictos entre configuraciones. Es más coherente aplicar una única configuración, validada por un único equipo, que un conjunto de configuraciones dispares repartidas entre varios equipos que no se comunican necesariamente. Habrá mucho menos riesgo de deriva y el control de la configuración de los nodos será más eficaz.

1. Recurso compuesto

Los recursos compuestos son, de hecho, configuraciones "disfrazadas". Agrupan un conjunto de parámetros genéricos que se aplican a todos los nodos. De hecho, no es raro tener toda una serie de configuraciones que establecer en todos los servidores. Esto puede abarcar la configuración del antivirus, parámetros de red (servidor DNS, puerta de enlace, etc.), variables de entorno, claves de registro, etc. Un muy buen ejemplo de recurso compuesto es el módulo CommonTasks de la comunidad DSC: https://github.com/dsccommunity/CommonTasks

Reúne un conjunto de recursos compuestos que facilitan la escritura de configuraciones para necesidades cotidianas, como la configuración de un conjunto de claves de registro, la creación de tareas programadas, etc.

Todas estas configuraciones pueden incluirse en un recurso compuesto...

Escritura de un recurso personalizado

Aunque los recursos creados por la comunidad y disponibles en la PowerShell Gallery son actualmente bastante variados, no cubren todas las necesidades. Teniendo esto en cuenta, Microsoft ha hecho posible la creación de recursos DSC personalizados.

El recurso Script puede utilizarse para proporcionar un método de procesamiento personalizado en un nodo (véase la sección Recursos DSC - Recursos incorporados). Sin embargo, carece de flexibilidad.

Por este motivo, se puede optar por uno de los dos métodos que se describen a continuación. El primero está disponible desde la versión 4.0 de Windows PowerShell. Utiliza una estructura de módulo específica y un archivo de esquema MOF que describe un recurso. El segundo método se introdujo con la versión 5 de Windows PowerShell y se basa en las clases de PowerShell (véase el capítulo Clases). Con la llegada de las nuevas versiones del motor DSC, se recomienda desarrollar los recursos basándose en clases. La Comunidad DSC está migrando gradualmente todos sus recursos a esta forma de escribir. El motivo es que se ha abandonado la escritura MOF en favor de las clases.

1. Recurso personalizado con un archivo MOF

a. Creación de un recurso basado en un esquema MOF

Un recurso DSC basado en un archivo de esquema MOF debe contener una serie de archivos específicos:

  • un archivo MOF con extensión .schema.mof que describe el recurso,

  • un archivo de módulo de script en formato PSM1 que contiene el mecanismo de recursos,

  • un manifiesto de módulo (opcional) con la extensión .psd1.

También debe integrarse en un módulo PowerShell con una estructura de árbol específica:

$env:ModulePath  
  └─<ModuleName>  
    └─DSCResources  
      ├─<ResourceName1>  
        ├─<ResourceName1>.schema.mof  
        ├─<ResourceName1>.psm1  
        └─[<ResourceName1>.psd1]  
      ├─<ResourceName2>  
        ├─<ResourceName2>.schema.mof  ...

DSC en Linux

Aquí es donde DSC realmente destaca. Poder configurar máquinas Linux de forma centralizada desde una máquina Windows es un verdadero paso adelante. Esta sección describe cómo establecer una configuración DSC para un sistema Linux.

El sistema Linux utilizado aquí es Debian. El sistema que genera la configuración y la aplica es Windows 10.

1. Prerrequisitos

Antes de iniciar la configuración, es necesario poner en marcha una serie de elementos en la máquina Linux. Para comunicarse entre máquinas Windows, DSC utiliza el estándar CIM. El equivalente de este estándar en Linux es OMI (Open Management Infrastructure). OMI no está presente por defecto, por lo que es necesario instalarlo antes de instalar el paquete DSC. También debe instalarse PowerShell Core (véase el capítulo sobre PowerShell y la gestión de versiones - Instalación de PowerShell Core).

a. Instalación del paquete OMI

Para instalar el paquete OMI, primero es necesario configurar el repositorio de Microsoft para la distribución de Linux. Esto es lo mismo que para PowerShell Core. El procedimiento se describe en el capítulo sobre PowerShell y la gestión de versiones - Instalación de PowerShell Core.

Una vez rellenado el repositorio, puede apuntar directamente al paquete OMI:

:~# sudo apt-get -y install omi 

A continuación, comprobamos qué versión de OpenSSL está instalada:

:~# openssl version   
OpenSSL 1.1.1l  24 Aug 2021 

b. Instalación del paquete DSC

Ahora que el paquete OMI está en su lugar, podemos instalar el paquete DSC. En primer lugar, elegimos la versión adecuada en función de la versión de OpenSSL que vimos antes. Las distintas versiones están disponibles en https://github.com/Microsoft/PowerShell-DSC-for-Linux/releases

En este caso, elegimos la versión 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 

Luego lo instalamos:

:~# dpkg -i ./dsc-1.2.4-0.ssl_110.x64.deb 

Por último, comprobamos el estado del servicio omid para asegurarnos de que se está ejecutando:

:~# service omid status 

2. Recursos DSC para Linux

Al igual que Windows...

Mantenimiento y solución de problemas

1. Forzar la reaplicación de una configuración

Esperar 15 minutos o más para que se vuelva a aplicar una configuración puede ser mucho tiempo, sobre todo si necesita el resultado para corregir un error o volver a poner el servidor en línea urgentemente. No hay ningún comando PowerShell disponible para realizar esta acción. Sin embargo, existe una forma, utilizando el método de una clase WMI.

El siguiente comando está disponible:

Invoke-CimMethod -ClassName MSFT_DSCLocalConfigurationManager `  
    -Namespace root/Microsoft/Windows/DesiredStateConfiguration `  
    -MethodName PerformRequiredConfigurationChecks `  
    -Arguments @{Flags = [System.UInt32]1} 

La ventaja de este comando es que acepta los parámetros -ComputerName y -CimSession. Esto permite ejecutar el comando a un host remoto.

2. Estado de una configuración DSC

Para diagnosticar un problema de configuración, puede utilizar el comando Get-DscConfigurationStatus. Esto devuelve el estado de todas las configuraciones actuales.

Ejemplo

PS C:\Scripts> Get-DscConfigurationStatus  
  
Status     StartDate                 Type            Mode  Reboot  ...