Configuring Virtual Machines Using Desired State Configuration - Part 4 - Applying Configurations

Welcome to the fourth article of the Desired Configuration series! Today we're going to discuss more on the ways you can apply configurations to virtual machines and how to examine the LCM verbose output.

Without further ado, let me present the two ways you can apply configurations: Push and Pull.

Push
The push method is the simplest, we just send the configuration to the node and from then on the node has to act accordingly. We just sit and watch.

Let's go through the process of pushing a configuration to a node. I'm going to be using my domain controller machine as the management host to avoid touching the node at all.

First we have to put together the configuration itself. Here we are going to use a configuration from one of the previous posts that installs the Web-Server role and copies a web page file.

We'll confirm that the Web-Server role is not installed on the node using the Get-WindowsFeature cmdlet:
Great, IIS is not installed. Now, the default LCM configuration is set to push, thus we don't need to configure the LCM.

In case you need to verify, you can use the Get-DscLocalConfigurationManager cmdlet to verify the LCM configuration, but since it does not have a -ComputerName parameter you'll have to include use it in a scriptblock for the Invoke-Command cmdlet just like below:
Alright, we're good to go! 

To push the configuration to  node we are going to use the Start-DscConfiguration cmdlet. The parameters we are going to use are:
  • -Path: The path to the directory that contains the compiled configuration
  • -ComputerName: The name of the computer to configure
  • -Wait: Wait for the command to complete
  • -Verbose: Show all the steps followed by the LCM
Before moving on, a small but very important detail about computer and configuration names! When a configuration file is compiled, the file that is created is named after the node name in the file. So, for example, if the node name in a configuration is "localhost" the compiled configuration file will be created in a folder with the same name as the configuration and named after the nodes, e.g. "localhost.mof".
If you try to remotely apply a configuration to a node and the name of the MOF file is different than the node, the command will fail. If you're planning on pushing the same configuration file on multiple nodes, consider changing the name of the node to a parameter. Each time you compile the configuration you will have to specify the name of the node and the corresponding file will be created. 
The configuration I'm using below is nothing more than the first configuration we've created, with the above change.

Now, back to business. The command to start the DSC configuration will result in something similar to the below:
What we have here is the process that LCM follows in order to check the current state of the system against what is described in the configuration we pushed and take any corrective actions necessary. 

The above screenshot contains verbose output from the entire configuration, however we will focus on the Web-Server windows feature, the lines marked by the green bracket. Note that LCM has identified the dependency between our resources and processes the windows feature resource first, followed by the file resource.

We have two kinds of operations performed against the windows feature resource, "Test" and "Set". The way LCM works is first test if the resource exists and is configured according to the configuration (red bracket) and if not, set it (yellow bracket). There is actually a third operation named "Get" that returns the status of the resource and is used within the context of Test. We'll talk about it when we'll go through creating a resource module in an upcoming article.

When the resource that is currently being processed is set successfully, LCM moves on to the next resource to configure. When all resources are sucessfull processed, the configuration has been applied! 

If you try to apply the configuration again, you'll notice that the set operations are skipped since the node is configurated as described in the configuration:
This is what is going to happen each time the LCM checks the node for consistency.

Now to the second way to apply a configuration, Pull.

Pull
The pull method is a bit more complicated. We have to configure the nodes to get their configurations from a pull service. A pull service is nothing more than a website that we publish the configurations on, along with any required resource modules. This is its biggest advantage, since having the modules available on the pull service saves us from the trouble of having to push the module files to all of the nodes. 

Since this post is about applying configurations, I am going to use a pull service I've already configured but the next post will be on how to configure your own. Let's start.

The below LCM configuration directs the LCM to register against the DSC service at dsc.lab.local and use the configuration WebApp001.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[DSCLocalConfigurationManager()]
configuration DSCClient
{
    param
    (
        [ValidateNotNullOrEmpty()]
        [string] $NodeName = 'localhost',

        [ValidateNotNullOrEmpty()]
        [string] $RegistrationKey
    )

    Node $NodeName {
        Settings{
            RefreshMode        = 'Pull'
        }

        ConfigurationRepositoryWeb LAB-DSC {
            ServerURL          = "https://dsc.lab.local:443/PSDSCPullServer.svc"
            RegistrationKey    = $RegistrationKey
            ConfigurationNames = @('WebApp001')
        }

        ReportServerWeb LAB-DSC {
            ServerURL       = "https://dsc.lab.local:443/PSDSCPullServer.svc"
            RegistrationKey = $RegistrationKey
        }
    }
}

The registration key is the key used by the node in order to register to the Pull Service and should be provided by the administrator of the service. The name of the configuration should also be provided by the administrator of the service since your config may have been renamed in order to avoid conflicts with other configurations or to comply with naming policies.

When you compile and apply the above configuration, the LCM will download the configuration from the Pull Service and apply it. Let's see it in action:

Getting the status of the configuration after you've configured the LCM will show only this specific action:

When the LCM will check for the updated configuration, the status will report a new type, "Initial". This is when LCM has downloaded and applied the configuration from the Pull Service:

From that point on, the status command will report a "Consistency" type, since the LCM is checking for configuration drift:

Everything should be OK, unless you're getting status other than "Success"!

The configurations used in this article are available in my Github repository here. Stay tuned for the next article of the series that's going to be about building your own pull service!

    Part 4 - Applying Configurations

Popular posts from this blog

Domain Controller Machine Password Reset

Configuring a Certificate on Exchange Receive Connector

Running Multiple NGINX Ingress Controllers in AKS