Why use DSC composite resources?

When you convert a set of DSC configuration blocks into a reusable DSC composite resource, you abstract the complexity of configuration that targets nodes or pieces of software and improves the manageability of your configuration scripts.

If this sounds confusing, it's because it is confusing to explain without an example to look at. If you look at the DSC configuration script in Defining a DSC configuration script file section of this chapter, you will see several DSC resources being used to declare the desired state of a target node. We split them into two node blocks because only some of the target nodes should have ExampleSoftware installed on them and all of them should have .NET installed, a specific environment variable set, and a specific file created. Let's imagine that we need to install another piece of software, called TheRealSoftwareStuff, software that has its own list of dependencies that are different from ExampleSoftware. We would have a long list of statements with a complicated DependsOn dependency list.

We've mentioned DependsOn several times without specifically calling it out. DependsOn is a parameter all DSC resources implement. This allows DSC to execute the DSC resources in an expected order. If DependsOn is not specified, then DSC does not guarantee the order in which it executes the DSC resources defined.

Adding to the middle of this list would require reordering the entire dependency tree and copying and pasting entries until it looked right, which we could get wrong. Wouldn't it be simpler and less error-prone if we were able to group the dependencies and steps into separate blocks? If we could do that, our dependency tree would suddenly become a lot smaller, and only the parts that matter to the software we are installing would be present.

We are going to take the example in the script file example, add TheRealSoftwareStuff software to it and then split it up into DSC composite resources. If you're thinking I didn't explain anything about the earlier remark of how DSC composite resources have to be packaged specially and it's hard to get right, don't worry; I will get to that. It's easier to understand if we look first at why you would want to do this. I won't copy the original here, as you can look at the Defining a DSC configuration script file section for that. Here is the modified script before we start to encapsulate the code. This example can be used with the following:

# beginning of script
[CmdletBinding()]
param(
[Parameter()]$OutputPath = [IO.Path]::
Combine($PSScriptRoot, 'InstallExampleSoftware'),
[Parameter()]$ConfigData
)

Configuration InstallExampleSoftware
{
Node $AllNodes.NodeName
{
WindowsFeature DotNet
{
Ensure = 'Present'
Name = 'NET-Framework-45-Core'
}
}

Node $AllNodes.Where({$_.Roles -contains 'FooBar'}).NodeName
{
Environment AppEnvVariable
{
Ensure = 'Present'
Name = 'ConfigFileLocation'
Value = $Node.ExampleSoftware.ConfigFile
}

File ConfigFile
{
DestinationPath = $Node.ExampleSoftware.ConfigFile
Contents = $ConfigurationData.NonNodeData.ConfigFileContents
}

Package InstallExampleSoftware
{
Ensure = 'Present'
Name = $Node.ExampleSoftware.Name
ProductId = $Node.ExampleSoftware.ProductId
Path = $Node.ExampleSoftware.SourcePath
DependsOn = @('[WindowsFeature]DotNet')
}
}

Node $AllNodes.Where({$_.Roles -contains 'RealStuff'}).NodeName
{
WindowsFeature IIS
{
Ensure = 'Present'
Name = 'Web-Server'
}

WindowsFeature IISConsole
{
Ensure = 'Present'
Name = 'Web-Mgmt-Console'
DependsOn = '[WindowsFeature]IIS'
}

WindowsFeature IISScriptingTools
{
Ensure = 'Present'
Name = 'Web-Scripting-Tools'
DependsOn = @('[WindowsFeature]IIS',
'[WindowsFeature]IISConsole')
}

WindowsFeature AspNet
{
Ensure = 'Present'
Name = 'Web-Asp-Net'
DependsOn = @('[WindowsFeature]IIS')
}

Package InstallRealStuffSoftware
{
Ensure = 'Present'
Name = $Node.RealStuffSoftware.Name
ProductId = $Node.RealStuffSoftware.ProductId
Path = $Node.RealStuffSoftware.Source
DependsOn = @('[WindowsFeature]IIS', '[WindowsFeature]AspNet')
}
}

}

InstallExampleSoftware -OutputPath $OutputPath -ConfigurationData $ConfigData
# script end

It's obvious that this will get quite long as we keep adding software and other features. If we need to insert a new IIS feature, it has to be inserted in the dependency chain of the IIS feature set as well as before the MSI package install. We also need to remember to keep the chain of steps between the ExampleSoftware install and RealStuffSoftware separated and not mix any steps between the two. In a long script, this may not be apparent when you come back to it after months of successful use.

We can reduce this complexity by grouping these declarations into DSC composite resources. In the new approach, shown as follows, we replace the long list of declarations with one DSC composite resource declaration. Note that we put the configuration data we used earlier as parameters to the parameter declarations. We will read more about this when we get to the syntax in the next section:

# beginning of script
[CmdletBinding()]
param(
[Parameter()]$OutputPath = [IO.Path]::Combine($PSScriptRoot, 'InstallExampleSoftware'),
[Parameter()]$ConfigData
)

Configuration InstallExampleSoftware
{
Import-DSCResource -Module ExampleSoftwareDscResource
Import-DSCResource -Module RealStuffDscResource

Node $AllNodes.NodeName
{
WindowsFeature DotNet
{
Ensure = 'Present'
Name = 'NET-Framework-45-Core'
}
}

Node $AllNodes.Where({$_.Roles -contains 'FooBar'}).NodeName
{
ExampleSoftwareDscResource InstallExampleSoftware
{
Name = $Node.ExampleSoftware.Name
ProductId = $Node.ExampleSoftware.ProductId
Path = $Node.ExampleSoftware.Source
ConfigFile = $Node.ExampleSoftware.ConfigFile
ConfigFileContents =
$ConfigurationData.NonNodeData.ConfigFileContents
}
}

Node $AllNodes.Where({$_.Roles -contains 'RealStuff'}).NodeName
{
RealStuffDscResource InstallRealStuffSoftware
{
Name = $Node.RealStuffSoftware.Name
ProductId = $Node.RealStuffSoftware.ProductId
Path = $Node.RealStuffSoftware.Source
}
}

}

InstallExampleSoftware -OutputPath $OutputPath -ConfigurationData $ConfigData
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset