Writing a DSC resource for Windows

Just some thoughts I’d like to share with the community regarding writing a DSC resource for Windows:

DSC is all the rage regarding config management on Windows. It’s not a product but a technology part of the Windows Management framework stack on newer OSes (the same stack where PowerShell sits). Several of the players in the “traditional” linxus-based config mgmt space are looking to DSC for windows-based config management, and with good reason: it’s a kick-ass technologi in need of a product.

Now that we have started on Windows support in Ansible it is my feeling that DSC naturally belongs among the win_ - modules.

A DSC config document comes in the form of a MOF file. This mof file can easily be generated using PowerShell (this is how most folks do it). This PowerShell file can be run with dynamic parameters in order to support multiple computers. The configuration takes dependency on one or more “DSC-enabled” PowerShell modules, which need to be present on the computer before the mof file is executed.

So, all Ansible needs to support DSC is some structuring around where to pick up these modules and DSC files. I was thinking of a folder structure like this:

webservers/
files/
templates/
tasks/
handlers/
vars/
meta/
win_dsc/
dsc_modules/
dsc_configurations/

The modules (which would be subfolders inside dsc_modules) would just be copied onto the target node when the role is executed.

In addition we’d need a “win_dsc” module (or something), which would execute a given file inside the dsc_configurations folder. the win_dsc module would look something like:

win_dsc: src=webserversDSC.ps1 params=(json object containing the variables, this will vary from dsc file to dsc file)

I’d be happy to write the DSC “plumbing”, but I’d need some help getting the module to pick up the modules and config files from the correct role directories.

Here’s a DSC intro from a recent Chef meetup:
http://www.youtube.com/watch?v=mXaAIawzNic

Hi Trond,

We’ve already talked a fair bit with the Microsoft Open Technologies Group and the DSC Team directly.

The problem with DSC right now, which they wish to address, is that it requires a description of the entire infrastructure, which means we can’t use it to implement single tasks. Thus, it doesn’t really “fit” with Ansible right now, but they are open to the idea of being able to execute smaller snippets and be able to use it to implement Ansible resources/tasks/modules. I’m very optimistic about that future.

That all being said, a module that says “apply this dsc” policy, that allows just pushing a MOF, if fair game, short term. The problem is, Ansible is really a system that is intended to make things easier.

Our Windows users are usually folks who have a lot of Linux, and some Windows, and want an easy introduction. If the way to write things is “write a DSC MOF”, that doesn’t feel like Ansible at all, and now there are two things to learn, and one is a very very very different model.

We’ve also confirmed with a lot of Windows users that they do want to automate things in Powershell, and DSC isn’t quite all there yet – I do think it’s part of a future, but there’s a need in Ansible to do a lot of step-wise imperative things. Thus I think our Powershell track is completely appropriate, though it’s not bad to have a module that can push a DSC MOF, we also want a horde of modules that means you never have to think about a DSC MOF either. I hope you see where I’m going - we’re here to simplify.

You are not correct that we need to modify the roles structure to accomodate this, the default “files/” directory in the role, with subdirectories, would be more than sufficient.

Also I would request that you please do not link videos/content from other config tools on this forum. When we disagree with things, it makes it sounds like we are attacking tool X and have an agenda with it, and we do not like to do that. I’m also somewhat limited from sharing my full opinions. It’s much easier if we just talk about what is best for Ansible, rather than “X did it this way”, since we aren’t X, nor do we wish to copy X :slight_smile:

I think I agree with you - Ansible and DSC are two very dissimmilar management modles (and that’s a good thing for Ansible).

My motivation for considering a dsc module for Ansible is simply the fact that a lot of great dsc configurations (similar to Ansible roles) are making its way onto the internets, and tapping into those resources could be benificial.

Ultimately I understand and respect your wish to stay true to the Ansible model. It’s probably a good call.

-Trond

Yeah, we can totally have a DSC module, it just shouldn’t dent the desire to have modules for most of the easier things. And should probably point at docs on writing that MOF.

I think if there are people who don’t know how to batch distribute a DSC to lots of machines, it might have some value – but is that really that hard?

I’m not sure what tools Windows provides for this, but I’d suspect you could attach one to all machines joining a domain or something similar, at least?

Just to comment on this.

I have come up with a pretty easy way to turn a DSC resource into an ansible module, re-using a lot of the open-source code coming out of the PowerShell team. It enables me to spit out Ansible modules a lot faster than developing a module from scratch.

I have a PR in now which tweaks the helper commands slightly and once that’s in devel I’ll be able to PR a lot of modules based on DSC code.

I think this is a better way, going with native ansible modules instead of trying to “bridge” into DSC/mofs.

-Trond

This sounds pretty huge, can you link to the PR?

Might have some questions but seems awesome.

Sorry Michael, I didn’t mean to reply in private email. I should stop doing stuff that late at night.

Anyways, here’s the reply I sent:

Here’s the PR for the helper function improvements:
https://github.com/ansible/ansible/pull/8769

It’s not technically required but it just eases the development and saves me from retyping tons of argument handling code, so that’s the technique I’ve gone with.

And example of a “ansible-ized” dsc resource can be found here:https://github.com/trondhindenes/ansible/compare/win_package

Basically all the code between #region dsc and #endregion comes from a DSC resource. The only thing I needed to add was some argument passing and output object stuff. Very lightweight compared to the dsc code itself (which is, as you can see, a beast).

That said, some of the DSC resources rely on others so it might not always be as simple as this, but a lot of them are pretty straight-forward.

Hi, will your new DSC-derived modules require PowerShell 4.0 (I believe its required for DSC)?
I’m close to deciding that any windows host to be managed needs to run PowerShell 4.0 anyway, but this might make this decision for me.

Many thanks,

Jon

No, there isn’t a “automatic” requirement on PS v. 4. I’m not using the DSC functionality per se, but rather the functions that comprise a DSC function (get-targetresource, set-targetresource and so on. So the PowerShell version requirement will depend on whats inside each of those functions.

As V.3 is the current Ansible requirement I try and stay away from requiring v.4 as best I can, and call that out/do a version check if I ever write a v4-and-higher module.

Thanks for clarifying.

Going off topic, does anyone know the rationale for sticking with Powershell 3.0 within Ansible?

Jon

You means as opposed to lower versions? PS 3.0 introduced support for importing/exporting from/to json, wich Ansible uses extensively. I think v3 is a good “baseline”

We decided on PS 3 while initially working with Rackspace Windows guys to
get WinRM support working. I don't recall if there were any other reasons,
but the built-in support for ConvertTo-Json and ConvertFrom-Json was
definitely one of them.

That being said, a number of existing Ansible modules depend on certain
packages/tools being installed on the remote system, so I don't think it
would be an issue for some Windows modules to require PS 4 if it's not
reasonably possible to implement with PS 3. A module needing PS 4 support
should fail cleanly with an error message vs. sending error information on
stderr and possibly incomplete results on stdout.

Thanks for clarifying.

I was just curious about the rationale really.

From the point of view of setting up a windows host, all the boxes available to me (2008 r2, mostly) have to have something installed in order to get to Powershell 3 or Powershell 4. Since you can go straight to 4, I wondered if there was really any benefit in maintaining support for Powershell 3.

However, having done a quick search the one difference between Powershell 3 and Powershell 4 in terms of supported operating systems seems to be Powershell 3 supports the original Windows Server 2008 (that is before the R2 version). Powershell 4 is only available for Server 2008 R2 it seems.

So I suppose Powershell 3 makes things most compatible. I am hoping to try out against a Server 2008 (not R2) 32 bit build shortly.

versions that support Powershell 3
http://www.microsoft.com/en-gb/download/details.aspx?id=34595

Supported Operating System
Windows 7 Service Pack 1, Windows Server 2008 R2 SP1, Windows Server 2008 Service Pack 2

Powershell 4:
http://www.microsoft.com/en-gb/download/details.aspx?id=40855

Supported Operating System
Windows 7, Windows Embedded Standard 7, Windows Server 2008 R2, Windows Server 2012

That sounds about right. Each version of PowerShell typically supports current OS + one version back. 3.0 was released for 2008R2, so that will work for 2008 also, while 4.0, which was released for 2012, will have support for 2008R2, but not 2008.

Hi Trond,

Big fan of your work and your blog posts. Has there been any traction with your Ansible Win_DSC module? Have you played with Ansible V2 and is there any differences with Windows support there?
(I know you had also posted to the general Ansible group: https://groups.google.com/forum/#!topic/ansible-devel/gDBBSO85ohM)

Thanks,
Jeff

Hi, and thanks!

Yep, there has been some progress:

  1. I’ve created a working prototype of a module-generator which basically takes a DSC resource and generated the required wrapper to represent it as an Ansible module. You can follow that work in this github repo:
    https://github.com/trondhindenes/AnsibleDscModuleGenerator (I’ll update the readme today in case you want to get started)

  2. Using the above, I’ve scripted an ansible module generator using all available DSC resources from the PowerShell Gallery (https://www.powershellgallery.com/). All the auto-generated modules are in this github repo: https://github.com/trondhindenes/Ansible-Auto-Generated-Modules

There is a requirement on the February preview of PowerShell V5 for this, since I’m using the “Invoke-DSCResource” cmdlet. I’ve had some trouble with the April preview, so I’d recommend you to use the Feb preview for now.

After V5 has RTM’ed I guess we need to have a discussion about how to leverage DSC with Ansible. It’s an awesome resource, and using codegen like I demonstrated we can pretty much offload module development to the Powershell community/Microsoft (while we sit back and drink beers).

Let me know what you think!

That is really cool. I’m traveling with family for the next two weeks so I won’t be able to take a close look until I return on 7/1.

But I’m looking forward to trying it out. I’m using WMF 5 April release but I’ll downgrade to Feb as you requested.

Thanks!!

Good stuff! I’ve updated the scripts + readme files, so everything should be ready when you get back :slight_smile: