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:
- Part 1: Chef intro
- Part 2: Chef notifications
- Part 3: Chef server
- Part 4: Chef bootstrapping
- Part 5: Chef client settings
- Part 6: Puppet intro
- Part 7: Puppet notifications
- Part 8: Puppet server
- Part 9: Puppet Modules, Roles and more
- Part 10: Puppet bootstrap
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
Now let’s apply the manifest.
puppet apply .\dsc01.pp
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.
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.
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.
Voila, that was easy. I’m so hoping this functionality will show up natively in DSC one day.
To be continued!