AzureRM to be retired on February 29, 2024

Just so you know,

  • After February 29, 2024, AzureRM PowerShell modules will continue to be available to customers, however will not be supported by Microsoft. 
  • Know your options for updating your scripts from AzureRM to Az PowerShell modules.
  • To automatically update scripts, reference this quickstart guide.
  • May want to upgrade sooner than later since Az PowerShell module runs cross-platform and supports all Azure services including Azure authentication mechanisms.

Disabling/Enabling Azure VM BootDiagnostic Using PowerShell

Despite a simple operation, apply the following sample statements to your environment if experiencing an issue in changing an Azure VM’s BootDiagnostic setting.

ISSUE for

  • Not able to disable/enable BootDiagoistic of an Azure VM

HOW-TO

References:

SAMSPLE STATEMENTS

The same process applies to enabling BootDiagnostic by specifying a vm object with the associated resource group and an intended storage account in step 4.

<# 
Disabling Azure VM BootDiagnostic Using PowerShell 

The following illustrates the process to disable VM BootDiagnostic. 
The statements are intended to be executed manually and in sequence. 
#>
 
# 1. Log in Azure and set the context, as appropriate
Connect-AzAccountstep 4
Get-AzContext
Set-AzContext -Subscription '????' -Tenant '????'
 
# 2. Specify a target VM 
$vmName = 'your vm name'
$vmRG = 'the resource group name of the vm'
 
# 3. Check the current BootDiagnostics status
($VM = Get-AzVM -ResourceGroupName $vmRG -Name $vmName).DiagnosticsProfile.BootDiagnostics
 
# 4. Disable BootDiagnostic of the VM
Set-AzVMBootDiagnostic -VM $VM -Disable
 
# 5. Update the VM settings
Update-AzVM -ResourceGroupName $vmRG -VM $VM
 
# 6. Check the current BootDiagnostics status and verify the change made
($VM = Get-AzVM -ResourceGroupName $vmRG -Name $vmName).DiagnosticsProfile.BootDiagnostics
 
# Notice it may take a few minutes for azure portal to reflect 
# the changes made to BootDiagnostic.
 

SAMPLE SESSION

  • Examine status before making a change

BootDiagnostic Settig

  • Disable BootDiagnistic

  • Examine status after making the change

Finding an Azure VM Image Sku Using PowerShell

<#

The function, azure-vm-image-sku, returns the sku of a user-selected 
Azure VM image interactively. It calls the function, pick-one-item, 
which accepts an item-list and returns a selected item interactively.

This script is for demonstrating and learning Azure and PowerShell. 
The code is not optimized and does not handle all error messages. 

Usage:

# Get a sku in the default text mode
azure-vm-image-sku 

# Get a sku with GUI
azure-vm-image-sku -gui $true

# Get a sku with optional switches
azure-vm-image-sku `
  -region 'targetAzureRegion' `
  -publisher 'targetPublisherName' `
  -offer 'targetOffer' `
  -gui $true

Examples: 

azure-vm-image-sku -region 'south central us' -gui $true

azure-vm-image-sku `
  -region 'south central us' `
  -publisher 'microsoftwindowsserver'

azure-vm-image-sku `
  -region 'south central us' `
  -publisher 'microsoftwindowsserver' `
  -offer 'windowsserver' 

© 2020 Yung Chou. All Rights Reserved.

#>

function pick-one-item {

  param (
    [array  ]$thisList = @('East Asia','South Central US', 'West Europe', 'UAE North', 'South Afraica North'), 
    [string ]$itemDescription ='Azure Region', 
    [boolean]$gui = $false
    )

  if ($gui) {

    $thisOne = $thisList | Out-GridView -Title "$itemDescription List" -PassThru
  
  } else {
  
    if ($thisList.count -eq 1) { $thisOne = $thisList[0] 
    } else {
      
      $i=1; $tempList = @()

      foreach ( $item in $thisList )  {
          $tempList+="`n$i.`t$item" 
          $i++
      }

      do {
          write-host "`nHere's the $itemDescription list `n$tempList"
          $thePick = Read-Host "`nWhich $itemDEscription"
      } while(1..$tempList.length -notcontains $thePick)

      $thisOne = $thisList[($thePick-1)]
    }
  }

  write-host "$(get-date -f T) - Selecting '$thisOne' from the $itemDescription list " -f green -b black

  return $thisOne
  
}

function azure-vm-image-sku {

  param (

    [boolean]$gui = $false, 
    
    [string]$region = (pick-one-item `
      -thisList (Get-AzLocation).DisplayName `
      -itemDescription "Azure region" `
      -gui $gui ),

    [string]$publisher = (pick-one-item `
      -thisList (Get-AzVMImagePublisher -Location $region).PublisherName `
      -itemDescription "Azure $region publisher" `
      -gui $gui ),

    [string]$offer = (pick-one-item `
      -thisList (Get-AzVMImageOffer -Location $region -PublisherName $publisher).offer `
      -itemDescription "Azure $region $publisher's Offer" `
      -gui $gui ),  

    [string]$itemDescription = "Azure $region $publisher $offer Sku"

    )

  return $sku = (pick-one-item `
    -thisList (Get-AzVMImageSku -Location $region -PublisherName $publisher -Offer $offer).skus `
    -itemDescription $itemDescription `
    -gui $gui )

}

Creating Azure Usage and Quota Report Using PowerShell


write-host "

This script, based on the original script published in the article,

Report Azure resource usage with PowerShell
https://4sysops.com/archives/report-azure-resource-usage-with-powershell/,

displays interactively the Azure compute, storage, 
and network quota and usage of an examined region relevant to 
an Azure subscription. It also generates a text file accordingly. 

© 2020 Yung Chou. All Rights Reserved.

"

#region [Customization]

$region="uksouth"

#endregion

Connect-AzAccount

#region [Needed only if an account owns multiple subscriptions]

# Set the context for subsequent operations
$context = (Get-AzSubscription | Out-GridView -Title 'Set subscription context' -PassThru)
Set-AzContext -Subscription $context | Out-Null
write-host "Azure context set for the subscription, `n$((Get-AzContext).Name)" -f green

#endregion

#region [DO NOT CHANGE]

($vm = Get-AzVMUsage -Location $region `
| select @{label='ResourceType';expression={$_.name.LocalizedValue}}, currentvalue, limit) `
| Out-GridView -Title "Azure $region Region Compute Quota & Usage"

($storage = Get-AzStorageUsage -Location $region `
| select @{label='ResourceType';expression={$_.name}}, currentvalue, limit) `
| Out-GridView -Title "Azure $region Region Storage Account Quota & Usage"

($network = Get-AzNetworkUsage -Location $region `
| select @{label='ResourceType';expression={$_.resourcetype}}, currentvalue, limit) `
| Out-GridView -Title "Azure $region Network Quota & Usage"

$when=get-date -format 'yyyyMMdd-hhmm'

($usage = @("Azure $region Region Quota and usage, as of $when",$vm,"`n",$storage,"`n",$network) | ft) `
>> "usage-$region-$when.txt"

#endregion [DO NTO CHANGE]

Creating Azure Managed Disk with VHD Using PowerShell


#region [CREATE MANAGED DISK WITH VHD]

write-host "
------------------------------------------------------------

This script is based on the following reference and for
learning Azure and PowerShell. I have made changes to the
original scrtip for clarity and portability.

Ref: Create a managed disk from a VHD file
https://docs.microsoft.com/en-us/azure/virtual-machines/scripts/virtual-machines-windows-powershell-sample-create-managed-disk-from-vhd

Recommend manually running the script statement by
statement in cloud shell.

© 2020 Yung Chou. All Rights Reserved.

------------------------------------------------------------
"

#region [CUSTOMIZATION]

#region [Needed only if an account owns multiple subscriptions]

Get-AzSubscription | Out-GridView  # Copy the target subscription name

# Set the context for subsequent operations
$context = (Get-AzSubscription | Out-GridView -Title 'Set subscription context' -PassThru)
Set-AzContext -Subscription $context | Out-Null
write-host "Azure context set for the subscription, `n$((Get-AzContext).Name)" -f green

#endregion

$sourceVhdStorageAccountResourceId = '/subscriptions/…/StorageAccounts/'
$sourceVhdUri = 'https://.../.vhd'

#Get-AzLocation
$sourceVhdLoc = 'centralus'

$mngedDiskRgName ="da-mnged-$(get-date -format 'mmss')"
#$mngedDiskRgName ='dnd-mnged'

#Provide the name of a to-be-created Managed Disk
$mngedDiskName = 'myMngedDisk'
$mngedStorageType = 'Premium_LRS' # Premium_LRS,Standard_LRS,Standard_ZRS
$mngedDiskSize = '128' # In GB greater than the source VHD file size

#endregion

if (($existingRG = (Get-AzResourceGroup | Where {$_.ResourceGroupName -eq $mngedDiskRgName})) -eq $Null) {
write-host "Resource group, $mngedDiskRgName, not found, creating it" -f y
New-AzResourceGroup -Name $mngedDiskRgName -Location $mngedDiskLoc
} else {
write-host "Using this resource group, $mngedDiskRgName, for the managed disk, $mngedDiskName" -f y
}

$diskConfig = New-AzDiskConfig `
-AccountType $mngedStorageType `
-Location $sourceVhdLoc `
-CreateOption Import `
-StorageAccountId $sourceVhdStorageAccountResourceId `
-SourceUri $sourceVhdUri

New-AzDisk `
-Disk $diskConfig `
-ResourceGroupName $mngedDiskRgName `
-DiskName $mngedDiskName `
-Verbose

#endregion [CREATE MANAGED DISK WITH VHD]

#region [CLean up]
# Remove-AzResourceGroup -Name $mngedDiskRgName -Force -AsJob
#endregion

Deploying Azure VM with Diagnostics Extension and Boot Diagnostics

This is a sample script for deploying an Azure VM with Diagnostics Extension and Boot Diagnostics, while each in a different resource group. The intent is to clearly illustrate the process with required operations, while paying minimal effort for code optimization.

Ideally an Azure VM, Diagnostic Extension, and Boot Diagnostics are to be deployed with the same resource group. However in production, it may be necessary to organize them into individual resource groups for standardization, which is what this script demonstrates.

The script can be run as it is. Or simply make changes in customization section and leave the rest in place. For VM Diagnostic Extension, the configuration file should be placed where the script is. Or update the variable, $diagnosticsConfigPath, accordingly. This script uses Storage Account Key for access which allows the storage account with a subscription different from that deploys the VM. A sample configuration file, diagnostics_publicconfig_NoStorageAccount.xml, is available  and notice there is no <StorageAccount> element specified in this file.

Here’s the user experience up to finishing the [Deploying] section in the script. By default, an Azure VM is deployed with Boot Diagnostic enabled. The script upon a VM deployment changes and disables the Boot Diagnostic of the VM. For the following sample run, it took 3 minutes and 58 seconds.

Deploying Azure VM and setting Boot Diagnostics as disabled Deploying Azure VM and setting Boot Diagnostics as disabled

Now with an Azure VM in place, the script adds VM Diagnostic Extension, followed by enabling Boot Diagnostics. Herr either extension uses a storage account in a resource group different form the VM’s. So this script creates 3 resource groups for: a VM itself, and the Diagnostics Extension and the Boot Diagnostics of the VM.

VM, Diagnostics, and Boot Diagnostics deployed with individual resource groups

VM, Diagnostics, and Boot Diagnostics deployed with individual resource groups


write-host "
---------------------------------------------------------

This is a sample script for deploying an Azure VM
with Diagnostics Extension and Boot Diagnostics,
while each in a different resource group.

The intent is to clearly illustrate the process with
required operations, while paying minimal effort for
code optimization.

Ideally an Azure VM, Diagnostic Extension, and Boot Diagnostics
are to be deployed with the same resource group. However
in production, it may be necessary to organize them into
individual resource groups for standardization,
which is what this script demonstrates.

The script can be run as it is. Or simply make changes
in customization section, while leave the rest in place.
For VM Diagnostic Extension, the configuration file should
be placed where thi script is. Or update the variable,
$diagnosticsConfigPath, accordingly. This script uses a
Storage Account Key for access. This configuration allows
the storage account with a subscription different from that
deploys the VM. A sample configuration file,
diagnostics_publicconfig_NoStorageAccount.xml, is available at

https://1drv.ms/u/s!AuraBlxqDFRshVSl0IpWcsjRQkUX?e=3CGcgq

and notice there is no <StorageAccount> element specified in this file.

© 2020 Yung Chou. All Rights Reserved.

---------------------------------------------------------
"

Disconnect-AzAccount; Connect-AzAccount
# If multipel subscription
# Set-AzContext -SubscriptionId "xxxx-xxxx-xxxx-xxxx"

#region [Customization]

$cust=@{
initial='yc'
;region='southcentralus'
}

$diagnosticsConfigPath='diagnostics_publicconfig_NoStorageAccount.xml'

#region [vm admin credentials]

# 1.To hard-code
$cust+=@{
vmAdmin ='changeMe'
;vmAdminPwd='forDemoOnly!'
}
$vmAdmPwd=ConvertTo-SecureString $cust.vmAdminPwd -AsPlainText -Force
$vmAdmCred=New-Object System.Management.Automation.PSCredential ($cust.vmAdmin, $vmAdmPwd);
#>

# 2. Or interactively
#$vmAdminCred = Get-Credential -Message "Enter the VM Admin credentials."

#endregion

$tag=$cust.initial+(get-date -format 'mmss')
Write-host "`nSession ID = $tag" -f y

# Variables for common values
$vmRGName=$tag+'-RG'
$loc=$cust.region
$vmName=$tag+'vm'

$deployment=@{
vmSize='Standard_B2ms'
;dataDiskSzieInGB=5
;publisher='MicrosoftWindowsServer'
;offer='WindowsServer'
;sku='2016-Datacenter'
;version='latest'
;vnetAddSpace='192.168.0.0/16'
;subnetAddSpace='192.168.1.0/24'
}

#endregion

#region [Deployment Preping]

# Create a resource group
New-AzResourceGroup -Name $vmRGName -Location $loc
# Remove-AzResourceGroup -Name $vmRGName -AsJob

# Create a subnet configuration
$subnetConfig = `
New-AzVirtualNetworkSubnetConfig `
-Name 'default' `
-AddressPrefix ($deployment.subnetAddSpace) `
-WarningAction 'SilentlyContinue'

# Create a virtual network
$vnet = `
New-AzVirtualNetwork `
-ResourceGroupName $vmRGName `
-Location $loc `
-Name "$tag-vnet" `
-AddressPrefix $deployment.vnetAddSpace `
-Subnet $subnetConfig

# Create a public IP address and specify a DNS name
$pip = `
New-AzPublicIpAddress `
-ResourceGroupName $vmRGName `
-Location $loc `
-Name "$vmName-pip" `
-AllocationMethod Static `
-IdleTimeoutInMinutes 4

# Create an inbound network security group rule for port 3389
$nsgRuleRDP = `
New-AzNetworkSecurityRuleConfig `
-Name "$vmName-rdp" `
-Protocol Tcp `
-Direction Inbound `
-Priority 1000 `
-SourceAddressPrefix * `
-SourcePortRange * `
-DestinationAddressPrefix * `
-DestinationPortRange 3389 `
-Access Allow

# Create an inbound network security group rule for port 80,443
$nsgRuleHTTP = `
New-AzNetworkSecurityRuleConfig `
-Name "$vmName-http" -Protocol Tcp `
-Direction Inbound `
-Priority 1010 `
-SourceAddressPrefix * `
-SourcePortRange * `
-DestinationAddressPrefix * `
-DestinationPortRange 80,443 `
-Access Allow

$nsg= `
New-AzNetworkSecurityGroup `
-ResourceGroupName $vmRGName `
-Location $loc `
-Name "$vmName-nsg" `
-SecurityRules $nsgRuleRDP, $nsgRuleHTTP `
-Force

# Create a virtual network card and associate with public IP address and NSG
$nic = `
New-AzNetworkInterface `
-Name "$vmName-nic" `
-ResourceGroupName $vmRGName `
-Location $loc `
-SubnetId $vnet.Subnets[0].Id `
-PublicIpAddressId $pip.Id `
-NetworkSecurityGroupId $nsg.Id

$vmConfig = `
New-AzVMConfig `
-VMName $vmName `
-VMSize $deployment.vmSize `
| Set-AzVMOperatingSystem `
-Windows `
-ComputerName $vmName `
-Credential $vmAdmCred `
| Set-AzVMSourceImage `
-PublisherName $deployment.publisher `
-Offer $deployment.offer `
-Skus $deployment.sku `
-Version $deployment.version `
| Add-AzVMNetworkInterface `
-Id $nic.Id

#endregion

#region [Deploying]

$StopWatch = New-Object -TypeName System.Diagnostics.Stopwatch; $stopwatch.start()
write-host "`nDeploying the vm, $vmName, to $loc...`n" -f y

$vmStatus = `
New-AzVM `
-ResourceGroupName $vmRGName `
-Location $loc `
-VM $vmConfig `
-WarningAction 'SilentlyContinue' `
-Verbose

Set-AzVMBgInfoExtension `
-ResourceGroupName $vmRGName `
-VMName $vmName `
-Name 'bginfo'

$vm = Get-AzVM -ResourceGroupName $vmRGName -Name $vmName
# Set by default not to enable boot diagnostic
Set-AzVMBootDiagnostic `
-VM $vm `
-Disable `
| Update-AzVM
write-host "`nSet the vm, $vmName, with BootDiagnostic 'Disabled'`n" -f y

write-host '[Deployment Elapsed Time]' -f y
$stopwatch.stop(); $stopwatch.elapsed

#endregion

#region [Set VM Diagnostic Extension]
<# If using a diagnostics storage account name for the VM Diagnostic Extension, the storage account must be in the same subscription as the virtual machine. If the diagnostics storage account is in a different subscription than the virtual machine's, then enable sending diagnostics data to that storage account by explicitly specifying its name and key. #>
$vmDiagRGName=$tag+'vmDiag-RG'
$vmDiagStorageName=$tag+'vmdiagstore'

New-AzResourceGroup -Name $vmDiagRGName -Location $loc
#Remove-AzResourceGroup -Name $vmDiagRGName -AsJob

New-AzStorageAccount `
-ResourceGroupName $vmDiagRGName `
-AccountName $vmDiagStorageName `
-Location $loc `
-SkuName Standard_LRS

Set-AzVMDiagnosticsExtension `
-ResourceGroupName $vmRGName `
-VMName $vmName `
-DiagnosticsConfigurationPath $diagnosticsConfigPath `
-StorageAccountName $vmDiagStorageName `
-StorageAccountKey (
Get-AzStorageAccountKey `
-ResourceGroupName $vmDiagRGName `
-AccountName $vmDiagStorageName
).Value[0] `
-WarningAction 'SilentlyContinue'

$vmExtDiag = Get-AzVMDiagnosticsExtension -ResourceGroupName $vmRGName -VMName $vmName

#endregion

#region [Enable Boot Diagnostic]

# The resource group and the storage account are
# different from the vm's.

$vmBootDiagRGName=$tag+'bootDiag-RG'
$bootDiagStorageName=$tag+'bootdiagstore'

New-AzResourceGroup -Name $vmBootDiagRGName -Location $loc
#Remove-AzResourceGroup -Name $vmBootDiagRGName -AsJob

New-AzStorageAccount `
-ResourceGroupName $vmBootDiagRGName `
-AccountName $bootDiagStorageName `
-Location $loc `
-SkuName Standard_LRS

Set-AzVMBootDiagnostic `
-Enable `
-VM $vm `
-ResourceGroupName $vmBootDiagRGName `
-StorageAccountName $bootDiagStorageName `
| Update-AzVM

#endregion

#region [Session Summary]

($RGs = Get-AzResourceGroup | Where ResourceGroupName -like "$tag*") `
| ft ResourceGroupName, Location

($vms = Get-AzVM| Where ResourceGroupName -like "$tag*") `
| ft ResourceGroupName, Location, Name

($SAs = Get-AzStorageAccount | Where ResourceGroupName -like "$tag*") `
| ft ResourceGroupName, Location, StorageAccountName

#endregion

<# [Clean Up] 
Remove-AzResourceGroup -Name $vmRGName -AsJob 
Remove-AzResourceGroup -Name $vmDiagRGName -AsJob 
Remove-AzResourceGroup -Name $vmBootDiagRGName -AsJob 
#>

US TechNet on Tour | Cloud Infrastructure – Resource Page

This wave of TechNet events focuses on Azure (IaaS) V2, namely Azure Resource Manager or ARM. It is part of IT Innovation series currently delivered in US metros and many other geo-locations in the spring of 2016. For those outside of the US, go to http://aka.ms/ITInnovation to find out events near you. Come and have some serious fun in learning.

imageimage

The presentations, available in PDF format, and the following lab material are included in this zip file.

GitHub repository for Lab Files if using your own machine

If you are not using the hosted virtual machine and are using your own workstation, any custom files the lab instruction call out can be found in a GitHub repository. The repository is located here: https://github.com/AZITCAMP/Labfiles.

Required Software

Description

Steps

Required software will be called out throughout the lab.

  1. Microsoft Azure PowerShell – http://go.microsoft.com/?linkid=9811175&clcid=0x409 (also installs the Web Platform Installer, minimum version 0.9.8 and higher)
  2. Visual Studio Code – https://code.visualstudio.com/
  3. Install GIT at: http://git-scm.com/download/win
  4. GitHub Desktop for Windows – https://desktop.github.com/
  5. Windows Credential Store for Git (if VSCode won’t authenticate with GitHub) – http://gitcredentialstore.codeplex.com/
  6. Iometer – http://sourceforge.net/projects/iometer/

Optional Software

Description

Software

Any additional software that you require will be called out in the lab. The following software may be useful when working with Azure in general.

  1. Remote Server Administration Tools – http://support.microsoft.com/kb/2693643 (Windows 8.1) or http://www.microsoft.com/en-ca/download/details.aspx?id=45520 (Windows 10)
  2. AzCopy – http://aka.ms/downloadazcopy
  3. Azure Storage Explorer – http://azurestorageexplorer.codeplex.com/downloads/get/891668
  4. Microsoft Azure Cross-platform Command Line Tools (installed using the Web Platform Installer)
  5. Visual Studio Community 2015 with Microsoft Azure SDK – 2.8.1 (installed using the Web Platform Installer)
  6. Msysgit – http://msysgit.github.io
  7. PuTTY and PuTTYgen – (Use the Windows Installer) http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
  8. Microsoft Online Services Sign-In Assistant for IT Professionals RTW – http://go.microsoft.com/fwlink/?LinkID=286152
  9. Azure Active Directory Module for Windows PowerShell (64-bit version) – http://go.microsoft.com/fwlink/p/?linkid=236297

Try It Yourself, Application Deployment as a Service with Microsoft Azure PowerShell

In the last few months, I have taken a few opportunities to talk about deploying an application as a service. This is a subject with many aspects in connecting the concepts of cloud computing, application deployment process and IT operations. I find it also encompasses great frequently run routines for automation with Azure PowerShell.

Here I share the material which I have integrated into IaaS workshops I have recently delivered.

  • Part 1 is the user experience which is also supplemented with published videos. (Channel 9)
  • Part 2 highlights the PowerShell scripts I wrote to deploy the sample application. (Channel 9)

http://www.microsoft.com/feeds/omni_external_blogs.js

A Memorandum to IT Pros on Imperative vs. Declarative Scripting Models

One noticeable difference of Azure Infrastructure Services (IaaS) V2 from Azure IaaS V1 (or classic Azure IaaS as I call it) is the employment of  Azure “Resource Group” templates. A resource group not only is a newly introduced artifact in Azure, but denotes a fundamental shift on automating, deploying, and managing IT resources. This change signifies the arrival of a declarative programming/scripting model for the better. I will walk through an application deployment with Azure resource group templates in an upcoming post. In this memo, the focus is on distinguishing these two programming/scripting models.

Imperative vs. Declarative

Traditionally, within a logical unit of work (or simply a transaction) the conventional wisdom is to define how to implement a business logic by programmatically referencing parameter values, verifying the dependencies, examining variables at runtime, and stepping through a predefined data flow accordingly. This is a so-called imperative programming model which uses assignments, conditions/branching and looping statements to serialize operations for establishing the state of a program at runtime, i.e. an instance. An imperative programming model is to describe virtually “how” to reach “what.” A vivid example is that C-family programming languages are based on an imperative model. An imperative model like the following pseudo code specifies the steps (i.e. how) to ensure the operability of attaching a database to a SQL server (in other words, what) by ensuring the SQL server is first up and running, i.e. ready, before attaching an intended database. The implementation logic is to repeated a routine of waiting for a specified period of time, checking the status of a target resource, until the target resource is ready for an intended operation.

Wait 30 seconds and check the SQL server status again, till it is up and running

Then attach the database

At the same time, a declarative programming model is to describe business logic based on ‘what it is and not how to do it.’ For instance, rather than programming a loop to periodically check the status of if a target SQL server is up and running like what an imperative model does as depicted by the above example, a declarative model will simply state the dependency on a target SQL server, i.e. what the state must meet, before attaching an intended database and let the system (here I use the system as an umbrella team of other components) to implement how to enforce this pre-requisite. The following illustrates a declarative approach.

This database has a dependency of the hosting SQL server

The above states the dependency, i.e. what it is, and delegates the implementations carried out later.

What vs. How

Notice that an imperative model is to specify both the what and the how of a deployment. At the same time, a declarative model implies a logical separation and focuses on the what and leave the how later.  In layman’s term, imperative vs. declarative is simply an approach of how vs. what, respectively.

Why Declarative

For simple operations, one may not be advantageous over the other. For large amount of operations or tasks with high concurrency and noticeable complexities, the orchestrations can be too overwhelming to productively implement with an imperative model. This is increasingly what IT pros are facing in a cloud setting where operations are intermittent, concurrent, and carried out on hundreds or thousands of various application instances with inter- and intra-dependencies among themselves at an application layer and a system level.

A declarative model states what a target state is and the system will make it so, i.e. enforce it as stated. Employing an declarative model will fundamentally simplify how an administrator carries out application deployment and automation with increased consistency, persistency, and predictability.

As IT is transitioning into cloud computing, the number of VMs will continue to increase while the deployment environment is likely becoming hybrid and complex, adopting a declarative programming model is, in my view, critical and inevitable.

Essentially, IT has become such a highly integrated and increasingly complex environment, which is particularly true in an emerging IT model where cloud computing combined with hybrid deployment scenarios. Programmatically describing how to establish a state in runtime can quickly overwhelm programming logic and make an implementation based on imperative model very costly to develop and maintain. Shifting to a declarative programming model is strategic and becoming “imperative” for IT.

Call to Action

Recognizing the presented opportunity, IT pros should make this shift from imperative to declarative scripting models sooner than later. Employ a declarative model as a vehicle to improve the capabilities and productivity of application deployments, to facilitate and maximize ROI of transitioning to cloud in an IT organization. To get started, there are already abundant information of Azure IaaS V2 available including:

In addition, those who are new to Azure IaaS may find the following resources helpful:

And for those who would like to review cloud computing concepts, I recommend:

Application Deployment as a Service, A Sample Implementation of with Microsoft Azure PowerShell

This is a lab delivered in the spring of 2015 for Microsoft US IT Camps, Extend Your Datacenter to Azure, which is a whole day event with hands-on experience on deploying and migrating workloads to Azure. This lab is specifically for IT pros to experience an automatic deployment of a business function/application, instead of deploying just VMs. The ability to deploy VMs are important and essential. Deploying VMs are however not the ultimate goal of moving to cloud. As I have addressed elsewhere, cloud goes way beyond virtualization and deploying VMs, instead it is about the anytime readiness and on-demand abilities to grow and shrink resource capacities based on demands, i.e. being elastic. And this lab does just that to prove this concept using Azure and PowerShell.

The script is published in github and one can run the script as it is and without making changes. In the recording below, I walked through the steps to acquire and run the script. The intent is to run it as a service, i.e. on demand, to deploy application instances from zero to running instances. Notice this script is for learning and testing Microsoft Azure and PowerShell. It does hard-code and not encrypt employed password, has very limited error handling, is not intended for production use.

image

For those who are not familiar with the essentials of Microsoft Azure Infrastructure Services, compliance, pricing, and cost structure, here are additional resources: