Working with DSC in the context of 3rd party CM tooling. Part 7: Puppet notifications

Like Chef, Puppet also support the concept of notifications. A change event on one resource triggers an action on another resource. Support for this kind of functionality helps with keeping resources monotonic and within the boundaries of the technology domain that is being governed by the resource. For example: a Website resource doesn’t have to restart a service, as the service resource can be notified of the change event that requires the restart and handles that job that obviously belongs to the service resource domain. It also keeps you from writing custom resources when an existing resource doesn’t do that one thing you need but could be handled using a notification to another resource.

I detailed some of my scenario’s in the Chef part 2 post. For this post I’ll investigate how we to achieve a similar implementation with Puppet.

Index:

Let’s continue with the same manifest where we left off in the previous post.

dsc { 'some file':
  dsc_resource_module_name => 'PSDesiredStateConfiguration',
  dsc_resource_name => 'File',
  dsc_resource_properties => {
    ensure => 'present',
    destinationpath => 'c:/testfile.txt',
    contents => 'some text',
  }
}

The scenario again is that when the file content is changed by the resource by an update or corrective action, that the bits service needs to restart. The scenario isn’t exactly useful but it still proves the point without the system needing to reboot or crash or anything.

With Puppet, the refresh action is available to a only a couple of inbox resources like the one we want to target Service.

First let’s update the manifest so it is ensured that the bits service is started and will start automatically (enable) when Windows is started.

dsc { 'some file':
  dsc_resource_module_name => 'PSDesiredStateConfiguration',
  dsc_resource_name => 'File',
  dsc_resource_properties => {
    ensure => 'present',
    destinationpath => 'c:/testfile.txt',
    contents => 'some text',
  }
}

Service { 'bits':
    ensure => 'running',
    enable => true,
}

Lets stop the bits service and set the startup type to manual so we can actually see the resource doing something.

Get-Service -Name bits | Stop-Service -PassThru | set-service -StartupType Manual

bitsstatus

Now let’s apply the manifest.

puppet apply .\dsc01.pp

puppetapply01

Note that you can always add --debug so you can see in detail what is going on under the covers

As the result we can inspect the service again and indeed, it now has the state of started and the startup type of automatic.

bitsstatus02

Now let’s see how we implement this notification. This can be done via multiple ways, in this case it makes sense to notify the Service resource when the file changes (you could also subscribe the Service resource on file changes).

dsc { 'some file':
  dsc_resource_module_name => 'PSDesiredStateConfiguration',
  dsc_resource_name => 'File',
  dsc_resource_properties => {
    ensure => 'present',
    destinationpath => 'c:/testfile.txt',
    contents => 'some text',
  },
  notify => Service['bits'],
}

Service { 'bits':
    ensure => 'running',
    enable => true,
}

As you can see, the notify takes a string in the form: ResourceType['name'] similar as how DSC DependsOn is specified.

Time to introduce a change to the file.

'File Changed!' > c:\testfile.txt

Now let’s see if we can run the manifest in WhatIf (-noop) mode to see what would happen.

whatif

Cool! As you can see, applying this in noop mode will (as expected) give you what would happen without it being effected. Now let’s apply this.

notify

Voila, that was easy. I’m so hoping this functionality will show up natively in DSC one day.

To be continued!

comments powered by Disqus