Desired State Configuration Azure Extension
If you read this blog you already heard about few tools in order to apply a Desired State Configuration script to your system. Today i want to write about Azure DSC Extension. This extension, can be used in two ways. The first, and the crappiest, is using the GUI, and you know what? I won’t spend much time on it. And the second one is using PowerShell Azure SDK!
So let’s take a look at this DSC Azure Extension!
Azure DSC Extension Portal
Let’s open Virtual Machines parameters in Azure portal
[su_frame align=”center”][/su_frame]
Once parameters appears in the left window, click on Extensions and on the next window, you’ll see a BGInfo extension and a DSC one (if you already apply a DSC configuration).
[su_frame align=”center”][/su_frame]
If you want to deploy a new DSC configuration, just click on Add and choose the Microsoft PowerShell DSC extension in the list.
[su_frame align=”center”][/su_frame]
A new window with few blah blah appears explaining what DSC is, why you should use it, and advertise you that PowerShell v5 will be installed alongside this extension.
[su_frame align=”center”][/su_frame]
Click on create. And fill all fields on the next Window in order to have the configuration applied.
Please note that if you already have a configuration applied, it’ll be remplaced by this one.
[su_frame align=”center”][/su_frame]
And now your configuration will apply (or not)!
Apply a configuration with Desired State Configuration
The first thing to do is to get the last Azure PowerShell SDK on github.
Once this is done let’s build a configuration in order to enable IIS
configuration NewWebsite { param ( [string[]]$NodeName = 'localhost' ) # Import the module that defines custom resources Import-DscResource -Module xWebAdministration Node $NodeName { # Install the IIS role WindowsFeature IIS { Ensure = "Present" Name = "Web-Server" } # Install the ASP .NET 4.5 role WindowsFeature AspNet45 { Ensure = "Present" Name = "Web-Asp-Net45" } } }
Please look that you don’t have to generate a MOF file, it’s the Azure DSC Extension that will generate it. Also, do not forget to install xWebAdministration resource 😉
Now we will use DSC to setup the environment, create the Affinity group, the service the VM and apply the DSC Configuration to the VM ! To do this task, the configuration script and all the needed resources will be merged into a single .zip file and pushed to a storage account and downloaded by the Azure DSC extension.
Configuration CreateAzure { param ( [String]$VMName = "Demo-VMDSC", [String]$AffinityGroup = "TestAffinity", [String]$AffinityGroupLocation = 'East US', [String]$AffinityGroupDescription = 'Affinity Group', [String]$StorageAccountName = "srcxf01", [String]$ScriptExtensionsFiles = 'dscrepo1', [String]$ServiceName = "TestDSCService", [String]$ServiceDescription = 'Demo Service', [PSCredential]$Credential = (Get-Credential) ) Import-DscResource -ModuleName xAzure Node localhost { xAzureSubscription Demotest { Ensure = 'Present' AzureSubscriptionName = '<id>' AzurePublishSettingsFile = 'C:\PowerShell\account.publishsettings' } xAzureAffinityGroup DemotestAffinity { Ensure = 'Present' Name = $AffinityGroup Location = $AffinityGroupLocation Label = $AffinityGroup Description = $AffinityGroupDescription DependsOn = '[xAzureSubscription]Demotest' } xAzureStorageAccount DemotestStorage { Ensure = 'Present' StorageAccountName = $StorageAccountName AffinityGroup = $AffinityGroup Container = $ScriptExtensionsFiles Folder = 'C:\PowerShell\demo-1\ExtensionFiles' Label = $StorageAccountName DependsOn = '[xAzureAffinityGroup]DemotestAffinity' } xAzureService DemotestService { Ensure = 'Present' ServiceName = $ServiceName AffinityGroup = $AffinityGroup Label = $ServiceName Description = $ServiceDescription DependsOn = '[xAzureStorageAccount]DemotestStorage' } xAzureVM DemotestVM { Ensure = 'Present' Name = $VMName ImageName = 'a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-201502.01-en.us-127GB.vhd' ServiceName = $ServiceName StorageAccountName = $StorageAccountName Windows = $True Credential = $Credential InstanceSize = 'Medium' DependsOn = '[xAzureService]DemotestService' } xAzureVMDscConfiguration TestFiles { StorageAccountName = $StorageAccountName ConfigurationPath = 'C:\PowerShell\demo-1\ExtensionFiles\Breizhcamp.ps1' DependsOn = '[xAzureVM]DemotestVM' } xAzureVMDscExtension DSCTest { VMName = $VMName ServiceName = $ServiceName ConfigurationArchive = 'Breizhcamp.ps1.zip' StorageAccountName = $StorageAccountName Configuration = 'NewWebsite' DependsOn = '[xAzureVMDscConfiguration]TestFiles' } } } $ConfigData = @{ AllNodes = @( @{ NodeName = 'localhost' PSDscAllowPlainTextPassword=$true } ) } # Création du fichier MOF sl 'C:\PowerShell\demo-1' CreateAzure -ConfigurationData $ConfigData # Exécution du fichier MOF Start-DscConfiguration -ComputerName 'localhost' -wait -force -verbose -path C:\PowerShell\demo-1\CreateAzure
After a few minutes, your VM is now deployed with the assigned configuration as you can see in your verbose screen
[su_frame align=”center”]
[/su_frame]
Troubleshooting
In order to detect a failure or a success in your deployment, Azure team has provided you a cmdlet for that: Get-AzureVMDscExtensionStatus
The first thing to do is to create an object containing all the VM informations and properties.
$vm = Get-AzureVM -ServiceName TestDSCService -Name Demo-VMDSC
PS C:\ $vm DeploymentName : TestDSCService Name : Demo-VMDSC Label : VM : Microsoft.WindowsAzure.Commands.ServiceManagement.Model.PersistentVM InstanceStatus : ReadyRole IpAddress : InstanceStateDetails : PowerState : Started InstanceErrorCode : InstanceFaultDomain : 0 InstanceName : Demo-VMDSC InstanceUpgradeDomain : 0 InstanceSize : Medium HostName : Demo-VMDSC AvailabilitySetName : DNSName : Status : ReadyRole GuestAgentStatus : Microsoft.WindowsAzure.Commands.ServiceManagement.Model.GuestAgentStatus ResourceExtensionStatusList : {Microsoft.Compute.BGInfo, Microsoft.Powershell.DSC} PublicIPAddress : PublicIPName : PublicIPDomainNameLabel : PublicIPFqdns : {} NetworkInterfaces : {} VirtualNetworkName : ServiceName : TestDSCService OperationDescription : Get-AzureVM OperationId : 0f7789e70ac69c55b311307955f566bd OperationStatus : OK
Once you get it, you just have to pipe $vm to the cmdlet
$vm | Get-AzureVMDscExtensionStatus
And you will get some useful informations.
ServiceName : TestDSCService Name : Demo-VMDSC Status : Success StatusCode : 1 Timestamp : 5/11/2015 9:13:48 AM StatusMessage : DSC configuration was applied successfully. DscConfigurationLog : {Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'., An LCM method call arrived from computer DEMO-VMDSC with user sid S-1-5-18., [DEMO-VMDSC]: LCM: [ Start Set ], [DEMO-VMDSC]: LCM: [ Start Resource ] [[WindowsFeature]IIS]...}
Note that Status is Success and DscConfigurationLog contains all the verbose messages from LCM!
($vm | Get-AzureVMDscExtensionStatus).DscConfigurationLog
Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'. An LCM method call arrived from computer DEMO-VMDSC with user sid S-1-5-18. [DEMO-VMDSC]: LCM: [ Start Set ] [DEMO-VMDSC]: LCM: [ Start Resource ] [[WindowsFeature]IIS] [DEMO-VMDSC]: LCM: [ Start Test ] [[WindowsFeature]IIS] [DEMO-VMDSC]: [[WindowsFeature]IIS] The operation 'Get-WindowsFeature' started: Web-Server [DEMO-VMDSC]: [[WindowsFeature]IIS] The operation 'Get-WindowsFeature' succeeded: Web-Server [DEMO-VMDSC]: LCM: [ End Test ] [[WindowsFeature]IIS] in 47.5130 seconds. [DEMO-VMDSC]: LCM: [ Start Set ] [[WindowsFeature]IIS] [DEMO-VMDSC]: [[WindowsFeature]IIS] Installation started... [DEMO-VMDSC]: [[WindowsFeature]IIS] Continue with installation? [DEMO-VMDSC]: [[WindowsFeature]IIS] Prerequisite processing started... [DEMO-VMDSC]: [[WindowsFeature]IIS] Prerequisite processing succeeded. [DEMO-VMDSC]: [[WindowsFeature]IIS] Installation succeeded. [DEMO-VMDSC]: [[WindowsFeature]IIS] successfully installed the feature Web-Server [DEMO-VMDSC]: LCM: [ End Set ] [[WindowsFeature]IIS] in 176.2730 seconds. [DEMO-VMDSC]: LCM: [ End Resource ] [[WindowsFeature]IIS] [DEMO-VMDSC]: LCM: [ Start Resource ] [[WindowsFeature]AspNet45] [DEMO-VMDSC]: LCM: [ Start Test ] [[WindowsFeature]AspNet45] [DEMO-VMDSC]: [[WindowsFeature]AspNet45] The operation 'Get-WindowsFeature' started: Web-Asp-Net45 [DEMO-VMDSC]: [[WindowsFeature]AspNet45] The operation 'Get-WindowsFeature' succeeded: Web-Asp-Net45 [DEMO-VMDSC]: LCM: [ End Test ] [[WindowsFeature]AspNet45] in 0.7660 seconds. [DEMO-VMDSC]: LCM: [ Start Set ] [[WindowsFeature]AspNet45] [DEMO-VMDSC]: [[WindowsFeature]AspNet45] Installation started... [DEMO-VMDSC]: [[WindowsFeature]AspNet45] Continue with installation? [DEMO-VMDSC]: [[WindowsFeature]AspNet45] Prerequisite processing started... [DEMO-VMDSC]: [[WindowsFeature]AspNet45] Prerequisite processing succeeded. [DEMO-VMDSC]: [[WindowsFeature]AspNet45] Installation succeeded. [DEMO-VMDSC]: [[WindowsFeature]AspNet45] successfully installed the feature Web-Asp-Net45 [DEMO-VMDSC]: LCM: [ End Set ] [[WindowsFeature]AspNet45] in 108.0200 seconds. [DEMO-VMDSC]: LCM: [ End Resource ] [[WindowsFeature]AspNet45] [DEMO-VMDSC]: LCM: [ End Set ] [DEMO-VMDSC]: LCM: [ End Set ] in 341.4930 seconds. Operation 'Invoke CimMethod' complete. Time taken for configuration job to complete is 345.504 seconds
If you got an error in this message you can also log on your VM and check C:\WindowsAzure\Logs
Set-Location C:\WindowsAzure\Logs\Plugins\Microsoft.Powershell.DSC\1.9.0.0
[su_frame align=”center”][/su_frame]
The ones interesting are DscExtensionHandler.* files. If you open the last one (which is the one you applied with your script) you’ll see that everything is here to help you debug.
Get-Content .\DscExtensionHandler.0.20150511-090544.log
VERBOSE: [2015-05-11T09:06:08] File lock does not exist: begin processing VERBOSE: [2015-05-11T09:06:09] File C:\Packages\Plugins\Microsoft.Powershell.DSC\1.9.0.0\bin\..\DSCWork\1-InProgress.Install.dsc exists; install in progress. VERBOSE: [2015-05-11T09:06:09] Installing DSC Extension... VERBOSE: [2015-05-11T09:06:09] Reading handler environment from C:\Packages\Plugins\Microsoft.Powershell.DSC\1.9.0.0\bin\..\HandlerEnvironment.jsonVERBOSE: [2015-05-11T09:06:11] Reading handler settings from C:\Packages\Plugins\Microsoft.Powershell.DSC\1.9.0.0\RuntimeSettings\0.settings VERBOSE: [2015-05-11T09:06:19] Retrieving WMF download information... VERBOSE: [2015-05-11T09:06:19] WMF Version: 5.0 VERBOSE: [2015-05-11T09:06:19] OS Version : 6.2 VERBOSE: [2015-05-11T09:06:19] Server OS : True VERBOSE: [2015-05-11T09:06:19] 64-bit OS : True VERBOSE: [2015-05-11T09:06:19] Verifying that WMF (KB3055377) is installed... VERBOSE: [2015-05-11T09:06:25] WMF is already installed. VERBOSE: [2015-05-11T09:06:25] Enabling PowerShell Remoting... VERBOSE: [2015-05-11T09:06:25] Setting up network connections as private VERBOSE: [2015-05-11T09:07:04] Install completed; creating C:\Packages\Plugins\Microsoft.Powershell.DSC\1.9.0.0\bin\..\DSCWork\2-Completed.Install.dsc. VERBOSE: [2015-05-11T09:07:04] File C:\Packages\Plugins\Microsoft.Powershell.DSC\1.9.0.0\bin\..\DSCWork\2-Completed.Install.dsc exists; invoking extension handler... VERBOSE: [2015-05-11T09:07:06] Applying DSC configuration: VERBOSE: [2015-05-11T09:07:06] Sequence Number: 0 VERBOSE: [2015-05-11T09:07:06] Configuration Package URL: https://srcxf01.blob.core.windows.net/windows-powershell-dsc/Breizhcamp.ps1.zip VERBOSE: [2015-05-11T09:07:06] ModuleSource: VERBOSE: [2015-05-11T09:07:06] Configuration Module Version: VERBOSE: [2015-05-11T09:07:06] Configuration Container: Breizhcamp.ps1 VERBOSE: [2015-05-11T09:07:06] Configuration Function: NewWebsite (0 arguments) VERBOSE: [2015-05-11T09:07:07] Configuration Data URL: VERBOSE: [2015-05-11T09:07:07] Certificate Thumbprint: B4BDD772A54E1C3C438EADEBA77FD0C6F635C769 VERBOSE: [2015-05-11T09:07:07] Creating Working directory: C:\Packages\Plugins\Microsoft.Powershell.DSC\1.9.0.0\bin\..\DSCWork\Breizhcamp.ps1.0 VERBOSE: [2015-05-11T09:07:07] Downloading configuration package VERBOSE: [2015-05-11T09:07:07] Downloading https://srcxf01.blob.core.windows.net/windows-powershell-dsc/Breizhcamp.ps1.zip?sv=2014-02-14&sr=b&sig=TQNDUDE1sTdFezlnOcLpASdQ rEEkCFXd6kFKyXUzw0g%3D&se=2015-05-11T09%3A44%3A32Z&sp=rd to C:\Packages\Plugins\Microsoft.Powershell.DSC\1.9.0.0\bin\..\DSCWork\Breizhcamp.ps1.0\Breizhcamp.ps1.zip VERBOSE: [2015-05-11T09:07:08] Extracting Breizhcamp.ps1.zip VERBOSE: [2015-05-11T09:07:08] Installing custom DSC resource modules to C:\Program Files\WindowsPowerShell\Modules VERBOSE: [2015-05-11T09:07:08] Installing custom DSC resource module xWebAdministration VERBOSE: [2015-05-11T09:07:08] Applying DSC configuration Breizhcamp.ps1\NewWebsite VERBOSE: [2015-05-11T09:07:09] Writing handler status to C:\Packages\Plugins\Microsoft.Powershell.DSC\1.9.0.0\Status\0.status VERBOSE: [2015-05-11T09:07:09] Looking for the definition of the configuration function. VERBOSE: [2015-05-11T09:07:09] Import script as new module:C:\Packages\Plugins\Microsoft.Powershell.DSC\1.9.0.0\bin\..\DSCWork\Breizhcamp.ps1.0\Breizhcamp.ps1 VERBOSE: [2015-05-11T09:07:10] Preparing configuration arguments. VERBOSE: [2015-05-11T09:07:10] Preparing configuration data. VERBOSE: [2015-05-11T09:07:10] Creating MOF files. VERBOSE: [2015-05-11T09:07:10] Executing the configuration function to generate the MOF files. WARNING: The configuration 'NewWebsite' is loading one or more built-in resources without explicitly importing associated modules. Add Import-DscResource -ModuleName 'PSDesiredStateConfiguration' to your configuration to avoid this message. VERBOSE: [2015-05-11T09:07:18] Executing Start-DscConfiguration... VERBOSE: [2015-05-11T09:07:31] Writing handler status to C:\Packages\Plugins\Microsoft.Powershell.DSC\1.9.0.0\Status\0.status
You can see every action and have a better understanding about how DSC Extension works behind the scene!
 Pester validation
In order to implement this script in your continuous delivery process, here is a Pester script to validate your deployed infrastructure.
Describe "Validate your Azure Virtual Machine creation and all the environnement" { $Certfile = 'C:\BreizhCamp\BreizhCamp.publishsettings' $StorageName = 'srcxf01' $ContainerName = 'dscrepo1' $Subscription = '<sid>' $ServiceName = "TestDSCService" Import-AzurePublishSettingsFile -PublishSettingsFile $Certfile Select-AzureSubscription -SubscriptionName $Subscription | Set-AzureSubscription Set-AzureSubscription -SubscriptionName $subscription -CurrentStorageAccountName $StorageName $Subscription = (Get-AzureSubscription | ? SubscriptionName -eq $Subscription ) $StorageAccount = Get-AzureStorageAccount -StorageAccountName $StorageName $AffinityGroup = Get-AzureAffinityGroup -Name $StorageAccount.AffinityGroup $key = Get-AzureStorageKey -StorageAccountName $StorageName $Blob = Get-AzureStorageBlob -Context (New-AzureStorageContext -StorageAccountKey $key.Primary -StorageAccountName $StorageName) -Container $ContainerName $vm = Get-AzureVM -ServiceName $ServiceName -Name $VMName $DscExtension = $vm | Get-AzureVMDscExtensionStatus $AzureService = Get-AzureService -ServiceName $ServiceName It "Publish Settings file exists" { $Certfile | Should Exist } It "Azure Subscription exists" { $subscription | Should Not be $null } It "Current Storage account Affinty Group is TestAffinity" { $StorageAccount.AffinityGroup | Should be "TestAffinity" } It "Current Storage account is located on East US" { $AffinityGroup.Location | Should be "East US" } It "Current Storage account configured to srcxf01" { $subscription.CurrentStorageAccountName | Should be "srcxf01" } It "Service is created" { $AzureService.Status | Should be "Created" } It "Service Affinity group is correctly setted to TestAffinity" { $AzureService.AffinityGroup | Should be "TestAffinity" } It "Container Breizhcamp.ps1 exists on blob" { $blob.Name | Should be "Breizhcamp.ps1" } It "VM name is Demo-VMDSC" { $vm.Name | Should be "Demo-VMDSC" } It "VM Role Size is Medium" { $vm.vm.RoleSize | Should be "Medium" } It "VM is correctly created and started" { $vm.PowerState | Should be "Started" } It "VM is correctly deployed in the good service" { $vm.ServiceName | Should be "TestDSCService" } It "VM Operating System is good" { $vm.vm.OSVirtualHardDisk.SourceImageName | Should be "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-Datacenter-201502.01-en.us-127GB.vhd" } It "VM should have 2 Endpoints" { $vm.vm.ConfigurationSets.InputEndpoints.Count | Should be 2 } It "VM should have WinRM endpoint" { ($vm.vm.ConfigurationSets.InputEndpoints | ? { $_.LocalPort -eq 5986 }).Name | Should be "PowerShell" } It "VM should have RemoteDesktop endpoint" { ($vm.vm.ConfigurationSets.InputEndpoints | ? { $_.LocalPort -eq 3389 }).Name | Should be "RemoteDesktop" } It "VM iDsc Extension is installed" { ($vm.ResourceExtensionStatusList | ? { $_.HandlerName -eq "Microsoft.Powershell.DSC" }).status | Should be "Ready" } It "Desired State Configuration is applied" { $DscExtension.Status | Should be "Success" } }
[su_frame align=”center”][/su_frame]
Hope this’ll help you!
See you
Do you know if it can be used with linux hosts? 🙂
Hi,
Currently this is not possible, and i don’t know if this is planned…
Ok merci 😀
You can now use Azure Automation DSC with Linux hosts if you want 🙂