Summary: Matthew Hitchcock takes us through a deeper look at Azure DSC.
It's an honor for me to be writing my first Hey, Scripting Guys! Blog post! I'd like to share something I have been doing a lot of recently—using advanced Desired State Configuration (DSC) files with Azure virtual machines, and perhaps more importantly, learning how to troubleshoot them! Let's face it, this is IT and we wouldn't have jobs if everything was easy and worked first time.
Keen readers of the Hey, Scripting Guys! Blog will have seen a series by Honorary Scripting Guy, Sean Kearney: Use PowerShell to Create Virtual Machine in Azure. He discusses how to create virtual machines and assign DSC files through the DSC VM Extension. In Part 4, Sean created a basic configuration to configure a web server. It was a simple example with static data to teach a concept, but when we get into doing this for real we often need to do something a bit more advanced.
What is an advanced DSC file?
By advanced DSC, I mean something that is parameterized and reusable. Take for example, a baseline server configuration. You may want to have a DSC that will join the server to a domain. The domain that you join may change from VM to VM, and the credential used may change also. You may want to pass a file share path for source files, which may change depending on the environment. In short, anything that you parameterize so you can reuse it is considered advanced.
A note about prerequisites
If you're following along, you'll need to know that I am using some downloadable DSC resources; **xComputerManagement** and **xSmbShare**. I am also using the Azure PowerShell module. I have an Azure subscription and I have already opened a PowerShell session, connected to my Azure subscription, and specified a default storage account. I will not cover these steps in this post, but there are plenty of articles online that discusee setting up your Azure connection. You can download the DSC resources and Azure module from the PowerShell Gallery.
Creating an advanced configuration file
With the PowerShell ISE open and my subscription established, I’ll create the DSC file that I want to use and save it as Fileserver.ps1:
Configuration FileServer
{
param (
[Parameter(Mandatory)]
[pscredential]$domainCred,
[Parameter(Mandatory)]
[string]$domainName,
[Parameter(Mandatory)]
[string]$FolderPath
)
Import-DSCResource -Module xComputerManagement,xSmbShare
Node localhost
{
LocalConfigurationManager
{
ActionAfterReboot = 'ContinueConfiguration'
\ ConfigurationMode = 'ApplyOnly'
RebootNodeIfNeeded = $true
}
xComputer JoinDomain
{
DomainName = $domainName
Credential = $domainCred
Name = $env:computername
}
File MyPackageDirectory
{
DestinationPath = $FolderPath
Type = "Directory"
Ensure = "Present"
DependsOn = "[xComputer]JoinDomain"
}
xSmbShare MyFileShare
{
Ensure = "present"
Name = "SourceFiles"
Path = $FolderPath
FullAccess = "Domain Admins"
Description = "Source for all Packages in the environment"
DependsOn = "[File]MyFileDirectory"
}
}
}
As you can see, there are a few parameters at the top of the file. They will take the domain name input, the domain credential to help join the domain and a file share path for a package I want to deploy.
"Credentials?!" I hear you cry. "This will mean storing plain text passwords or much jiggery-pokery with certificates to encrypt them!"
Fret not, my security conscious admin, I will put your mind at ease shortly. After I have my DSC script with parameters, it is time to upload it to my Azure storage account. I can do this by using the following command:
Publish-AzureVMDscConfiguration -ConfigurationPath ".\FileServer.ps1"
This uploads a file into the storage account associated with my Azure subscription. If you don't have one defaulted, you will be prompted to set it. If this is your first time uploading a DSC file, a folder called windows-powershell-dsc will be created. The file is uploaded as a ZIP file, and it includes the modules that are needed to apply this configuration to the target server. There is a lot more that you can configure with this cmdlet, and I encourage you to explore the additional parameters.
Note If you run into issues with the Help topics for Azure PowerShell cmdlets, please let the team know on GitHub at Azure PowerShell issues.
Assign the configuration to a virtual machine
After it is uploaded, I can assign it to my virtual machine. I have an existing virtual machine that I will use:
get-azurevm -ServiceName "hitchfscloud" -Name "HitchFS01" | Set-AzureVMDscExtension -Version "2.9" -WmfVersion latest -Verbose -ConfigurationArchive "FileServer.ps1.zip" -ConfigurationName "FileServer" -ContainerName "windows-powershell-dsc" -ConfigurationArgument @{domainName = "hitchy.com"; domainCred = Get-Credential; FolderPath = "C:\SourceFiles"} | Update-AzureVM
With this command I have assigned the DSC Extension to the virtual machine in Azure and assigned my DSC file from Azure Storage to the extension. There are a few interesting parameters to pay attention to:
- -Version Dictates the version of the extension that will be used. You can explore versions at Release history for the Azure DSC Extension. The default is 2, but evaluate which is right for you.
- -WMFVersion Refers to the version of the Windows Management Framework that will be used by the extension. This may matter to you. The Default if not specified at the time of writing is "latest" which is WMF 5 Preview.
- -ConfigurationArgument This is the most interesting parameter here. See how each parameter I specify matches up to one in my script? Here is what happens next:
A file is created on the virtual machine with the values I have given it. This will be used with the DSC file to set up the virtual machine. Azure recognizes that I have provided a credential and uses the certificate for the virtual machine to encrypt that credential before writing it to the Azure VM disk. Clever huh? We will take a deeper look at that shortly.
What's going on?
So now if I execute this command, I can wait a few minutes and use the Get-AzureVMDSCExtensionStatus cmdlet to see that it's actually running:
If I run that command a few more times, I can see the state changing, so I know everything is running perfectly:
The Azure DSC Extension is doing the following:
- Creating a folder called C:\Packages\Plugins\Microsoft.Powershell.DSC for the extension
- Creating a folder for the version of the extension, in my case: C:\Packages\Plugins\Microsoft.Powershell.DSC\2.10.0.0
- Creating the relevant files and folder structure in this folder
- Downloading the WMF files and DSC file into the following folder: C:\Packages\Plugins\Microsoft.Powershell.DSC\2.10.0.0\DSCWork
- Extracting the required modules from the DSC ZIP folder that accompanied my configuration and placing them in C:\Program Files\WindowsPowerShell\Modules
- Installing the WMF package and restarting to apply the DSC Configuration
The parameters that we specified when we assigned the configuration to the VM and the password were written to:
C:\Packages\Plugins\Microsoft.Powershell.DSC\2.10.0.0\RuntimeSettings\0.settings
Here is what it looks like on disk:
Everything is in there, nice and secure. Perfect.
Now that you have an understanding of how to write and apply these configurations, what about troubleshooting? I have a feeling that something is going to go wrong with this configuration, and I am going to have to fix it. Join me in Part 2 where I’ll take a deeper look at what's going on inside of the Azure VM and how we can troubleshoot the errors.
~Matthew
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy