Desired State Configuration Extension and the Replica Domain Controller ARM Template
Published May 26 2020 12:01 AM 6,062 Views

By now, you have probably examined my code (if not, please click the link). If you are familiar with ARM Templates, the code should seem relatively straightforward. There is one piece that may seem foreign though: the Desired State Configuration (or DSC) extension. I wanted to take some time out and unpack the DSC extension within your ARM Template configuration. From there, the last post will surround the DSC script plus how to troubleshoot if something does not work right (these topics are ever so slightly mysterious at times).


First off, let us dig into what DSC is related to infrastructure as code. The management and maintenance of servers becomes difficult and challenging as time evolves plus configurations change. In the sysadmin world, we tend to end up with a plethora of scripts to manage a server and usually those scripts live on some sort of utils server or UNC share. With the cloud, that legacy practice just does not scale (unfortunately). With cloud, we need a better way to automate a task (and maybe even a series of tasks) or a configuration state to prevent configuration drift among servers. DSC is a declarative way of leaning on PowerShell scripts, where you define and configure instances of resources. Upon running configurations, DSC ensures the configurations match up with a predefined state all servers should hold. These configurations are also idempotent: The Local Configuration Manager (LCM) continues to ensure that machines are configured in whatever state the configuration declares. Typically, these configurations exist on some sort of pull server. The pull server is an automation server that allows all configurations to be maintained on many servers across a network.


Seems simple as a concept and a powerful reality that all sysadmins should be adopting, right? Right. After reading through these descriptions, you may be wondering how DSC works with my ARM Template and that is ever so slightly different. I want to shed some light, as I am not deploying a pull server, but I am using a DSC script + a DSC extension to tell the server what I want it to do, post build.


Within Azure Resource Manager IaaS deployments, there are VM extensions you can lean on for post-deployment configuration and automation tasks on Azure VMs. The extensions themselves are comprehensive and extensive. Rather than spend too much time going into what those extensions can do and why they are invaluable related to configuration, I want to focus on the DSC VM extension specifically, as that is the extension my template makes use of during deployment. By using this extension, it uploads and applies a PowerShell DSC configuration on an Azure VM. During the automated ARM Template deployment, the DSC extension calls into PowerShell DSC to enact the received DSC configuration on the VM. So, there is no pull server managing configuration state after the VM is deployed. Rather the DSC extension in my template runs through a series of configurations I declare in the script before finishing deployment. To break it down, my script formats the data disk, joins the VM to the existing domain, adds the Active Directory Domain Services (ADDS) role, and promotes the domain controller. Pretty nifty, right? The best part is you can use this extension on Windows and Linux VMs (although I do tend to see Linux VMs deployed and managed using a configuration management tool like Ansible, Salt Stack, Chef, or Puppet).


The actual DSC schema and example template structure can be found here. I find looking at example code helpful if I am embarking down a path I have personally never traveled on before. Let us now look at how the DSC extension is called within my ARM Template:



Seems straightforward, right?


So the DSC extension is declared as an actual resource within the ARM Template and depends upon the vmloop that you use for the VMs by leaning on a copyIndex function (coupled with a padLeft + concat function to differentiate on names) from earlier (note this DSC extension configuration also makes use of those same functions within the name). You should also see the URL referenced within this resource. The extension expects to find your DSC files in a zip file at the URL specified and the DSC script must be in the root folder of the zip file. From there, the zip file needs to be accessible. Within my template, I zipped up all required modules and the script to host within a public GitHub repository. GitHub can serve up these files to your ARM Template during deployment, or you could lean on Azure Blob Storage and provide a SAS token like the following example. I decided to leave my zip file up on GitHub so you can see just exactly how the zip file needs to be assembled for the DSC Extension to work correctly within the template deployment.


One last thing I want to call out are the settings vs. protected settings within the ARM Template. As a frame of reference, here is how they show up within my template:



Protected Settings



So, what is the difference? Well, all settings declared here for the DSC Extension are saved in a settings text file on the VM as the extension deploys. Properties listed under settings are public properties. Public properties are not encrypted in the settings text file, so you will not want to have any sort of password or important username like your Enterprise Administrator inside the template. Properties listed under protectedSettings are encrypted with a certificate and are not shown in plain text in the settings file on the VM.


Now, I know I am sort of covering these topics quickly and I want to encourage that you take time to explore the example code within your environment for a better overall understanding. As always, if you run into any snags or care to connect offline for a deeper discussion, do not hesitate to let me know! Tune in for the final installment when we go over the actual DSC script + how to troubleshoot (in the event something does not work right for you)!

Version history
Last update:
‎May 28 2020 01:39 PM
Updated by: