Legacy apps to Azure with PowerShell DSC and CI + CD

Disclaimer: Cloud is very fast moving target. It means that by the time you’re reading this post everything described here could have been changed completely Smiley. Hopefully some things still apply to you! Enjoy the ride!


I have been blogging about power of PowerShell, ARM and automation earlier. But every now and then I still come across to discussions which typically goes like this:

Yes, it works for those new fancy apps but I have this old legacy <InsertYourTechnologyOrAppHere /> which cannot be automated and cannot be put to cloud just like that.

Therefore, I decided to create demo which will show that you can do amazing things even with older technologies. CI + CD and automations apply even if your app is not built using "new" technologies.

Let’s jump directly into my demo application architecture:
Legacy app architecture

My application runs in Windows Server and it has two components:

  • Common Gateway Interface (CGI) app running under IIS
    • Written in C++
    • Reads information from registry
  • Windows Service
    • Written in C++
    • Writes information to registry

Basically, these components interact with each other via registry and we don’t want to (or as typically you cannot) modify source code at all so we’re stuck with this solution. This means that we need to leverage Infrastructure-as-a-Service (IaaS) in our solution since there we have free hands when it comes to server configuration.

Again, our code setup is the same as earlier in my solutions:
Source code structure

Structure has already familiar "deploy", "src" and "test" sub-folders.

Deploy folder even has pretty much same content as earlier but there is one new thing underneath sub folder "DSC". We'll come back later to that.

Source folder has our legacy application components and test folder has simple release test which we will use in our release process.

Our CI is almost same as in the previous examples (so no re-inventing wheel in here Smiley):
Build definition

And of course, our CD follows the same footprints as earlier:
Release definition

Only new thing in the release definition is our PowerShell Pester testing task titled as "Pester Test Runner". It will validate that our release was successful and environment is running as it should. But more about that later (see I’m postponing all the good stuff to the end Smiley).

How is the Windows Server configuration handled?

This is the part where the DSC comes relevant. If you’re completely new to the topic, then you might want to check these first:
Windows PowerShell Desired State Configuration Overview Built-In Windows PowerShell Desired State Configuration Resources

Similarly, from Azure Automation perspective:
Azure Automation DSC Overview Getting Started With Azure Automation DSC

Okay so now I assume that you know what's DSC all about and why it's very interesting piece when automating environment configuration and setup.

In my demo, I have this one extra sub folder in "deploy/DSC" which I already mentioned earlier. This folder contains dscExtension.ps1 file:

This file basically contains configuration to:

  • Ensure that correct Windows features are installed (e.g. IIS and friends)
  • Ensure that IIS is configured to be CGI app friendly
  • Download our apps from Azure Storage to the VM
  • Install and configure our apps

First one is straightforward and basic DSC scenario. Second one requires a bit more tweaking of the IIS and IIS Configuration Reference is great help on that. Third and fourth ones are purely your application specific from the installation point of view. I only had few extra lines to get the applications files downloaded to the VM.

How did those applications land into the virtual machine?

In our deploy.ps1 file we had part that took our compiled application and created Zip package out of them. This package was then copied over to Azure Storage and SAS Token is then used to grant temporary access to those resources using "fixed SAS token url". This url is passed (with the help of PowerShell of course!) into the ARM process and that lands into our DSC process as easily downloadable content.

What was that Pester in CD?

Pester is very handy PowerShell testing framework which you can use in your unit tests and as in this case, release tests. I have simple validation script to check that this newly created environment is as expected. And if it’s not then it would fail the release process. This way I can easily validate that the environment creation works as planned and that my DSC has configured all the things required correctly. And how did Pester know that environment specific url then? Well it was passed by deploy.ps1 as environment variable in the CD using VSTS Logging Commands.

How does the final output look like?

Result as animated gif :)

Closing words

In this demo, I presented few new tools that you should take into use. DSC is extremely powerful if you combine that with ARM and PowerShell you can build cool Infrastructure-as-a-Service solutions.

As promised you can find the source code used in this example application from GitHub at JanneMattila / 300-WindowsService.

Anyways... Happy hacking!