Versioning composite resources

I’ve been using DSC (with custom modules and composite resources) to manage a number of servers. Now the time has come to make a change to one of my Composite Resources (CR), which is utilized by a few different configurations. I didn’t plan well for this, and I realized I’d like version control over my CR’s. In the future when I change a CR I’d like to create a new version, then change my existing configs to point to the new version as I see fit, or create new configs based on the new version of the CR.

So far so good. Right now I have a single module with all my CR’s in it (this is what all the tutorials online seem to show). Drill down inside the module folder, inside a CR folder, and you get to the x.psd1 and x.schema.psm1 files for a given CR. The x.psd1 file contains a line that says “ModuleVersion = ‘x.x.x’”. This makes me think I could specify this CR’s version when referencing it in a config. However, I don’t see any way to do that. The only thing I see for specifying a version is the “ModuleVersion” paramater for “Import-DscResource”. But it’s not the version of the module I want to specify, it’s the version of the composite resource inside the module!

So, maybe I have to split out all my CR’s into separate modules, and version the modules. But if that’s necessary, what’s the point of the .psd1 file for the CR with the version number in it?

By the way, I’d love to hear others’ approaches to versioning things in DSC. I don’t see it addressed much in the literature, but it has got to be a common desire to make a change to a bunch of servers (either the way you configure them or a fix/enhancement to a custom resource) but roll it out in a slow and controlled fashion.

The version number inside the manifest is important, but it isn’t want the LCM and pull server use. Keep in mind that manifests are used across all kinds of PowerShell modules, not just DSC resources - so some of what’s in the manifest isn’t applicable to resources. For resources, versioning is handled in the filename, as the resource module sits on a pull server.

So, before I assume that you’re deploying this via a pull server - are you?

Yes, I’m deploying this via a pull server.

I worked on it some more and did find that the following worked:

  1. Split out each composite resource into its own module, with a folder structure as follows:
   module1 (folder)
     1.0 (folder)
       module1.psd1 (file, line inside states ModuleVersion = 1.0)
       DscResources (folder)
         resource1 (folder)
           resource1.psd1 (file, line inside states ModuleVersion = 1.0)
  1. Note that you can have multiple version folders using this structure, just make sure you modify the .psd1 files as well
  2. When you write your configs, first import the proper module version, e.g.
    Import-DscResource -ModuleName module1 -ModuleVersion 1.0

I assume that under this type of structure, you could have more than one composite resource per module, but you lose your ability to version those resources separately. Maybe that’s okay for some resources though.

I do like this setup because it forces me to be very explicit when composing configs about what version of each composite resource I’m using. Then if I do create a new version of a composite resource and want to slowly “upgrade” my configs, it’s easy to see which configs reference the older version by looking at the Import-DscResource lines.