Chocolatey, PowerShell DSC and Azure IAAS - Automating dev box creation

Hi,

So back in 2013 I wrote a post on automating the creation of a Virtual Machine, and installation of all my loved bits of software, using Chocolaty and Remote Powershell. Well things have moved on in the Azure IAAS world and we have a nice new way to automate installation and configuration of VM’s.

PowerShell DSC (desired state configuration) gives you a nice declarative way to define the setup of your machine. It also allows you to write custom modules to extend its functionality, which is just what I’ve done for Chocolatey. It’s here on GitHub.

So now you can add in all the nice apps you want on the box is one simple DSC config, along with windows features etc.

Below is an example of using the cChoco module to install Git on a new Azure VM. I’ve broken down the script into sections with a full version at the bottom.

Brief description of Sections:

  1. This is an example of a simple DSC config that installs IIS on the machine where it runs, for reference.
  2. Pulls down the custom cChoco module from Github, this needs to be copied onto your box so it can be used later.
  3. Creates a DSC config using the module which installs git from Chocolatey. You can add more “cChocoPackageInstaller” nodes, changing the Name parameter to be the package you’d like to install or add “WindowsFeature” nodes to install IIS and other bits.
  4. Takes this DSC config and pushing it up to Azure, ready to apply to my nice new VM.
  5. Create a VM adding in the DSC extension and providing the DSC Config name and file from step 4

Finally at the bottom of the Gist is a full script that will combine all these steps and do some extra checks and goodness.

Happy Automating!

@lawrencegripper

PS. You can check on the install progress through the portal, screenshot below the Gist.

configuration IISInstall
{
node ("localhost")
{
WindowsFeature IIS
{
Ensure = "Present"
Name = "Web-Server"
}
}
}
#NB - If you see issues with Git with note "git : The term 'git' is not recognized as the name of a cmdlet"
# make sure you have git aliased in your powershell environment and installed.
# Line below will do this
#
#$env:path += ";" + (Get-Item "Env:ProgramFiles(x86)").Value + "\Git\bin"
#
# Or you can manually download the resources from https://github.com/PowerShellOrg/cChoco and paste into C:\Program Files\WindowsPowerShell\Modules
# Once you've done this you can comment out the first line 11.
New-Item "C:\Program Files\WindowsPowerShell\Modules\cChoco" -type directory
git clone https://github.com/PowerShellOrg/cChoco/ "C:\Program Files\WindowsPowerShell\Modules\cChoco"
Get-DscResource
Configuration myChocoConfig
{
Import-DscResource -Module cChoco
Node "localhost"
{
LocalConfigurationManager
{
ConfigurationMode = "ApplyAndAutoCorrect"
ConfigurationModeFrequencyMins = 30 #must be a multiple of the RefreshFrequency and how often configuration is checked
}
cChocoInstaller installChoco
{
InstallDir = "c:\choco"
}
cChocoPackageInstaller installGit
{
Name = "git.install"
DependsOn = "[cChocoInstaller]installChoco"
}
}
}
view raw 3-ChocoDSC.ps1 hosted with ❤ by GitHub
Publish-AzureVMDscConfiguration -ConfigurationPath C:\examples\ChocoInstall.ps1
###### ToDos before Running ##############
#Line 3 - Change -name for your VM name
#Line 6 - Change -AdminUsername and -Password
#Line 11 - Change -ServiceName and -Location (if you don't want europe)
####### Notes ############################
#Line 12 -ConfigurationArchive is from file name used in PublishChocoConfig.ps1 script
#Line 12 -ConfigurationName is from DSC config name on Line1 in ChocoDSC.ps1
$vm = New-AzureVMConfig -Name "exampleNameForVM" -InstanceSize Small -ImageName "a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201407.01-en.us-127GB.vhd"
$vm = Add-AzureProvisioningConfig -VM $vm -Windows -AdminUsername "admin_account" -Password "someSuperSecurePa$$w0rd"
$vm = Set-AzureVMDSCExtension -VM $vm -ConfigurationArchive "ChocoInstall.ps1.zip" -ConfigurationName "myChocoConfig"
New-AzureVM -VM $vm -Location "North Europe" -ServiceName "exampleSericeNameChangeMe" -WaitForBoot
#NB - If you see errors relating to storage accounts make sure the default is setup
# also check its in the region that the machine is deploying to, currently "North Europe" on line 90
# Set-AzureSubscription -SubscriptionName "YourSubscriptionName" -CurrentStorageAccountName "StorageAccountName"
$ErrorActionPreference = "Stop"
# Check if Windows Azure Powershell is avaiable
if ((Get-Module -ListAvailable Azure) -eq $null)
{
throw "Windows Azure Powershell not found! Please make sure to install them"
}
#Install the cChoco DSC Module from GitHub
#
# NB - If you see issues with Git with note "git : The term 'git' is not recognized as the name of a cmdlet"
# make sure you have git aliased in your powershell environment and installed.
# Line below will do this
#
# $env:path += ";" + (Get-Item "Env:ProgramFiles(x86)").Value + "\Git\bin"
#
# Or you can manually download the resources from https://github.com/PowerShellOrg/cChoco and paste into C:\Program Files\WindowsPowerShell\Modules
# Once you've done this you can comment out the first line 11.
if (-not (Test-Path "C:\Program Files\WindowsPowerShell\Modules\cChoco"))
{
New-Item "C:\Program Files\WindowsPowerShell\Modules\cChoco" -type directory
git clone https://github.com/PowerShellOrg/cChoco/ "C:\Program Files\WindowsPowerShell\Modules\cChoco"
Get-DscResource
}
#Create a DSC Config to install Git on our new machine
$dscConfig = @'
Configuration myChocoConfig
{
Import-DscResource -Module cChoco
Node "localhost"
{
LocalConfigurationManager
{
ConfigurationMode = "ApplyAndAutoCorrect"
ConfigurationModeFrequencyMins = 30 #must be a multiple of the RefreshFrequency and how often configuration is checked
}
cChocoInstaller installChoco
{
InstallDir = "c:\choco"
}
cChocoPackageInstaller installGit
{
Name = "git.install"
DependsOn = "[cChocoInstaller]installChoco"
}
}
}
'@
#Test the config
Invoke-Expression $dscConfig
myChocoConfig
#Save to ps1 file for upload
$dscConfig | out-file ".\ChocoInstall.ps1"
#Get latest Server 2012 Image - This is used to create the VM
$imageFilter = "Windows Server 2012 R2 Datacenter"
$imageList = Get-AzureVMImage
$imageListFiltered = $imageList |
Where-Object { `
($_.PublisherName -ilike "Microsoft*" -and `
$_.ImageFamily -ilike $imageFilter ) }
$imageList = $imageListFiltered |
Sort-Object -Unique -Descending -Property ImageFamily |
Sort-Object -Descending -Property PublishedDate
$image = $imageList | Select-Object -First(1)
#Publish the DSC config to Azure
Publish-AzureVMDscConfiguration -ConfigurationPath .\ChocoInstall.ps1 -Force
#Setup the VM config
$serviceName = exampleServiceName
$vmName = exampleVMName
$vm = New-AzureVMConfig -Name $vmName -InstanceSize Small -ImageName $image.ImageName
$vm = Add-AzureProvisioningConfig -VM $vm -Windows -AdminUsername "demodude" -Password "demodude123$"
#Add DSC extension to VM
$vm = Set-AzureVMDSCExtension -VM $vm -ConfigurationArchive "ChocoInstall.ps1.zip" -ConfigurationName "myChocoConfig"
#Create the VM
New-AzureVM -VM $vm -Location "North Europe" -ServiceName $serviceName -WaitForBoot
#Start RDP to the box (note some of the DSC config might still be underway)
Get-AzureRemoteDesktopFile -ServiceName $serviceName -Name $vmName –Launch

Review Progress in Preview Portal:

DSCStatus