Deploying Windows Services with Chef
Deploying Windows services with chef can be a little tricky. The service
resource doesn’t actually know how to create services in Windows, and surprisingly, niether does windows_service
.
Fortunately, this is not a deal breaker since creating services is actually pretty easy using a variety of approaches, and the simplest being sc create
.
So our task breakdown is:
- Create the service if it does not exist.
- Stop the service
- Fetch the updated service files
- Start the service
Create the service
An execute
resource can run our sc
command. In order to check if the service exists first, we can use ::Win32::Service.exists?
in the guard block for the execute. You will also need to `require ‘win32/service’.
So, it might look like this:
end
Voile!
Stop the service
This one is straight forward with the service
or windows_service
resource:
Fetch the updated service files
In my case I am using my build server to “distribute” the services in a folder structure as a build step, which I then simply zip up, and can download as a build artefact.
This means I have two steps to “fetch”: Download, Unpack.
The download step is done with remote_file
:
You can of course use role
and environment
attributes to inject the URL for the package.
I’ve decided to use 7-Zip to do my unpacking, which I run with another execute resource:
Note that I’m subscribing to the remote_file[c:/temp/Package.zip
. This is because the remote_file
resource seems to execute asynchronously, so I need to wait for that to finish before trying to unpack it.
Start the service
Starting the service is straight forward. You can either use a new service resource (just provide a different name), or you can notify the existing service resource from your UnpackServices
:
Conclusion
And thats the nuts and bolts of it.
Theres a few things going on here, and I’ve templatised this into a way that makes it easy to extend without changing the recipe (as in, add new services), but that’s for another post.