Published on 18 September 2018 by

Editor's note: Guest blogger Dan Franciscus is a systems engineer for the Institute for Advanced Study.

In this blog, I will go through the steps of taking a custom community Desired State Configuration (DSC) resource module, in this case “cSNNP,” which is used to configure SNMP on a Windows computer, and use it in a Puppet manifest using the Puppet dsc_lite module. The dsc_lite module is an alternative to the existing dsc module, providing users with a more direct and lightweight approach to using Puppet with DSC.

PowerShell Desired State Configuration (DSC) is a fantastic tool for configuring Window servers. Not only does Microsoft produce a large amount of resources that can be used in DSC, but the community produces a lot of resources too. Many times, when there is no Microsoft-provided resources that fit a need for a Windows server, a custom community-created resource exists that you can leverage.

Combining Puppet and DSC resources using dsc_lite can provide excellent benefits for managing Windows. For instance, monitoring your configurations on Windows through native DSC can be difficult due to not having a GUI to use. This is where combining Puppet and DSC makes a lot of sense. Using Puppet as your configuration management solution but also leveraging DSC resources has been supported for a while, but with the release of the dsc_lite Puppet module, IT teams can now leverage any DSC resource as long as it can be used with Invoke-DSCResource. Ultimately, this means Puppet users can configure Windows using all those g reat DSC resources in the PowerShell Gallery without waiting for Puppet to add them as a supported resource.

Distributing DSC resources

When using DSC, one thing to consider is how to get resources to your target nodes. Ideally, this would likely be an internal repository that holds all the DSC resources, so that you do not rely on the PowerShell Gallery. For the sake of simplicity, I will be using the PowerShell Gallery as a repository in this example.

A quick and easy way to ensure your nodes obtain the DSC resources you use in Puppet, is to use the exec Puppet resource and set a repository like this:

exec { 'Set-NuGetProvider':
  command   => 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force',
  unless => 'if (!(Get-PackageProvider -Name nuget)){exit 1}',
  provider  => 'powershell',
 } ->

 exec { 'Set-PSGalleryTrusted':
  command   => 'Set-PSRepository -Name PSGallery -InstallationPolicy Trusted',
  unless => 'if ((Get-PSRepository -Name PSGallery | Select-Object -ExpandProperty InstallationPolicy) -ne Trusted){exit 1}',
  provider  => 'powershell',
 } ->

Above we ensure the NuGet package provider is installed and the PSGallery repository is trusted. You can easily change this to an internal repository as well.

Next, we can use the exec resource again to install the required modules that contain our DSC resources (xPSDesiredStateConfiguration and cSNMP):

exec { 'xPSDesiredStateConfiguration-Install':
  command   => 'Install-Module -Name xPSDesiredStateConfiguration -Repository PSGallery -Force',
  unless => 'if (!(Get-Module -listavailable xPSDesiredStateConfiguration)){exit 1}',
  provider  => 'powershell',
} ->

exec { 'cSNNP-Install':
  command   => 'Install-Module -Name cSNMP -Repository PSGallery -Force',
  unless => 'if (!(Get-Module -listavailable cSNMP)){exit 1}',
  provider  => 'powershell',
} ->

Note that if you do use an internal repository, you may want to use the –Repository parameter in Install-Module to ensure your nodes are pulling modules from the repository you intended.

Example manifest

In this example Puppet manifest we would to perform the following tasks:

  • Ensure the SNMP service is present via Windows features
  • Ensure the RSAT tools for SNMP is present via Windows features
  • Ensure that the SNMP service is set to have ‘Test’ as the accepted community name as well as have the rights set to “READ ONLY”

First, we will use the Windows feature DSC resource to ensure that the SNMP service is present. To find what DSC properties to use, we can run the Get-DSCResource command in PowerShell on a computer that has these DSC resources installed.

PS C:\> Get-DscResource WindowsFeature | Select-Object -ExpandProperty Properties

Name                 PropertyType   IsMandatory Values
----                 ------------   ----------- ------
Name                 [string]              True {}
Credential           [PSCredential]       False {}
DependsOn            [string[]]           False {}
Ensure               [string]             False {Absent, Present}
IncludeAllSubFeature [bool]               False {}
LogPath              [string]             False {}
PsDscRunAsCredential [PSCredential]       False {}
Source               [string]             False {}

The DSC module name and version are first set in Puppet, followed by the DSC properties “ensure” and “name.” The DSC module name, version, properties and their values can all be obtained by running Get-DSCResource. Setting the “ensure” property to “present” means that the SNMP-Service will be installed if is not already. In contrast, “absent” would uninstall it.

dsc {'SNMP-Service':
  resource_name => 'WindowsFeature',
  module        => {
    name    => 'PSDesiredStateConfiguration',
    version => '1.1'
  },
  properties => {
    ensure => 'present',
    name   => 'SNMP-Service',
  }
} ->

Next, we use the same DSC module as above “PSDesiredStateConfiguration” to ensure RSAT tools are also installed. You will notice that the only change in this section is that the “name” property is changed to “RSAT-SNMP.”

dsc {'SNMP-RSAT':
  resource_name => 'WindowsFeature',
  module        => {
    name    => 'PSDesiredStateConfiguration',
    version => '1.1'
  },
  properties => {
    ensure => 'present',
    name   => 'RSAT-SNMP',
  }
} ->

Finally, we will use the cSNMPCommunity DSC resource to ensure that the SNMP community name is set to “Test” and that the “right” is “ReadOnly.” We can use the Get-DSCResource cmdlet again to find what properties are available:

PS C:\> Get-DscResource -Module cSNMP -Name cSNMPCommunity | Select-Object -ExpandProperty Properties

Name                 PropertyType   IsMandatory Values
----                 ------------   ----------- ------
Community            [string]              True {}
Ensure               [string]              True {Absent, Present}
Right                [string]              True {None, Notify, ReadCreate, ReadOnly...}
DependsOn            [string[]]           False {}
PsDscRunAsCredential [PSCredential]       False {}

The DSC properties ensure, name, and right are all represented in Puppet to ensure that our SNMP service is configured.

dsc {'SNMP-Community':
  resource_name => 'cSNMPCommunity',
  module        => {
    name    => 'cSNMP',
    version => '1.0.33',
  },
  properties => {
    ensure => 'present',
    community   => 'Test',
    right => 'ReadOnly',
  }
}

Now, if I run Puppet on a node, we see all of the steps created in our manifest apply:

Notice: /Stage[main]/Main/Node[puppetagent-win]/Exec[Set-NuGetProvider]/returns: executed successfully
Notice: /Stage[main]/Main/Node[puppetagent-win]/Exec[Set-PSGalleryTrusted]/returns: executed successfully
Notice: /Stage[main]/Main/Node[puppetagent-win]/Exec[xPSDesiredStateConfiguration-Install]/returns: executed successfully
Notice: /Stage[main]/Main/Node[puppetagent-win]/Exec[cSNNP-Install]/returns: executed successfully
Notice: /Stage[main]/Main/Node[puppetagent-win]/Dsc[SNMP-Service]/ensure: invoked {"name"=>"PSDesiredStateConfiguration", "version"=>"1.1"}\WindowsFeature
Notice: /Stage[main]/Main/Node[puppetagent-win]/Dsc[SNMP-RSAT]/ensure: invoked {"name"=>"PSDesiredStateConfiguration", "version"=>"1.1"}\WindowsFeature
Notice: /Stage[main]/Main/Node[puppetagent-win]/Dsc[SNMP-Community]/ensure: invoked {"name"=>"cSNMP", "version"=>"1.0.33"}\cSNMPCommunity
Info: Creating state file C:/ProgramData/PuppetLabs/puppet/cache/state/state.yaml
Notice: Applied catalog in 78.17 seconds 

Using Puppet with the dsc_lite module provides a flexible method to use a variety of custom DSC resources. We can setup and distribute DSC resources with the exec resource type in Puppet and then map those DSC resource properties found in the Get-DSCResource command into a Puppet manifest quite easily.

Dan Franciscus is a systems administrator at the Institute for Advanced Study in Princeton, NJ. He is an active freelance writer for several technical sites. You can follow him on Twitter at @dan_franciscus.

Learn more

Share via:
The content of this field is kept private and will not be shown publicly.

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.