<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Alexandre Brisebois ☁</title>
	<atom:link href="https://alexandrebrisebois.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://alexandrebrisebois.wordpress.com</link>
	<description></description>
	<lastBuildDate>Wed, 03 Jun 2015 20:50:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='alexandrebrisebois.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>https://s2.wp.com/i/buttonw-com.png</url>
		<title>Alexandre Brisebois ☁</title>
		<link>https://alexandrebrisebois.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="https://alexandrebrisebois.wordpress.com/osd.xml" title="Alexandre Brisebois ☁" />
	<atom:link rel='hub' href='https://alexandrebrisebois.wordpress.com/?pushpress=hub'/>
	<item>
		<title>Create Multi-Geo Environments using Azure Resource Manager</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/06/03/create-multi-geo-environments-using-azure-resource-manager/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/06/03/create-multi-geo-environments-using-azure-resource-manager/#comments</comments>
		<pubDate>Wed, 03 Jun 2015 06:25:41 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Azure Resource Manager]]></category>
		<category><![CDATA[Azure Storage]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Configurations]]></category>
		<category><![CDATA[Data Disk]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[NIC]]></category>
		<category><![CDATA[OS Disk]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Resource Group]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Virtual Network]]></category>
		<category><![CDATA[VNet]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6724</guid>
		<description><![CDATA[While I was playing around with the Azure Resource Manager Copy Operation, I started thinking about what I could do with it. The first wild idea that popped into my head was, to use it to deploy multi-geo environments from a single ARM Template. Alright, some of you might think that it&#8217;s not such great idea, [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6724&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/06/03/create-multi-geo-environments-using-azure-resource-manager/" target="_blank" title="Create Multi-Geo Environments using Azure Resource&nbsp;Manager"><img width="580" height="403" src="https://alexandrebrisebois.files.wordpress.com/2015/06/multi-geo.png?w=580" class="attachment-large wp-post-image" alt="multi-geo" /></a></p><p>While I was <a title="Use the Azure Resource Manager Copy Operation to Deploy Duplicates" href="https://alexandrebrisebois.wordpress.com/2015/06/03/use-the-azure-resource-manager-copy-operation-to-deploy-duplicates/" target="_blank">playing around with the Azure Resource Manager Copy Operation</a>, I started thinking about what I could do with it. The first wild idea that popped into my head was, to use it to deploy multi-geo environments from a single ARM Template.</p>
<p>Alright, some of you might think that it&#8217;s not such great idea, and I can appreciate that. But I&#8217;m just too curious, so let&#8217;s give this a chance.<span id="more-6724"></span></p>
<h2>The Scenario</h2>
<p>Imagine a service that needs to be deployed to multiple Data Centers. The Virtual Machine configuration for each environment is identical and generally requires to be deployed to at least five Microsoft Azure Data Centers.</p>
<p>The following Azure Resource Manager (ARM) Template, deploys CentOS 7.1 Virtual Machines to East US, West US, West Europe, East Asia and Southeast Asia Azure Data Centers. To accomplish this, I defined an array of Azure Regions, that is then used to populate the location property for each Resource.</p>
<p>For this to work, I had to create copies the Virtual Network (VNet), the Storage Account, the Public IP, the Network Interface (NIC) and the Virtual Machine in each region. Building on the ARM Template from my <a title="Use the Azure Resource Manager Copy Operation to Deploy Duplicates" href="https://alexandrebrisebois.wordpress.com/2015/06/03/use-the-azure-resource-manager-copy-operation-to-deploy-duplicates/" target="_blank">earlier post,</a> I decided to use the vmCount as the control value for the Copy Operation applied of each Resource. This strategy worked out because the Template creates one Virtual Machine per region.</p>
<p>This ARM Template should be considered an experiment, because the Resource Group resides in a particular Azure Region and it contains Resources from across the world. As of writing this post, I can tell you that this is pretty cool, and that I&#8217;m curious to find out more about the long-term maintainability of this scenario.</p>
<p>Taking this a few steps further, the Custom Script for Linux Virtual Machine Extension could be used to download, unpack, install and configure a service. Then an Azure Traffic Manager instance could be created and configured to load balance traffic across the multi-geo environment.</p>
<h2>Building the ARM Template</h2>
<p>This step required some gymnastics, because I wasn&#8217;t familiar with the Resouce Dependencies for some of the Resources in the Template. After a couple of minutes, it was clear that I needed to add Copy Operations to all of the Resources. Using the copyIndex() and concat() functions, I named the Resources. Then I made sure that everything was referenced properly.</p>
<h3>DeploymentTemplate.json</h3>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;newStorageAccountName&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique DNS Name for the Storage Account where the Virtual Machine's disks will be placed.&quot;
            }
        },
        &quot;adminUsername&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;User name for the Virtual Machine.&quot;
            }
        },
        &quot;adminPassword&quot;: {
            &quot;type&quot;: &quot;securestring&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Password for the Virtual Machine.&quot;
            }
        },
        &quot;dnsPrefixNameForPublicIP&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique DNS Name for the Public IP used to access the Virtual Machine.&quot;
            }
        },
        &quot;OSVersion&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;defaultValue&quot;: &quot;7.1&quot;,
            &quot;allowedValues&quot;: [
                &quot;7.1&quot;
            ]
        },
        &quot;vmCount&quot;: {
            &quot;type&quot;: &quot;int&quot;,
            &quot;defaultValue&quot;: 1
        },
        &quot;virtualNetworkName&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Virtual Network Name&quot;
            }
        },
        &quot;vmNamePrefix&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Virtual Machine Name Prefix&quot;
            }
        },
        &quot;vmSize&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;defaultValue&quot;: &quot;Standard_A1&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Virtual Machine Size&quot;
            }
        },
        &quot;locations&quot;: {
            &quot;type&quot;: &quot;array&quot;,
            &quot;defaultValue&quot;: [
                &quot;East Asia&quot;,
                &quot;Southeast Asia&quot;,
                &quot;East US&quot;,
                &quot;West US&quot;,
                &quot;West Europe&quot;
            ],
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Locations&quot;
            }
        }
    },
    &quot;variables&quot;: {
        &quot;addressPrefix&quot;: &quot;10.0.0.0/16&quot;,
        &quot;dataDiskSize&quot;: &quot;1023&quot;,
        &quot;imageOffer&quot;: &quot;CentOS&quot;,
        &quot;imagePublisher&quot;: &quot;OpenLogic&quot;,
        &quot;nicName&quot;: &quot;NIC&quot;,
        &quot;OSDiskName&quot;: &quot;osdisk&quot;,
        &quot;publicIPAddressType&quot;: &quot;Dynamic&quot;,
        &quot;storageAccountType&quot;: &quot;Standard_LRS&quot;,
        &quot;subnetName&quot;: &quot;Subnet&quot;,
        &quot;subnetPrefix&quot;: &quot;10.0.0.0/24&quot;,
        &quot;vmStorageAccountContainerName&quot;: &quot;vhds&quot;
    },
    &quot;resources&quot;: [
        {
            &quot;type&quot;: &quot;Microsoft.Storage/storageAccounts&quot;,
            &quot;name&quot;: &quot;[concat(parameters('newStorageAccountName'),copyIndex())]&quot;,
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;location&quot;: &quot;[parameters('locations')[copyIndex()]]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;StorageAccount&quot;
            },
            &quot;properties&quot;: {
                &quot;accountType&quot;: &quot;[variables('storageAccountType')]&quot;
            },
            &quot;copy&quot;: {
                &quot;name&quot;: &quot;storageAccountCopy&quot;,
                &quot;count&quot;: &quot;[parameters('vmCount')]&quot;
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/publicIPAddresses&quot;,
            &quot;name&quot;: &quot;[concat(parameters('dnsPrefixNameForPublicIP'),copyIndex())]&quot;,
            &quot;location&quot;: &quot;[parameters('locations')[copyIndex()]]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;PublicIPAddress&quot;
            },
            &quot;properties&quot;: {
                &quot;publicIPAllocationMethod&quot;: &quot;[variables('publicIPAddressType')]&quot;,
                &quot;dnsSettings&quot;: {
                    &quot;domainNameLabel&quot;: &quot;[concat(parameters('dnsPrefixNameForPublicIP'),copyIndex())]&quot;
                }
            },
            &quot;copy&quot;: {
                &quot;name&quot;: &quot;publicIpCopy&quot;,
                &quot;count&quot;: &quot;[parameters('vmCount')]&quot;
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/virtualNetworks&quot;,
            &quot;name&quot;: &quot;[concat(parameters('virtualNetworkName'),copyIndex())]&quot;,
            &quot;location&quot;: &quot;[parameters('locations')[copyIndex()]]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;VirtualNetwork&quot;
            },
            &quot;properties&quot;: {
                &quot;addressSpace&quot;: {
                    &quot;addressPrefixes&quot;: [
                        &quot;[variables('addressPrefix')]&quot;
                    ]
                },
                &quot;subnets&quot;: [
                    {
                        &quot;name&quot;: &quot;[variables('subnetName')]&quot;,
                        &quot;properties&quot;: {
                            &quot;addressPrefix&quot;: &quot;[variables('subnetPrefix')]&quot;
                        }
                    }
                ]
            },
            &quot;copy&quot;: {
                &quot;name&quot;: &quot;vnetCopy&quot;,
                &quot;count&quot;: &quot;[parameters('vmCount')]&quot;
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/networkInterfaces&quot;,
            &quot;name&quot;: &quot;[concat(variables('nicName'),copyIndex())]&quot;,
            &quot;location&quot;: &quot;[parameters('locations')[copyIndex()]]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;NetworkInterface&quot;
            },
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Network/publicIPAddresses/', parameters('dnsPrefixNameForPublicIP'), copyIndex())]&quot;,
                &quot;[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'), copyIndex())]&quot;
            ],
            &quot;properties&quot;: {
                &quot;ipConfigurations&quot;: [
                    {
                        &quot;name&quot;: &quot;[concat('ipconfig',copyIndex())]&quot;,
                        &quot;properties&quot;: {
                            &quot;privateIPAllocationMethod&quot;: &quot;Dynamic&quot;,
                            &quot;publicIPAddress&quot;: {
                                &quot;id&quot;: &quot;[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('dnsPrefixNameForPublicIP'),copyIndex()))]&quot;
                            },
                            &quot;subnet&quot;: {
                                &quot;id&quot;: &quot;[concat(resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName')), copyIndex(),'/subnets/',variables('subnetName'))]&quot;
                            }
                        }
                    }
                ]
            },
            &quot;copy&quot;: {
                &quot;name&quot;: &quot;nicCopy&quot;,
                &quot;count&quot;: &quot;[parameters('vmCount')]&quot;
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;copy&quot;: {
                &quot;name&quot;: &quot;nodeCopy&quot;,
                &quot;count&quot;: &quot;[parameters('vmCount')]&quot;
            },
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'), copyIndex())]&quot;,
                &quot;[concat('Microsoft.Network/networkInterfaces/', variables('nicName'), copyIndex())]&quot;
            ],
            &quot;location&quot;: &quot;[parameters('locations')[copyIndex()]]&quot;,
            &quot;name&quot;: &quot;[concat(parameters('vmNamePrefix'),copyIndex())]&quot;,
            &quot;properties&quot;: {
                &quot;hardwareProfile&quot;: {
                    &quot;vmSize&quot;: &quot;[parameters('vmSize')]&quot;
                },
                &quot;osProfile&quot;: {
                    &quot;computername&quot;: &quot;[concat(parameters('vmNamePrefix'), copyIndex())]&quot;,
                    &quot;adminUsername&quot;: &quot;[parameters('adminUsername')]&quot;,
                    &quot;adminPassword&quot;: &quot;[parameters('adminPassword')]&quot;
                },
                &quot;storageProfile&quot;: {
                    &quot;imageReference&quot;: {
                        &quot;publisher&quot;: &quot;[variables('imagePublisher')]&quot;,
                        &quot;offer&quot;: &quot;[variables('imageOffer')]&quot;,
                        &quot;sku&quot;: &quot;[parameters('OSVersion')]&quot;,
                        &quot;version&quot;: &quot;latest&quot;
                    },
                    &quot;osDisk&quot;: {
                        &quot;name&quot;: &quot;osdisk&quot;,
                        &quot;vhd&quot;: {
                            &quot;uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),copyIndex(),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',concat(variables('OSDiskName')),'.vhd')]&quot;
                        },
                        &quot;caching&quot;: &quot;ReadWrite&quot;,
                        &quot;createOption&quot;: &quot;FromImage&quot;
                    },
                    &quot;dataDisks&quot;: [
                        {
                            &quot;name&quot;: &quot;datadisk1&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('dataDiskSize')]&quot;,
                            &quot;lun&quot;: 0,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),copyIndex(),'.blob.core.windows.net/vhds/',concat(parameters('vmNamePrefix')),'dataDisk1' ,'.vhd')]&quot;
                            },
                            &quot;caching&quot;: &quot;None&quot;,
                            &quot;createOption&quot;: &quot;Empty&quot;
                        }
                    ]
                },
                &quot;networkProfile&quot;: {
                    &quot;networkInterfaces&quot;: [
                        {
                            &quot;id&quot;: &quot;[resourceId('Microsoft.Network/networkInterfaces', concat(variables('nicName') ,copyIndex()))]&quot;
                        }
                    ]
                }
            },
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;VirtualMachine&quot;
            },
            &quot;type&quot;: &quot;Microsoft.Compute/virtualMachines&quot;
        }
    ]
}
</pre>
<h2>Publishing the ARM Template</h2>
<p>Prepare the Template Parameter File a.k.a DeploymentTemplate.param.dev.json</p>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;newStorageAccountName&quot;: {
            &quot;value&quot;: &quot;briseboiscentos&quot;
        },
        &quot;adminUsername&quot;: {
            &quot;value&quot;: &quot;briseboiscentos&quot;
        },
        &quot;dnsPrefixNameForPublicIP&quot;: {
            &quot;value&quot;: &quot;centosdns&quot;
        },
        &quot;virtualNetworkName&quot;: {
            &quot;value&quot;: &quot;centosvnet&quot;
        },
        &quot;vmNamePrefix&quot;: {
            &quot;value&quot;: &quot;briseboiscentos&quot;
        },
        &quot;vmSize&quot;: {
            &quot;value&quot;: &quot;Standard_A1&quot;
        },
        &quot;vmCount&quot;: {
            &quot;value&quot;: 5
        },
        &quot;locations&quot;: {
            &quot;value&quot;: [
                &quot;East Asia&quot;,
                &quot;Southeast Asia&quot;,
                &quot;East US&quot;,
                &quot;West US&quot;,
                &quot;West Europe&quot;
            ]
        }
    }
}
</pre>
<p>Then deploy the Azure Resource Manager Template and Parameters using PowerShell.</p>
<pre class="brush: powershell; title: ; notranslate">
New-AzureResourceGroup -Name 'centosbrisebois' `
                       -Location 'eastus' `
                       -TemplateFile 'DeploymentTemplate.json' `
                       -TemplateParameterFile 'DeploymentTemplate.param.dev.json' `
                       -Force -Verbose
# New-AzureResourceGroup VERBOSE Log

VERBOSE: 12:26:05 AM - Created resource group 'centosbrisebois' in location 'eastus'
VERBOSE: 12:26:06 AM - Template is valid.
VERBOSE: 12:26:07 AM - Create template deployment 'DeploymentTemplate'.
VERBOSE: 12:26:12 AM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos3' provisioning status is running
VERBOSE: 12:26:12 AM - Resource Microsoft.Network/virtualNetworks 'centosvnet1' provisioning status is running
VERBOSE: 12:26:12 AM - Resource Microsoft.Network/virtualNetworks 'centosvnet0' provisioning status is running
VERBOSE: 12:26:12 AM - Resource Microsoft.Network/virtualNetworks 'centosvnet3' provisioning status is running
VERBOSE: 12:26:12 AM - Resource Microsoft.Network/virtualNetworks 'centosvnet4' provisioning status is running
VERBOSE: 12:26:12 AM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos1' provisioning status is running
VERBOSE: 12:26:12 AM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos0' provisioning status is running
VERBOSE: 12:26:12 AM - Resource Microsoft.Network/virtualNetworks 'centosvnet2' provisioning status is running
VERBOSE: 12:26:12 AM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos2' provisioning status is running
VERBOSE: 12:26:14 AM - Resource Microsoft.Network/publicIPAddresses 'centosdns0' provisioning status is running
VERBOSE: 12:26:14 AM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos4' provisioning status is running
VERBOSE: 12:26:14 AM - Resource Microsoft.Network/publicIPAddresses 'centosdns1' provisioning status is running
VERBOSE: 12:26:14 AM - Resource Microsoft.Network/publicIPAddresses 'centosdns2' provisioning status is running
VERBOSE: 12:26:14 AM - Resource Microsoft.Network/publicIPAddresses 'centosdns3' provisioning status is running
VERBOSE: 12:26:14 AM - Resource Microsoft.Network/publicIPAddresses 'centosdns4' provisioning status is running
VERBOSE: 12:26:24 AM - Resource Microsoft.Network/publicIPAddresses 'centosdns2' provisioning status is succeeded
VERBOSE: 12:26:24 AM - Resource Microsoft.Network/virtualNetworks 'centosvnet3' provisioning status is succeeded
VERBOSE: 12:26:24 AM - Resource Microsoft.Network/virtualNetworks 'centosvnet4' provisioning status is succeeded
VERBOSE: 12:26:24 AM - Resource Microsoft.Network/virtualNetworks 'centosvnet2' provisioning status is succeeded
VERBOSE: 12:26:26 AM - Resource Microsoft.Network/publicIPAddresses 'centosdns3' provisioning status is succeeded
VERBOSE: 12:26:26 AM - Resource Microsoft.Network/publicIPAddresses 'centosdns4' provisioning status is succeeded
VERBOSE: 12:26:26 AM - Resource Microsoft.Network/virtualNetworks 'centosvnet1' provisioning status is succeeded
VERBOSE: 12:26:26 AM - Resource Microsoft.Network/virtualNetworks 'centosvnet0' provisioning status is succeeded
VERBOSE: 12:26:28 AM - Resource Microsoft.Network/networkInterfaces 'NIC4' provisioning status is succeeded
VERBOSE: 12:26:28 AM - Resource Microsoft.Network/networkInterfaces 'NIC2' provisioning status is succeeded
VERBOSE: 12:26:28 AM - Resource Microsoft.Network/networkInterfaces 'NIC3' provisioning status is succeeded
VERBOSE: 12:26:28 AM - Resource Microsoft.Network/publicIPAddresses 'centosdns0' provisioning status is succeeded
VERBOSE: 12:26:28 AM - Resource Microsoft.Network/publicIPAddresses 'centosdns1' provisioning status is succeeded
VERBOSE: 12:26:31 AM - Resource Microsoft.Network/networkInterfaces 'NIC1' provisioning status is succeeded
VERBOSE: 12:26:31 AM - Resource Microsoft.Network/networkInterfaces 'NIC0' provisioning status is succeeded
VERBOSE: 12:26:38 AM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos3' provisioning status is succeeded
VERBOSE: 12:26:40 AM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos3' provisioning status is running
VERBOSE: 12:27:04 AM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos2' provisioning status is running
VERBOSE: 12:27:04 AM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos1' provisioning status is succeeded
VERBOSE: 12:27:04 AM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos2' provisioning status is succeeded
VERBOSE: 12:27:09 AM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos1' provisioning status is running
VERBOSE: 12:27:09 AM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos4' provisioning status is succeeded
VERBOSE: 12:27:11 AM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos4' provisioning status is running
VERBOSE: 12:28:35 AM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos3' provisioning status is succeeded
VERBOSE: 12:28:57 AM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos2' provisioning status is succeeded
VERBOSE: 12:29:09 AM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos0' provisioning status is succeeded
VERBOSE: 12:29:11 AM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos0' provisioning status is running
VERBOSE: 12:29:20 AM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos4' provisioning status is succeeded
VERBOSE: 12:31:10 AM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos0' provisioning status is succeeded
VERBOSE: 12:31:48 AM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos1' provisioning status is succeeded
</pre>
<p>This deployment took about 5 minutes to complete across five Microsoft Azure Data Centers. I&#8217;m amazed by the fact that I was able to do this with a single Virtual Machine definition. This obviously comes with a price. As you may have noticed, the Azure Resource Manager Template can get complicated.</p>
<p>This experiment was quite interesting and will definitely fuel more experiments with the Azure Resource Manager. Please use the comment section below ask questions, share your experiences and to discuss best practices.</p>
<h2>Helpful Azure Resource Manager Documentation</h2>
<ul>
<li><a title="" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-authoring-templates/">Authoring Azure Resource Manager Templates</a></li>
<li><a title="" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-template-deploy/">Deploy an application with Azure Resource Manager Template</a></li>
<li><a title="" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-deploy-debug/">Troubleshooting Resource Group Deployments in Azure</a></li>
<li><a title="" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-template-functions/">Azure Resource Manager Template Functions</a></li>
<li><a title="" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-advanced-template/">Advanced Template Operations</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/arm/'>ARM</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-resource-manager/'>Azure Resource Manager</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-storage/'>Azure Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/centos/'>CentOS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configurations/'>Configurations</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/data-disk/'>Data Disk</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iaas/'>IaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/json/'>JSON</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/linux/'>Linux</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/nic/'>NIC</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/os-disk/'>OS Disk</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/resource-group/'>Resource Group</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-network/'>Virtual Network</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/vnet/'>VNet</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6724/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6724/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6724/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6724/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6724/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6724/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6724/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6724/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6724/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6724/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6724/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6724/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6724/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6724/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6724&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/06/03/create-multi-geo-environments-using-azure-resource-manager/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/06/multi-geo.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/06/multi-geo.png?w=150" medium="image">
			<media:title type="html">multi-geo</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Use the Azure Resource Manager Copy Operation to Deploy Duplicates</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/06/03/use-the-azure-resource-manager-copy-operation-to-deploy-duplicates/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/06/03/use-the-azure-resource-manager-copy-operation-to-deploy-duplicates/#comments</comments>
		<pubDate>Wed, 03 Jun 2015 04:19:20 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Azure Resource Manager]]></category>
		<category><![CDATA[Azure Storage]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Configurations]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[NIC]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Resource Group]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Virtual Network]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6686</guid>
		<description><![CDATA[To duplicate a resource, we must use the <a href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-advanced-template/" target="_blank">copy operation</a>. It enables us to use an index number or to iterate through an array of values that can be used when deploying a resource. <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6686&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/06/03/use-the-azure-resource-manager-copy-operation-to-deploy-duplicates/" target="_blank" title="Use the Azure Resource Manager Copy Operation to Deploy&nbsp;Duplicates"><img width="580" height="411" src="https://alexandrebrisebois.files.wordpress.com/2015/06/arm-resource-group.png?w=580" class="attachment-large wp-post-image" alt="ARM Resource Group" /></a></p><h1>Deploying 20 CentOS VMs in 4 Minutes!</h1>
<p>I recently started to toy around with scenarios that required me to deploy multiple duplicates of the same CentOS Virtual Machine configuration. Working on this scenario got me curious. So I decided to build a template that would allow me to deploy 20 CentOS Virtual Machines each with one 1TB data disk and one public IP addresses.</p>
<p>To my surprise, deploying these 20 Standard A1 CentOS Virtual Machines on Microsoft Azure took 4 minutes!</p>
<h2>Building the ARM Template</h2>
<p>Let&#8217;s start by taking a <a href="https://alexandrebrisebois.wordpress.com/2015/05/25/create-a-centos-virtual-machine-using-azure-resource-manager-arm/" title="Create a CentOS Virtual Machine Using #Azure Resource Manager (ARM)" target="_blank">CentOS ARM Template</a> from a previous post. It will be our starting point for this exercise. Now, let&#8217;s removed the extra data disk and removed the Custom Script for Linux Virtual Machine Extension.   </p>
<p>To duplicate a resource, we must use the <a href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-advanced-template/" target="_blank">copy operation</a>. It enables us to use an index number or to iterate through an array of values that can be used when deploying a resource. </p>
<pre class="brush: jscript; title: ; notranslate">
&quot;copy&quot;: {
          &quot;name&quot;: &quot;nodeCopy&quot;,
          &quot;count&quot;: &quot;[parameters('vmCount')]&quot;
}
</pre>
<p>In this specific scenario, we want all our Virtual Machines to belong to the same Virtual Network and Subnet. Therefore, we need to duplicate each Virtual Machine, their Network Interface Cards (NIC) and their Public IP Addresses.</p>
<p>The following template, demonstrates the use of copyIndex() and concat(), to generate predictable identifiers for each copy.<span id="more-6686"></span></p>
<h3>DeploymentTemplate.json</h3>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;newStorageAccountName&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique DNS Name for the Storage Account where the Virtual Machine's disks will be placed.&quot;
            }
        },
        &quot;adminUsername&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;User name for the Virtual Machine.&quot;
            }
        },
        &quot;adminPassword&quot;: {
            &quot;type&quot;: &quot;securestring&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Password for the Virtual Machine.&quot;
            }
        },
        &quot;dnsPrefixNameForPublicIP&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique DNS Name for the Public IP used to access the Virtual Machine.&quot;
            }
        },
        &quot;OSVersion&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;defaultValue&quot;: &quot;7.1&quot;,
            &quot;allowedValues&quot;: [
                &quot;7.1&quot;
            ]
        },
        &quot;vmCount&quot;: {
            &quot;type&quot;: &quot;int&quot;,
            &quot;defaultValue&quot;: 1
        },
        &quot;virtualNetworkName&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Virtual Network Name&quot;
            }
        },
        &quot;vmNamePrefix&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Virtual Machine Name Prefix&quot;
            }
        },
        &quot;vmSize&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;defaultValue&quot;: &quot;Standard_A1&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Virtual Machine Size&quot;
            }
        },
        &quot;location&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;defaultValue&quot;: &quot;West US&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Location&quot;
            }
        }
    },
    &quot;variables&quot;: {
        &quot;addressPrefix&quot;: &quot;10.0.0.0/16&quot;,
        &quot;dataDiskSize&quot;: &quot;1023&quot;,
        &quot;imageOffer&quot;: &quot;CentOS&quot;,
        &quot;imagePublisher&quot;: &quot;OpenLogic&quot;,
        &quot;nicName&quot;: &quot;NIC&quot;,
        &quot;OSDiskName&quot;: &quot;osdisk&quot;,
        &quot;publicIPAddressType&quot;: &quot;Dynamic&quot;,
        &quot;storageAccountType&quot;: &quot;Standard_LRS&quot;,
        &quot;subnetName&quot;: &quot;Subnet&quot;,
        &quot;subnetPrefix&quot;: &quot;10.0.0.0/24&quot;,
        &quot;subnetRef&quot;: &quot;[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]&quot;,
        &quot;vmStorageAccountContainerName&quot;: &quot;vhds&quot;,
        &quot;vnetID&quot;: &quot;[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]&quot;
    },
    &quot;resources&quot;: [
        {
            &quot;type&quot;: &quot;Microsoft.Storage/storageAccounts&quot;,
            &quot;name&quot;: &quot;[parameters('newStorageAccountName')]&quot;,
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;StorageAccount&quot;
            },
            &quot;properties&quot;: {
                &quot;accountType&quot;: &quot;[variables('storageAccountType')]&quot;
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/publicIPAddresses&quot;,
            &quot;name&quot;: &quot;[concat(parameters('dnsPrefixNameForPublicIP'),copyIndex())]&quot;,
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;PublicIPAddress&quot;
            },
            &quot;properties&quot;: {
                &quot;publicIPAllocationMethod&quot;: &quot;[variables('publicIPAddressType')]&quot;,
                &quot;dnsSettings&quot;: {
                    &quot;domainNameLabel&quot;: &quot;[concat(parameters('dnsPrefixNameForPublicIP'),copyIndex())]&quot;
                }
            },
            &quot;copy&quot;: {
                &quot;name&quot;: &quot;publicIpCopy&quot;,
                &quot;count&quot;: &quot;[parameters('vmCount')]&quot;
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/virtualNetworks&quot;,
            &quot;name&quot;: &quot;[parameters('virtualNetworkName')]&quot;,
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;VirtualNetwork&quot;
            },
            &quot;properties&quot;: {
                &quot;addressSpace&quot;: {
                    &quot;addressPrefixes&quot;: [
                        &quot;[variables('addressPrefix')]&quot;
                    ]
                },
                &quot;subnets&quot;: [
                    {
                        &quot;name&quot;: &quot;[variables('subnetName')]&quot;,
                        &quot;properties&quot;: {
                            &quot;addressPrefix&quot;: &quot;[variables('subnetPrefix')]&quot;
                        }
                    }
                ]
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/networkInterfaces&quot;,
            &quot;name&quot;: &quot;[concat(variables('nicName'),copyIndex())]&quot;,
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;NetworkInterface&quot;
            },
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Network/publicIPAddresses/', concat(parameters('dnsPrefixNameForPublicIP'),copyIndex()))]&quot;,
                &quot;[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]&quot;
            ],
            &quot;properties&quot;: {
                &quot;ipConfigurations&quot;: [
                    {
                        &quot;name&quot;: &quot;[concat('ipconfig', copyIndex())]&quot;,
                        &quot;properties&quot;: {
                            &quot;privateIPAllocationMethod&quot;: &quot;Dynamic&quot;,
                            &quot;publicIPAddress&quot;: {
                                &quot;id&quot;: &quot;[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('dnsPrefixNameForPublicIP'),copyIndex()))]&quot;
                            },
                            &quot;subnet&quot;: {
                                &quot;id&quot;: &quot;[variables('subnetRef')]&quot;
                            }
                        }
                    }
                ]
            },
            &quot;copy&quot;: {
                &quot;name&quot;: &quot;nicCopy&quot;,
                &quot;count&quot;: &quot;[parameters('vmCount')]&quot;
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;copy&quot;: {
                &quot;name&quot;: &quot;nodeCopy&quot;,
                &quot;count&quot;: &quot;[parameters('vmCount')]&quot;
            },
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'))]&quot;,
                &quot;[concat('Microsoft.Network/networkInterfaces/', concat(variables('nicName'),copyIndex()))]&quot;
            ],
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;name&quot;: &quot;[concat(parameters('vmNamePrefix'),copyIndex())]&quot;,
            &quot;properties&quot;: {
                &quot;hardwareProfile&quot;: {
                    &quot;vmSize&quot;: &quot;[parameters('vmSize')]&quot;
                },
                &quot;osProfile&quot;: {
                    &quot;computername&quot;: &quot;[concat(parameters('vmNamePrefix'),copyIndex())]&quot;,
                    &quot;adminUsername&quot;: &quot;[parameters('adminUsername')]&quot;,
                    &quot;adminPassword&quot;: &quot;[parameters('adminPassword')]&quot;
                },
                &quot;storageProfile&quot;: {
                    &quot;imageReference&quot;: {
                        &quot;publisher&quot;: &quot;[variables('imagePublisher')]&quot;,
                        &quot;offer&quot;: &quot;[variables('imageOffer')]&quot;,
                        &quot;sku&quot;: &quot;[parameters('OSVersion')]&quot;,
                        &quot;version&quot;: &quot;latest&quot;
                    },
                    &quot;osDisk&quot;: {
                        &quot;name&quot;: &quot;osdisk&quot;,
                        &quot;vhd&quot;: {
                            &quot;uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',concat(variables('OSDiskName'),copyIndex()),'.vhd')]&quot;
                        },
                        &quot;caching&quot;: &quot;ReadWrite&quot;,
                        &quot;createOption&quot;: &quot;FromImage&quot;
                    },
                    &quot;dataDisks&quot;: [
                        {
                            &quot;name&quot;: &quot;datadisk1&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('dataDiskSize')]&quot;,
                            &quot;lun&quot;: 0,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/vhds/',concat(parameters('vmNamePrefix'),copyIndex()),'dataDisk1' ,'.vhd')]&quot;
                            },
                            &quot;caching&quot;: &quot;None&quot;,
                            &quot;createOption&quot;: &quot;Empty&quot;
                        }
                    ]
                },
                &quot;networkProfile&quot;: {
                    &quot;networkInterfaces&quot;: [
                        {
                            &quot;id&quot;: &quot;[resourceId('Microsoft.Network/networkInterfaces', concat(variables('nicName'),copyIndex()))]&quot;
                        }
                    ]
                }
            },
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;VirtualMachine&quot;
            },
            &quot;type&quot;: &quot;Microsoft.Compute/virtualMachines&quot;
        }
    ]
}
</pre>
<h2>Publishing the ARM Template</h2>
<p>Prepare the Template Parameter File a.k.a DeploymentTemplate.param.dev.json</p>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;newStorageAccountName&quot;: {
            &quot;value&quot;: &quot;briseboiscentos&quot;
        },
        &quot;adminUsername&quot;: {
            &quot;value&quot;: &quot;briseboiscentos&quot;
        },
        &quot;dnsPrefixNameForPublicIP&quot;: {
            &quot;value&quot;: &quot;centosdns&quot;
        },
        &quot;virtualNetworkName&quot;: {
            &quot;value&quot;: &quot;centosvnet&quot;
        },
        &quot;vmNamePrefix&quot;: {
            &quot;value&quot;: &quot;briseboiscentos&quot;
        },
        &quot;vmSize&quot;: {
            &quot;value&quot;: &quot;Standard_A1&quot;
        },
        &quot;vmCount&quot;: {
            &quot;value&quot;: 20
        },
        &quot;location&quot;: {
            &quot;value&quot;: &quot;East US&quot;
        }
    }
}
</pre>
<p>Then deploy the Azure Resource Manager Template and Parameters using PowerShell.</p>
<pre class="brush: powershell; title: ; notranslate">
Switch-AzureMode AzureResourceManager

New-AzureResourceGroup -Name 'centosbrisebois' `
                       -Location 'eastus' `
                       -TemplateFile 'DeploymentTemplate.json' `
                       -TemplateParameterFile 'DeploymentTemplate.param.dev.json' `
                       -Force -Verbose 

# New-AzureResourceGroup VERBOSE Log

VERBOSE: 7:17:09 PM - Created resource group 'centosbrisebois' in location 'eastus'
VERBOSE: 7:17:09 PM - Template is valid.
VERBOSE: 7:17:11 PM - Create template deployment 'DeploymentTemplate'.
VERBOSE: 7:17:16 PM - Resource Microsoft.Network/virtualNetworks 'centosvnet' provisioning status is running
VERBOSE: 7:17:16 PM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos' provisioning status is running
VERBOSE: 7:17:21 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns16' provisioning status is running
VERBOSE: 7:17:21 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns17' provisioning status is running
VERBOSE: 7:17:21 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns9' provisioning status is running
VERBOSE: 7:17:21 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns6' provisioning status is running
VERBOSE: 7:17:21 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns1' provisioning status is running
VERBOSE: 7:17:21 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns0' provisioning status is running
VERBOSE: 7:17:21 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns14' provisioning status is running
VERBOSE: 7:17:21 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns5' provisioning status is running
VERBOSE: 7:17:21 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns2' provisioning status is running
VERBOSE: 7:17:21 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns12' provisioning status is running
VERBOSE: 7:17:24 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns15' provisioning status is running
VERBOSE: 7:17:24 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns11' provisioning status is running
VERBOSE: 7:17:24 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns18' provisioning status is running
VERBOSE: 7:17:24 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns19' provisioning status is running
VERBOSE: 7:17:24 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns8' provisioning status is running
VERBOSE: 7:17:24 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns3' provisioning status is running
VERBOSE: 7:17:24 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns10' provisioning status is running
VERBOSE: 7:17:24 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns7' provisioning status is running
VERBOSE: 7:17:24 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns13' provisioning status is running
VERBOSE: 7:17:24 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns4' provisioning status is running
VERBOSE: 7:17:28 PM - Resource Microsoft.Network/virtualNetworks 'centosvnet' provisioning status is succeeded
VERBOSE: 7:17:33 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns15' provisioning status is succeeded
VERBOSE: 7:17:33 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns7' provisioning status is succeeded
VERBOSE: 7:17:33 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns4' provisioning status is succeeded
VERBOSE: 7:17:33 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns16' provisioning status is succeeded
VERBOSE: 7:17:33 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns1' provisioning status is succeeded
VERBOSE: 7:17:33 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns14' provisioning status is succeeded
VERBOSE: 7:17:33 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns5' provisioning status is succeeded
VERBOSE: 7:17:33 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns2' provisioning status is succeeded
VERBOSE: 7:17:33 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns12' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC14' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC18' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC9' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC8' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC4' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC13' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC12' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC15' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC5' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC1' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC7' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC16' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/networkInterfaces 'NIC2' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns18' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns19' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns8' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns10' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns13' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns9' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns6' provisioning status is succeeded
VERBOSE: 7:17:36 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns0' provisioning status is succeeded
VERBOSE: 7:17:38 PM - Resource Microsoft.Network/networkInterfaces 'NIC10' provisioning status is succeeded
VERBOSE: 7:17:38 PM - Resource Microsoft.Network/networkInterfaces 'NIC19' provisioning status is succeeded
VERBOSE: 7:17:43 PM - Resource Microsoft.Storage/storageAccounts 'briseboiscentos' provisioning status is succeeded
VERBOSE: 7:17:46 PM - Resource Microsoft.Network/networkInterfaces 'NIC0' provisioning status is succeeded
VERBOSE: 7:17:46 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos10' provisioning status is running
VERBOSE: 7:17:46 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos1' provisioning status is running
VERBOSE: 7:17:46 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos19' provisioning status is running
VERBOSE: 7:17:46 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos2' provisioning status is running
VERBOSE: 7:17:46 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos12' provisioning status is running
VERBOSE: 7:17:46 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos7' provisioning status is running
VERBOSE: 7:17:46 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos16' provisioning status is running
VERBOSE: 7:17:48 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos6' provisioning status is running
VERBOSE: 7:17:48 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos0' provisioning status is running
VERBOSE: 7:17:48 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos15' provisioning status is running
VERBOSE: 7:17:48 PM - Resource Microsoft.Network/networkInterfaces 'NIC6' provisioning status is succeeded
VERBOSE: 7:17:55 PM - Resource Microsoft.Network/networkInterfaces 'NIC11' provisioning status is succeeded
VERBOSE: 7:17:55 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns11' provisioning status is succeeded
VERBOSE: 7:18:03 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos11' provisioning status is running
VERBOSE: 7:18:05 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos4' provisioning status is running
VERBOSE: 7:18:05 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos14' provisioning status is running
VERBOSE: 7:18:08 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos13' provisioning status is running
VERBOSE: 7:18:08 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos18' provisioning status is running
VERBOSE: 7:18:08 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos9' provisioning status is running
VERBOSE: 7:18:08 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos8' provisioning status is running
VERBOSE: 7:18:10 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos5' provisioning status is running
VERBOSE: 7:18:13 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns17' provisioning status is succeeded
VERBOSE: 7:18:15 PM - Resource Microsoft.Network/networkInterfaces 'NIC3' provisioning status is succeeded
VERBOSE: 7:18:15 PM - Resource Microsoft.Network/networkInterfaces 'NIC17' provisioning status is succeeded
VERBOSE: 7:18:15 PM - Resource Microsoft.Network/publicIPAddresses 'centosdns3' provisioning status is succeeded
VERBOSE: 7:18:18 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos17' provisioning status is running
VERBOSE: 7:18:18 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos3' provisioning status is running
VERBOSE: 7:19:39 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos12' provisioning status is succeeded
VERBOSE: 7:19:44 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos6' provisioning status is succeeded
VERBOSE: 7:19:47 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos0' provisioning status is succeeded
VERBOSE: 7:19:54 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos19' provisioning status is succeeded
VERBOSE: 7:19:54 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos16' provisioning status is succeeded
VERBOSE: 7:19:57 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos10' provisioning status is succeeded
VERBOSE: 7:19:57 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos2' provisioning status is succeeded
VERBOSE: 7:19:59 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos8' provisioning status is succeeded
VERBOSE: 7:20:02 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos5' provisioning status is succeeded
VERBOSE: 7:20:12 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos15' provisioning status is succeeded
VERBOSE: 7:20:12 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos7' provisioning status is succeeded
VERBOSE: 7:20:14 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos14' provisioning status is succeeded
VERBOSE: 7:20:17 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos13' provisioning status is succeeded
VERBOSE: 7:20:17 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos18' provisioning status is succeeded
VERBOSE: 7:20:17 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos9' provisioning status is succeeded
VERBOSE: 7:20:17 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos4' provisioning status is succeeded
VERBOSE: 7:20:17 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos11' provisioning status is succeeded
VERBOSE: 7:20:29 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos17' provisioning status is succeeded
VERBOSE: 7:21:04 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos3' provisioning status is succeeded
VERBOSE: 7:21:19 PM - Resource Microsoft.Compute/virtualMachines 'briseboiscentos1' provisioning status is succeeded
</pre>
<p>Voila! 4 minutes later, we are now ready to start working with our 20 new CentOS Virtual Machines.</p>
<h3>Additional Thoughts</h3>
<p>In some circumstances, using a copy index (0,1,2,3&#8230;) to name resources isn&#8217;t practical. When this is the case, it is possible to use the copy index to read from an array of values. In the following example, we are creating three Azure Storage Accounts using by concatenating elements from an array of names.</p>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;storageAccountNames&quot;: {
            &quot;type&quot;: &quot;array&quot;,
            &quot;defaultValue&quot;: [
                &quot;archive&quot;,
                &quot;data&quot;,
                &quot;vhds&quot;
            ]
        },
        &quot;count&quot;: {
            &quot;type&quot;: &quot;int&quot;,
            &quot;defaultValue&quot;: 3
        }
    },
    &quot;resources&quot;: [
        {
           &quot;type&quot;: &quot;Microsoft.Storage/storageAccounts&quot;,
            &quot;name&quot;: &quot;[concat('brisebois',parameters('storageAccountNames')[copyIndex()])]&quot;,
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;location&quot;: &quot;[resourceGroup().location]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;[concat('brisebois',parameters('storageAccountNames')[copyIndex()])]&quot;
            },
            &quot;properties&quot;: {
                &quot;accountType&quot;: &quot;Standard_LRS&quot;
            },
            &quot;copy&quot;: {
                &quot;name&quot;: &quot;storageAccountCopy&quot;,
                &quot;count&quot;: &quot;[parameters('count')]&quot;
            }
        }
    ]
}
</pre>
<h2>ARM Resources</h2>
<ul>
<li><a title="" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-authoring-templates/">Authoring Azure Resource Manager Templates</a></li>
<li><a title="" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-template-deploy/">Deploy an application with Azure Resource Manager Template</a></li>
<li><a title="" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-deploy-debug/">Troubleshooting Resource Group Deployments in Azure</a></li>
<li><a title="" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-template-functions/">Azure Resource Manager Template Functions</a></li>
<li><a title="" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-advanced-template/">Advanced Template Operations</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/arm/'>ARM</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-resource-manager/'>Azure Resource Manager</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-storage/'>Azure Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/centos/'>CentOS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configurations/'>Configurations</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iaas/'>IaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/json/'>JSON</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/linux/'>Linux</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/nic/'>NIC</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/resource-group/'>Resource Group</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-network/'>Virtual Network</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6686/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6686&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/06/03/use-the-azure-resource-manager-copy-operation-to-deploy-duplicates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/06/arm-resource-group.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/06/arm-resource-group.png?w=150" medium="image">
			<media:title type="html">ARM Resource Group</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Protect Mission Critial #Azure Virtual Machines from Accidental Deletion</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/05/26/protect-mission-critial-azure-virtual-machines-from-accidental-deletion/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/05/26/protect-mission-critial-azure-virtual-machines-from-accidental-deletion/#comments</comments>
		<pubDate>Tue, 26 May 2015 22:06:11 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Azure Resource Manager]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Configurations]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Resource Group]]></category>
		<category><![CDATA[Resource Lock]]></category>
		<category><![CDATA[Virtual Machine]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6648</guid>
		<description><![CDATA[<blockquote>Accidents happen. Resource Locks help prevent them.</blockquote>
The <strong>Resource Lock</strong> level is applied at the resource group or resource scope. These can be set by the administrators and current values include <strong>CanNotDelete</strong> and <strong>ReadOnly</strong>.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6648&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/05/26/protect-mission-critial-azure-virtual-machines-from-accidental-deletion/" target="_blank" title="Protect Mission Critial #Azure Virtual Machines from Accidental&nbsp;Deletion"><img width="565" height="292" src="https://alexandrebrisebois.files.wordpress.com/2015/05/7279664108_f758f0b4a0_z.jpg?w=565" class="attachment-large wp-post-image" alt="lockdown" /></a></p><h1>Lock it Down!</h1>
<blockquote><p>Accidents happen. Resource Locks help prevent them.</p></blockquote>
<p>The <strong>Resource Lock</strong> level is applied at the resource group or resource scope. These can be set by the administrators and current values include <strong>CanNotDelete</strong> and <strong>ReadOnly</strong>.</p>
<p>Using a modified version of the ARM Template from a post on <a title="creating a CentOS Virtual Machine" href="https://alexandrebrisebois.wordpress.com/2015/05/25/create-a-centos-virtual-machine-using-azure-resource-manager-arm/" target="_blank">creating a CentOS Virtual Machine</a>, let&#8217;s provision a VM and protect it from accidental deletion.</p>
<p>As a best practice, we should consider implementing Resource Locks for mission critical resources.<span id="more-6648"></span></p>
<h2>The Azure Resource Manager (ARM) Template</h2>
<p>To make things easy to follow, both data disks and the Custom Script for Linux Virtual Machine extension were removed from the ARM Template.</p>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;newStorageAccountName&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique DNS Name for the Storage Account where the Virtual Machine's disks will be placed.&quot;
            }
        },
        &quot;adminUsername&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;User name for the Virtual Machine.&quot;
            }
        },
        &quot;adminPassword&quot;: {
            &quot;type&quot;: &quot;securestring&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Password for the Virtual Machine.&quot;
            }
        },
        &quot;dnsNameForPublicIP&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique DNS Name for the Public IP used to access the Virtual Machine.&quot;
            }
        },
        &quot;OSVersion&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;defaultValue&quot;: &quot;7.1&quot;,
            &quot;allowedValues&quot;: [
                &quot;7.1&quot;
            ]
        }
    },
    &quot;variables&quot;: {
        &quot;addressPrefix&quot;: &quot;10.0.0.0/16&quot;,
        &quot;dataDiskSize&quot;: &quot;100&quot;,
        &quot;imageOffer&quot;: &quot;CentOS&quot;,
        &quot;imagePublisher&quot;: &quot;OpenLogic&quot;,
        &quot;location&quot;: &quot;West US&quot;,
        &quot;nicName&quot;: &quot;myVMNic&quot;,
        &quot;OSDiskName&quot;: &quot;osdisk&quot;,
        &quot;publicIPAddressType&quot;: &quot;Dynamic&quot;,
        &quot;scriptUrl&quot;: &quot;https://briseboispackages.blob.core.windows.net/linux/centos-vm-disk-utils-0.1.sh&quot;,
        &quot;storageAccountType&quot;: &quot;Standard_LRS&quot;,
        &quot;subnetName&quot;: &quot;Subnet&quot;,
        &quot;subnetPrefix&quot;: &quot;10.0.0.0/24&quot;,
        &quot;subnetRef&quot;: &quot;[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]&quot;,
        &quot;virtualNetworkName&quot;: &quot;MyVNET&quot;,
        &quot;vmName&quot;: &quot;msbriseboislinux&quot;,
        &quot;vmSize&quot;: &quot;Standard_A3&quot;,
        &quot;vmStorageAccountContainerName&quot;: &quot;vhds&quot;,
        &quot;vnetID&quot;: &quot;[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]&quot;
    },
    &quot;resources&quot;: [
        {
            &quot;type&quot;: &quot;Microsoft.Storage/storageAccounts&quot;,
            &quot;name&quot;: &quot;[parameters('newStorageAccountName')]&quot;,
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;StorageAccount&quot;
            },
            &quot;properties&quot;: {
                &quot;accountType&quot;: &quot;[variables('storageAccountType')]&quot;
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/publicIPAddresses&quot;,
            &quot;name&quot;: &quot;[parameters('dnsNameForPublicIP')]&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;PublicIPAddress&quot;
            },
            &quot;properties&quot;: {
                &quot;publicIPAllocationMethod&quot;: &quot;[variables('publicIPAddressType')]&quot;,
                &quot;dnsSettings&quot;: {
                    &quot;domainNameLabel&quot;: &quot;[parameters('dnsNameForPublicIP')]&quot;
                }
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/virtualNetworks&quot;,
            &quot;name&quot;: &quot;[variables('virtualNetworkName')]&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;VirtualNetwork&quot;
            },
            &quot;properties&quot;: {
                &quot;addressSpace&quot;: {
                    &quot;addressPrefixes&quot;: [
                        &quot;[variables('addressPrefix')]&quot;
                    ]
                },
                &quot;subnets&quot;: [
                    {
                        &quot;name&quot;: &quot;[variables('subnetName')]&quot;,
                        &quot;properties&quot;: {
                            &quot;addressPrefix&quot;: &quot;[variables('subnetPrefix')]&quot;
                        }
                    }
                ]
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/networkInterfaces&quot;,
            &quot;name&quot;: &quot;[variables('nicName')]&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;NetworkInterface&quot;
            },
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Network/publicIPAddresses/', parameters('dnsNameForPublicIP'))]&quot;,
                &quot;[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]&quot;
            ],
            &quot;properties&quot;: {
                &quot;ipConfigurations&quot;: [
                    {
                        &quot;name&quot;: &quot;ipconfig1&quot;,
                        &quot;properties&quot;: {
                            &quot;privateIPAllocationMethod&quot;: &quot;Dynamic&quot;,
                            &quot;publicIPAddress&quot;: {
                                &quot;id&quot;: &quot;[resourceId('Microsoft.Network/publicIPAddresses',parameters('dnsNameForPublicIP'))]&quot;
                            },
                            &quot;subnet&quot;: {
                                &quot;id&quot;: &quot;[variables('subnetRef')]&quot;
                            }
                        }
                    }
                ]
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Compute/virtualMachines&quot;,
            &quot;name&quot;: &quot;[variables('vmName')]&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;VirtualMachine&quot;
            },
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'))]&quot;,
                &quot;[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]&quot;
            ],
            &quot;properties&quot;: {
                &quot;hardwareProfile&quot;: {
                    &quot;vmSize&quot;: &quot;[variables('vmSize')]&quot;
                },
                &quot;networkProfile&quot;: {
                    &quot;networkInterfaces&quot;: [
                        {
                            &quot;id&quot;: &quot;[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]&quot;
                        }
                    ]
                },
                &quot;osProfile&quot;: {
                    &quot;computername&quot;: &quot;[variables('vmName')]&quot;,
                    &quot;adminUsername&quot;: &quot;[parameters('adminUsername')]&quot;,
                    &quot;adminPassword&quot;: &quot;[parameters('adminPassword')]&quot;
                },
                &quot;storageProfile&quot;: {
                    &quot;imageReference&quot;: {
                        &quot;publisher&quot;: &quot;[variables('imagePublisher')]&quot;,
                        &quot;offer&quot;: &quot;[variables('imageOffer')]&quot;,
                        &quot;sku&quot;: &quot;[parameters('OSVersion')]&quot;,
                        &quot;version&quot;: &quot;latest&quot;
                    },
                    &quot;osDisk&quot;: {
                        &quot;name&quot;: &quot;osdisk&quot;,
                        &quot;vhd&quot;: {
                            &quot;uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]&quot;
                        },
                        &quot;caching&quot;: &quot;ReadWrite&quot;,
                        &quot;createOption&quot;: &quot;FromImage&quot;
                    }
                }
            }
        }
    ]
}
</pre>
<h3>Template Parameters</h3>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;newStorageAccountName&quot;: {
            &quot;value&quot;: &quot;mslinuxbrisebois&quot;
        },
        &quot;adminUsername&quot;: {
            &quot;value&quot;: &quot;brisebois&quot;
        },
        &quot;dnsNameForPublicIP&quot;: {
            &quot;value&quot;: &quot;briseboisdns&quot;
        }
    }
}
</pre>
<h2>Deploying the Template to Azure</h2>
<p>To deploy the ARM Template, navigate to the folder that contains both the template and parameter files. Then call the New-AzureResourceGroup cmdlet.</p>
<pre class="brush: powershell; title: ; notranslate">
Switch-AzureMode AzureResourceManager

New-AzureResourceGroup -Name 'mslinuxbrisebois' `
                       -Location 'westus' `
                       -TemplateFile 'DeploymentTemplate.json' `
                       -TemplateParameterFile 'DeploymentTemplate.param.dev.json' `
                       -Verbose
</pre>
<h3>Creating a Resource Lock</h3>
<p>Resource Locks can be applied on Resource Groups and on individual Resources like VMs and Storage Accounts. In this example, we are locking a Virtual Machine so that it cannot be deleted by accident.</p>
<pre class="brush: powershell; title: ; notranslate">
New-AzureResourceLock -LockLevel CanNotDelete `
                      -LockNotes 'Critial Virtual Machine, do not delete.' `
                      -LockName 'msbriseboislinuxlock' `
                      -ResourceName 'msbriseboislinux' `
                      -ResourceType 'Microsoft.Compute/virtualMachines' `
                      -ResourceGroupName 'mslinuxbrisebois' `
                      -Verbose
</pre>
<h2>Deleting the Resource Group</h2>
<p>To show what happens when we try to delete a Resource Group that contains a Resource Lock, we can execute the Remove-AzureResourceGroup cmdlet.</p>
<pre class="brush: powershell; title: ; notranslate">
Remove-AzureResourceGroup -Name 'mslinuxbrisebois'
</pre>
<p>The cmdlet should fail with an error similar to the following.</p>
<pre class="brush: powershell; title: ; notranslate">
Remove-AzureResourceGroup : ScopeLocked: The scope
'/subscriptions/64668628-d5e6-4c5b-9be4-9e577d5b8fd0/resourcegroups/mslinuxbrisebois' cannot perform delete operation because
following scope(s) are locked: '/subscriptions/64668628-d5e6-4c5b-9be4-9e577d5b8fd0/resourceGroups/mslinuxbrisebois/providers/Mi
crosoft.Compute/virtualMachines/msbriseboislinux'. Please remove the lock and try again.
At line:1 char:1
+ Remove-AzureResourceGroup -Name 'mslinuxbrisebois'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : CloseError: (:) [Remove-AzureResourceGroup], CloudException
    + FullyQualifiedErrorId : Microsoft.Azure.Commands.Resources.RemoveAzureResourceGroupCommand
</pre>
<h3>Removing the Resource Lock &amp; Deleting the Resource Group</h3>
<p>Deleting a Resource Group that contains Resources Lock requires us to start by removing all Locks. Then we can use the Remove-AzureResourceGroup cmdlet to delete the Resource Group.</p>
<pre class="brush: powershell; title: ; notranslate">
# remove the lock before the resource group
Get-AzureResourceLock -ResourceGroupName 'mslinuxbrisebois' `
                      -ResourceName 'msbriseboislinux' `
                      -ResourceType 'Microsoft.Compute/virtualMachines' `
| Remove-AzureResourceLock

Remove-AzureResourceGroup -Name 'mslinuxbrisebois'
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/arm/'>ARM</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-resource-manager/'>Azure Resource Manager</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/best-practices/'>Best Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/centos/'>CentOS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configurations/'>Configurations</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/json/'>JSON</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/linux/'>Linux</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/resource-group/'>Resource Group</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/resource-lock/'>Resource Lock</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6648/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6648/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6648/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6648/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6648/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6648/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6648/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6648/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6648/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6648/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6648/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6648/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6648/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6648/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6648&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/05/26/protect-mission-critial-azure-virtual-machines-from-accidental-deletion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/05/7279664108_f758f0b4a0_z.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/05/7279664108_f758f0b4a0_z.jpg?w=150" medium="image">
			<media:title type="html">lockdown</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Create a CentOS Virtual Machine Using #Azure Resource Manager (ARM)</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/05/25/create-a-centos-virtual-machine-using-azure-resource-manager-arm/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/05/25/create-a-centos-virtual-machine-using-azure-resource-manager-arm/#comments</comments>
		<pubDate>Mon, 25 May 2015 15:42:34 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Azure Resource Manager]]></category>
		<category><![CDATA[Azure VM Image]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Data Disk]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OS Disk]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Virtual Machine]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6610</guid>
		<description><![CDATA[Creating a CentOS VM Using ARM Docker and Open Source projects are getting lots of attention, so I decided that it was time for me to build a Linux Virtual Machine on Microsoft Azure. This post is all about creating an Azure Resource Manager Template for a CentOS Virtual Machine with two stripped Data Disks. [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6610&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/05/25/create-a-centos-virtual-machine-using-azure-resource-manager-arm/" target="_blank" title="Create a CentOS Virtual Machine Using #Azure Resource Manager&nbsp;(ARM)"><img width="580" height="339" src="https://alexandrebrisebois.files.wordpress.com/2015/05/centos-azure.png?w=580" class="attachment-large wp-post-image" alt="CentOs-Azure" /></a></p><h1>Creating a CentOS VM Using ARM</h1>
<p>Docker and Open Source projects are getting lots of attention, so I decided that it was time for me to build a Linux Virtual Machine on Microsoft Azure. This post is all about creating an Azure Resource Manager Template for a CentOS Virtual Machine with two stripped Data Disks. This template should be used as a starting point and may require some tweaking to meet your needs. Feel free to share your thoughts by using the comment section.<span id="more-6610"></span></p>
<h2>Finding a CentOS VM Image</h2>
<p>Using our favorite PowerShell tools, we can discover details about pre-built CentOS 7.1 Azure Virtual Images. </p>
<pre class="brush: powershell; title: ; notranslate">
Switch-AzureMode -Name AzureResourceManager

$location = 'westus'

Get-AzureVMImagePublisher -Location $location

$publisherName = 'OpenLogic'

Get-AzureVMImageOffer -Location $location `
                      -PublisherName $publisherName
$offer = 'CentOS'

Get-AzureVMImageSku -Location $location `
                    -PublisherName $publisherName `
                    -Offer $offer `
    | Select-Object -Property 'Skus'

$sku = '7.1'
                                 
Get-AzureVMImage -Location $location `
                 -PublisherName $publisherName `
                 -Offer $offer `
                 -Skus $sku

$verison = '7.1.201504'

Get-AzureVMImageDetail -Location $location `
                       -PublisherName $publisherName `
                       -Offer $offer `
                       -Skus $sku `
                       -Version $verison
</pre>
<h2>Building the ARM Template</h2>
<p>Starting from the Ubuntu Template in Visual Studio we can use the CentOS Virtual Image information, found in the previous section of this post, to create a CentOS 7.1 Standard_A3 Virtual Machine. To regroup the data disks as a RAID0 volume we can use the <a href="https://github.com/Azure/azure-quickstart-templates/tree/master/diskraid-ubuntu-vm" target="_blank">Create Ubuntu vm data disk raid0</a> template as a guide. Then we can make small changes to reach our goal.</p>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;newStorageAccountName&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique DNS Name for the Storage Account where the Virtual Machine's disks will be placed.&quot;
            }
        },
        &quot;adminUsername&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;User name for the Virtual Machine.&quot;
            }
        },
        &quot;adminPassword&quot;: {
            &quot;type&quot;: &quot;securestring&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Password for the Virtual Machine.&quot;
            }
        },
        &quot;dnsNameForPublicIP&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique DNS Name for the Public IP used to access the Virtual Machine.&quot;
            }
        },
        &quot;OSVersion&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;defaultValue&quot;: &quot;7.1&quot;,
            &quot;allowedValues&quot;: [
                &quot;7.1&quot;
            ]
        }
    },
    &quot;variables&quot;: {
        &quot;addressPrefix&quot;: &quot;10.0.0.0/16&quot;,
        &quot;dataDiskSize&quot;: &quot;100&quot;,
        &quot;imageOffer&quot;: &quot;CentOS&quot;,
        &quot;imagePublisher&quot;: &quot;OpenLogic&quot;,
        &quot;location&quot;: &quot;West US&quot;,
        &quot;nicName&quot;: &quot;myVMNic&quot;,
        &quot;OSDiskName&quot;: &quot;osdisk&quot;,
        &quot;publicIPAddressType&quot;: &quot;Dynamic&quot;,
        &quot;scriptUrl&quot;: &quot;https://briseboispackages.blob.core.windows.net/linux/centos-vm-disk-utils-0.1.sh&quot;,
        &quot;storageAccountType&quot;: &quot;Standard_LRS&quot;,
        &quot;subnetName&quot;: &quot;Subnet&quot;,
        &quot;subnetPrefix&quot;: &quot;10.0.0.0/24&quot;,
        &quot;subnetRef&quot;: &quot;[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]&quot;,
        &quot;virtualNetworkName&quot;: &quot;MyVNET&quot;,
        &quot;vmName&quot;: &quot;msbriseboislinux&quot;,
        &quot;vmSize&quot;: &quot;Standard_A3&quot;,
        &quot;vmStorageAccountContainerName&quot;: &quot;vhds&quot;,
        &quot;vnetID&quot;: &quot;[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]&quot;
    },
    &quot;resources&quot;: [
        {
            &quot;type&quot;: &quot;Microsoft.Storage/storageAccounts&quot;,
            &quot;name&quot;: &quot;[parameters('newStorageAccountName')]&quot;,
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;StorageAccount&quot;
            },
            &quot;properties&quot;: {
                &quot;accountType&quot;: &quot;[variables('storageAccountType')]&quot;
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/publicIPAddresses&quot;,
            &quot;name&quot;: &quot;[parameters('dnsNameForPublicIP')]&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;PublicIPAddress&quot;
            },
            &quot;properties&quot;: {
                &quot;publicIPAllocationMethod&quot;: &quot;[variables('publicIPAddressType')]&quot;,
                &quot;dnsSettings&quot;: {
                    &quot;domainNameLabel&quot;: &quot;[parameters('dnsNameForPublicIP')]&quot;
                }
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/virtualNetworks&quot;,
            &quot;name&quot;: &quot;[variables('virtualNetworkName')]&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;VirtualNetwork&quot;
            },
            &quot;properties&quot;: {
                &quot;addressSpace&quot;: {
                    &quot;addressPrefixes&quot;: [
                        &quot;[variables('addressPrefix')]&quot;
                    ]
                },
                &quot;subnets&quot;: [
                    {
                        &quot;name&quot;: &quot;[variables('subnetName')]&quot;,
                        &quot;properties&quot;: {
                            &quot;addressPrefix&quot;: &quot;[variables('subnetPrefix')]&quot;
                        }
                    }
                ]
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/networkInterfaces&quot;,
            &quot;name&quot;: &quot;[variables('nicName')]&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;NetworkInterface&quot;
            },
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Network/publicIPAddresses/', parameters('dnsNameForPublicIP'))]&quot;,
                &quot;[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]&quot;
            ],
            &quot;properties&quot;: {
                &quot;ipConfigurations&quot;: [
                    {
                        &quot;name&quot;: &quot;ipconfig1&quot;,
                        &quot;properties&quot;: {
                            &quot;privateIPAllocationMethod&quot;: &quot;Dynamic&quot;,
                            &quot;publicIPAddress&quot;: {
                                &quot;id&quot;: &quot;[resourceId('Microsoft.Network/publicIPAddresses',parameters('dnsNameForPublicIP'))]&quot;
                            },
                            &quot;subnet&quot;: {
                                &quot;id&quot;: &quot;[variables('subnetRef')]&quot;
                            }
                        }
                    }
                ]
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Compute/virtualMachines&quot;,
            &quot;name&quot;: &quot;[variables('vmName')]&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;VirtualMachine&quot;
            },
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'))]&quot;,
                &quot;[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]&quot;
            ],
            &quot;properties&quot;: {
                &quot;hardwareProfile&quot;: {
                    &quot;vmSize&quot;: &quot;[variables('vmSize')]&quot;
                },
                &quot;osProfile&quot;: {
                    &quot;computername&quot;: &quot;[variables('vmName')]&quot;,
                    &quot;adminUsername&quot;: &quot;[parameters('adminUsername')]&quot;,
                    &quot;adminPassword&quot;: &quot;[parameters('adminPassword')]&quot;
                },
                &quot;storageProfile&quot;: {
                    &quot;imageReference&quot;: {
                        &quot;publisher&quot;: &quot;[variables('imagePublisher')]&quot;,
                        &quot;offer&quot;: &quot;[variables('imageOffer')]&quot;,
                        &quot;sku&quot;: &quot;[parameters('OSVersion')]&quot;,
                        &quot;version&quot;: &quot;latest&quot;
                    },
                    &quot;osDisk&quot;: {
                        &quot;name&quot;: &quot;osdisk&quot;,
                        &quot;vhd&quot;: {
                            &quot;uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]&quot;
                        },
                        &quot;caching&quot;: &quot;ReadWrite&quot;,
                        &quot;createOption&quot;: &quot;FromImage&quot;
                    },
                    &quot;dataDisks&quot;: [
                        {
                            &quot;name&quot;: &quot;datadisk1&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('dataDiskSize')]&quot;,
                            &quot;lun&quot;: 0,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/vhds/',variables('vmName'),'dataDisk1' ,'.vhd')]&quot;
                            },
                            &quot;caching&quot;: &quot;None&quot;,
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk2&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('dataDiskSize')]&quot;,
                            &quot;lun&quot;: 1,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/vhds/',variables('vmName') ,'dataDisk2','.vhd')]&quot;
                            },
                            &quot;caching&quot;: &quot;None&quot;,
                            &quot;createOption&quot;: &quot;Empty&quot;
                        }
                    ]
                },
                &quot;networkProfile&quot;: {
                    &quot;networkInterfaces&quot;: [
                        {
                            &quot;id&quot;: &quot;[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]&quot;
                        }
                    ]
                }
            }
        },
        {
            &quot;type&quot;: &quot;Microsoft.Compute/virtualMachines/extensions&quot;,
            &quot;name&quot;: &quot;[concat(variables('vmName'), '/azureVmUtils')]&quot;,
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;location&quot;: &quot;[variables('location')]&quot;,
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]&quot;
            ],
            &quot;properties&quot;: {
                &quot;publisher&quot;: &quot;Microsoft.OSTCExtensions&quot;,
                &quot;type&quot;: &quot;CustomScriptForLinux&quot;,
                &quot;typeHandlerVersion&quot;: &quot;1.2&quot;,
                &quot;settings&quot;: {
                    &quot;fileUris&quot;: [
                        &quot;[variables('scriptUrl')]&quot;
                    ],
                    &quot;commandToExecute&quot;: &quot;bash vm-disk-utils-0.1.sh -s&quot;
                }
            }
        }
    ]
}
</pre>
<h2>Publishing the ARM Template</h2>
<p>Prepare the Template Parameter File</p>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.0&quot;,
    &quot;parameters&quot;: {
        &quot;newStorageAccountName&quot;: {
            &quot;value&quot;: &quot;mslinuxbrisebois&quot;
        },
        &quot;adminUsername&quot;: {
            &quot;value&quot;: &quot;brisebois&quot;
        },
        &quot;dnsNameForPublicIP&quot;: {
            &quot;value&quot;: &quot;briseboisdns&quot;
        }
    }
}
</pre>
<p>Then deploy the Azure Resource Manager Template and Parameters using PowerShell.</p>
<pre class="brush: powershell; title: ; notranslate">
Set-AzureSubscription -SubscriptionName (Get-AzureSubscription -Current).SubscriptionName `
                      -CurrentStorageAccountName 'briseboispackages'

Switch-AzureMode AzureResourceManager

New-AzureResourceGroup -Name 'mslinuxbrisebois' `
                       -Location 'westus' `
                       -TemplateFile 'LinuxVirtualMachine.json' `
                       -TemplateParameterFile 'LinuxVirtualMachine.param.dev.json' `
                       -Force -Verbose

# New-AzureResourceGroup VERBOSE Log

VERBOSE: 10:15:18 AM - Created resource group 'mslinuxbrisebois' in location 'westus'
VERBOSE: 10:15:19 AM - Template is valid.
VERBOSE: 10:15:21 AM - Create template deployment 'LinuxVirtualMachine'.
VERBOSE: 10:15:24 AM - Resource Microsoft.Storage/storageAccounts 'mslinuxbrisebois1' provisioning status is running
VERBOSE: 10:15:34 AM - Resource Microsoft.Network/publicIPAddresses 'briseboisdns' provisioning status is running
VERBOSE: 10:15:36 AM - Resource Microsoft.Network/virtualNetworks 'MyVNET' provisioning status is running
VERBOSE: 10:15:46 AM - Resource Microsoft.Network/virtualNetworks 'MyVNET' provisioning status is succeeded
VERBOSE: 10:15:49 AM - Resource Microsoft.Network/publicIPAddresses 'briseboisdns' provisioning status is succeeded
VERBOSE: 10:15:51 AM - Resource Microsoft.Network/networkInterfaces 'myVMNic' provisioning status is succeeded
VERBOSE: 10:15:58 AM - Resource Microsoft.Storage/storageAccounts 'mslinuxbrisebois1' provisioning status is succeeded
VERBOSE: 10:16:03 AM - Resource Microsoft.Compute/virtualMachines 'msbriseboislinux1' provisioning status is running
VERBOSE: 10:18:16 AM - Resource Microsoft.Compute/virtualMachines 'msbriseboislinux1' provisioning status is succeeded
VERBOSE: 10:18:21 AM - Resource Microsoft.Compute/virtualMachines/extensions 'msbriseboislinux1/azureVmUtils' provisioning status is running
VERBOSE: 10:20:55 AM - Resource Microsoft.Compute/virtualMachines/extensions 'msbriseboislinux1/azureVmUtils' provisioning status is succeeded
</pre>
<p>This template will use the following script inspired by <a href="https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/shared_scripts/ubuntu/vm-disk-utils-0.1.sh" target="_blank">vm-disk-utils-0.1.sh</a> for Ubuntu to create a <strong>RAID0</strong> out of all the unformated data disks. A small modification has been applied for this to work on CentOS.</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash

# The MIT License (MIT)
#
# Copyright (c) 2015 Microsoft Azure
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the &quot;Software&quot;), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Script Name: centos-vm-disk-utils.sh
# Author: Trent Swanson - Full Scale 180 Inc github:(trentmswanson)
# Version: 0.1
# Last Modified By: Alexandre Brisebois
# Description:
#  This script automates the partitioning and formatting of data disks
#  Data disks can be partitioned and formatted as seperate disks or in a RAID0 configuration
#  The scrtip will scan for unpartitioined and unformatted data disks and partition, format, and add fstab entries
# Parameters :
#  1 - b: The base directory for mount points (default: /datadisks)
#  2 - s  Create a striped RAID0 Array (No redundancy)
#  3 - h  Help 
# Note : 
# This script has only been tested on CentOS 7.1 and must be root

help()
{
    echo &quot;Usage: $(basename $0) [-b data_base] [-h] [-s]&quot;
    echo &quot;&quot;
    echo &quot;Options:&quot;
    echo &quot;   -b         base directory for mount points (default: /datadisks)&quot;
    echo &quot;   -h         this help message&quot;
    echo &quot;   -s         create a striped RAID array (no redundancy)&quot;
}

log()
{
    # Un-comment the following if you would like to enable logging to a service
    #curl -X POST -H &quot;content-type:text/plain&quot; --data-binary &quot;${HOSTNAME} - $1&quot; https://logs-01.loggly.com/inputs/&lt;key&gt;/tag/es-extension,${HOSTNAME}
    echo &quot;$1&quot;
}

if [ &quot;${UID}&quot; -ne 0 ];
then
    log &quot;Script executed without root permissions&quot;
    echo &quot;You must be root to run this program.&quot; &gt;&amp;2
    exit 3
fi

#A set of disks to ignore from partitioning and formatting
BLACKLIST=&quot;/dev/sda|/dev/sdb&quot;

# Base path for data disk mount points
DATA_BASE=&quot;/datadisks&quot;

while getopts b:sh optname; do
    log &quot;Option $optname set with value ${OPTARG}&quot;
  case ${optname} in
    b)  #set clsuter name
      DATA_BASE=${OPTARG}
      ;;
    s) #Partition and format data disks as raid set
      RAID_CONFIGURATION=1
      ;;
    h)  #show help
      help
      exit 2
      ;;
    \?) #unrecognized option - show help
      echo -e \\n&quot;Option -${BOLD}$OPTARG${NORM} not allowed.&quot;
      help
      exit 2
      ;;
  esac
done

get_next_md_device() {
    shopt -s extglob
    LAST_DEVICE=$(ls -1 /dev/md+([0-9]) 2&gt;/dev/null|sort -n|tail -n1)
    if [ -z &quot;${LAST_DEVICE}&quot; ]; then
        NEXT=/dev/md0
    else
        NUMBER=$((${LAST_DEVICE/\/dev\/md/}))
        NEXT=/dev/md${NUMBER}
    fi
    echo ${NEXT}
}

is_partitioned() {
    OUTPUT=$(partx -s ${1} 2&gt;&amp;1)
    egrep &quot;partition table does not contains usable partitions|failed to read partition table&quot; &lt;&lt;&lt; &quot;${OUTPUT}&quot; &gt;/dev/null 2&gt;&amp;1
    if [ ${?} -eq 0 ]; then
        return 1
    else
        return 0
    fi    
}

has_filesystem() {
    DEVICE=${1}
    OUTPUT=$(file -L -s ${DEVICE})
    grep filesystem &lt;&lt;&lt; &quot;${OUTPUT}&quot; &gt; /dev/null 2&gt;&amp;1
    return ${?}
}

scan_for_new_disks() {
    # Looks for unpartitioned disks
    declare -a RET
    DEVS=($(ls -1 /dev/sd*|egrep -v &quot;${BLACKLIST}&quot;|egrep -v &quot;[0-9]$&quot;))
    for DEV in &quot;${DEVS[@]}&quot;;
    do
        # The disk will be considered a candidate for partitioning
        # and formatting if it does not have a sd?1 entry or
        # if it does have an sd?1 entry and does not contain a filesystem
        is_partitioned &quot;${DEV}&quot;
        if [ ${?} -eq 0 ];
        then
            has_filesystem &quot;${DEV}1&quot;
            if [ ${?} -ne 0 ];
            then
                RET+=&quot; ${DEV}&quot;
            fi
        else
            RET+=&quot; ${DEV}&quot;
        fi
    done
    echo &quot;${RET}&quot;
}

get_next_mountpoint() {
    DIRS=$(ls -1d ${DATA_BASE}/disk* 2&gt;/dev/null| sort --version-sort)
    MAX=$(echo &quot;${DIRS}&quot;|tail -n 1 | tr -d &quot;[a-zA-Z/]&quot;)
    if [ -z &quot;${MAX}&quot; ];
    then
        echo &quot;${DATA_BASE}/disk1&quot;
        return
    fi
    IDX=1
    while [ &quot;${IDX}&quot; -lt &quot;${MAX}&quot; ];
    do
        NEXT_DIR=&quot;${DATA_BASE}/disk${IDX}&quot;
        if [ ! -d &quot;${NEXT_DIR}&quot; ];
        then
            echo &quot;${NEXT_DIR}&quot;
            return
        fi
        IDX=$(( ${IDX} + 1 ))
    done
    IDX=$(( ${MAX} + 1))
    echo &quot;${DATA_BASE}/disk${IDX}&quot;
}

add_to_fstab() {
    UUID=${1}
    MOUNTPOINT=${2}
    grep &quot;${UUID}&quot; /etc/fstab &gt;/dev/null 2&gt;&amp;1
    if [ ${?} -eq 0 ];
    then
        echo &quot;Not adding ${UUID} to fstab again (it's already there!)&quot;
    else
        LINE=&quot;UUID=\&quot;${UUID}\&quot;\t${MOUNTPOINT}\text4\tnoatime,nodiratime,nodev,noexec,nosuid\t1 2&quot;
        echo -e &quot;${LINE}&quot; &gt;&gt; /etc/fstab
    fi
}

do_partition() {
# This function creates one (1) primary partition on the
# disk, using all available space
    _disk=${1}
    _type=${2}
    if [ -z &quot;${_type}&quot; ]; then
        # default to Linux partition type (ie, ext3/ext4/xfs)
        _type=83
    fi
    echo &quot;n
p
1


t
${_type}
w&quot;| fdisk &quot;${_disk}&quot;

#
# Use the bash-specific $PIPESTATUS to ensure we get the correct exit code
# from fdisk and not from echo
if [ ${PIPESTATUS[1]} -ne 0 ];
then
    echo &quot;An error occurred partitioning ${_disk}&quot; &gt;&amp;2
    echo &quot;I cannot continue&quot; &gt;&amp;2
    exit 2
fi
}
#end do_partition

scan_partition_format()
{
    log &quot;Begin scanning and formatting data disks&quot;

    DISKS=($(scan_for_new_disks))

    if [ &quot;${#DISKS}&quot; -eq 0 ];
    then
        log &quot;No unpartitioned disks without filesystems detected&quot;
        return
    fi
    echo &quot;Disks are ${DISKS[@]}&quot;
    for DISK in &quot;${DISKS[@]}&quot;;
    do
        echo &quot;Working on ${DISK}&quot;
        is_partitioned ${DISK}
        if [ ${?} -ne 0 ];
        then
            echo &quot;${DISK} is not partitioned, partitioning&quot;
            do_partition ${DISK}
        fi
        PARTITION=$(fdisk -l ${DISK}|grep -A 1 Device|tail -n 1|awk '{print $1}')
        has_filesystem ${PARTITION}
        if [ ${?} -ne 0 ];
        then
            echo &quot;Creating filesystem on ${PARTITION}.&quot;
    #        echo &quot;Press Ctrl-C if you don't want to destroy all data on ${PARTITION}&quot;
    #        sleep 10
            mkfs -j -t ext4 ${PARTITION}
        fi
        MOUNTPOINT=$(get_next_mountpoint)
        echo &quot;Next mount point appears to be ${MOUNTPOINT}&quot;
        [ -d &quot;${MOUNTPOINT}&quot; ] || mkdir -p &quot;${MOUNTPOINT}&quot;
        read UUID FS_TYPE &lt; &lt;(blkid -u filesystem ${PARTITION}|awk -F &quot;[= ]&quot; '{print $3&quot; &quot;$5}'|tr -d &quot;\&quot;&quot;)
        add_to_fstab &quot;${UUID}&quot; &quot;${MOUNTPOINT}&quot;
        echo &quot;Mounting disk ${PARTITION} on ${MOUNTPOINT}&quot;
        mount &quot;${MOUNTPOINT}&quot;
    done
}

create_striped_volume()
{
    DISKS=(${@})

    if [ &quot;${#DISKS[@]}&quot; -eq 0 ];
    then
        log &quot;No unpartitioned disks without filesystems detected&quot;
        return
    fi

    echo &quot;Disks are ${DISKS[@]}&quot;

    declare -a PARTITIONS

    for DISK in &quot;${DISKS[@]}&quot;;
    do
        echo &quot;Working on ${DISK}&quot;
        is_partitioned ${DISK}
        if [ ${?} -ne 0 ];
        then
            echo &quot;${DISK} is not partitioned, partitioning&quot;
            do_partition ${DISK} fd
        fi

        PARTITION=$(fdisk -l ${DISK}|grep -A 2 Device|tail -n 1|awk '{print $1}')
        PARTITIONS+=(&quot;${PARTITION}&quot;)
    done

    MDDEVICE=$(get_next_md_device)    
    
    mdadm --create ${MDDEVICE} --level 0 --raid-devices ${#PARTITIONS[@]} ${PARTITIONS[*]}

    MOUNTPOINT=$(get_next_mountpoint)
    echo &quot;Next mount point appears to be ${MOUNTPOINT}&quot;
    [ -d &quot;${MOUNTPOINT}&quot; ] || mkdir -p &quot;${MOUNTPOINT}&quot;

    #Make a file system on the new device
    mkfs -t ext4 &quot;${MDDEVICE}&quot;

    read UUID FS_TYPE &lt; &lt;(blkid -u filesystem ${MDDEVICE}|awk -F &quot;[= ]&quot; '{print $3&quot; &quot;$5}'|tr -d &quot;\&quot;&quot;)

    add_to_fstab &quot;${UUID}&quot; &quot;${MOUNTPOINT}&quot;

    mount &quot;${MOUNTPOINT}&quot;
}

check_mdadm() {
    rpm -ql mdadm &gt;/dev/null 2&gt;&amp;1
    if [ ${?} -ne 0 ]; then
        yum clean all
        yum update
        yum install mdadm -y
    fi
}

# Create Partitions
DISKS=$(scan_for_new_disks)

if [ &quot;$RAID_CONFIGURATION&quot; -eq 1 ]; then
    check_mdadm
    create_striped_volume &quot;${DISKS[@]}&quot;
else
    scan_partition_format
fi
</pre>
<p>Once the Azure Resource Manager Template completed its execution, I opened an SSH session using Putty and verified that our data disks have been stripped and mounted.</p>
<p><img src="https://alexandrebrisebois.files.wordpress.com/2015/05/raid0-on-azure-linux-vm.png?w=580&#038;h=363" alt="RAID0 on Azure Linux VM" width="580" height="363" class="aligncenter size-full wp-image-6642" /><br />
We are now ready to start working with this brand new CentOS Virtual Machine.</p>
<h2>Resources</h2>
<ul>
<li><a href="http://blogs.msdn.com/b/cloud_solution_architect/archive/2015/05/05/creating-azure-vms-with-arm-powershell-cmdlets.aspx" target="_blank">Creating Azure VMs with ARM PowerShell cmdlets</a></li>
<li><a href="http://azure.microsoft.com/en-in/documentation/articles/virtual-machines-linux-use-ssh-key/" target="_blank">How to Use SSH with Linux on Azure</a></li>
<li><a href="http://azure.microsoft.com/en-in/documentation/articles/virtual-machines-linux-use-vmaccess-reset-password-or-ssh/" target="_blank">How to Reset a Password or SSH for Linux Virtual Machines</a></li>
<li><a href="https://github.com/Azure/azure-quickstart-templates" target="_blank">Azure Quickstart Templates</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/arm/'>ARM</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-resource-manager/'>Azure Resource Manager</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-vm-image/'>Azure VM Image</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/centos/'>CentOS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/data-disk/'>Data Disk</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iaas/'>IaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/json/'>JSON</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/linux/'>Linux</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/os-disk/'>OS Disk</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/ssh/'>SSH</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6610/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6610&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/05/25/create-a-centos-virtual-machine-using-azure-resource-manager-arm/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/05/centos-azure.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/05/centos-azure.png?w=150" medium="image">
			<media:title type="html">CentOs-Azure</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/05/raid0-on-azure-linux-vm.png" medium="image">
			<media:title type="html">RAID0 on Azure Linux VM</media:title>
		</media:content>
	</item>
		<item>
		<title>Debugging Desired State Configuration (DSC)  on #Azure VMs</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/05/20/debugging-desired-state-configuration-dsc-on-azure-vms/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/05/20/debugging-desired-state-configuration-dsc-on-azure-vms/#comments</comments>
		<pubDate>Wed, 20 May 2015 18:54:01 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[DSC]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[RDP]]></category>
		<category><![CDATA[Remote Desktop]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6560</guid>
		<description><![CDATA[My previous post was about using the Azure Resource Manager to provision a Virtual Machine. It demonstrated how to use a custom PowerShell Desired State Configuration (DSC) to stripe, format and assign a drive letter to a storage space that contains thirty-two 1TB VHDs. Debugging a custom PowerShell Desired State Configuration was a challenge, because [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6560&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/05/20/debugging-desired-state-configuration-dsc-on-azure-vms/" target="_blank" title="Debugging Desired State Configuration (DSC)  on #Azure&nbsp;VMs"><img width="580" height="326" src="https://alexandrebrisebois.files.wordpress.com/2015/05/bugzapper.jpg?w=580" class="attachment-large wp-post-image" alt="bugzapper" /></a></p><p>My previous post was about using the <a title="Using  Azure Resource Manager (ARM) to Deploy a Monster VM" href="https://alexandrebrisebois.wordpress.com/2015/05/16/using-azure-resource-manager-arm-to-deploy-a-monster-vm/" target="_blank">Azure Resource Manager to provision a Virtual Machine</a>. It demonstrated how to use a custom PowerShell Desired State Configuration (DSC) to stripe, format and assign a drive letter to a storage space that contains thirty-two 1TB VHDs.</p>
<p>Debugging a custom PowerShell Desired State Configuration was a challenge, because I was completely new to PowerShell DSC and to the Azure Virtual Machine DSC Extension. This post is all about how I managed to debug, refine and test using the artifacts created by the Virtual Machine Extension.<span id="more-6560"></span></p>
<h1>Why is my DSC Failing?</h1>
<p>The Azure Virtual Machine Extension for DSC gives us ways to test, debug and refine our Desired State Configurations. Finding that pesky bug can be challenging, don&#8217;t give up! Let&#8217;s take a look at what we should be looking for.</p>
<h2>The Environment</h2>
<p>To have something to work with, we need a Virtual Machine that uses the DSC Extension. So I used the<a title="Using  Azure Resource Manager (ARM) to Deploy a Monster VM" href="https://alexandrebrisebois.wordpress.com/2015/05/16/using-azure-resource-manager-arm-to-deploy-a-monster-vm/" target="_blank"> Azure Resource Manager Template from my previous post</a> to provision a brand-new VM.</p>
<pre class="brush: powershell; title: ; notranslate">
Set-AzureSubscription -SubscriptionName (Get-AzureSubscription -Current).SubscriptionName -CurrentStorageAccountName 'briseboispackages'

$ModuleURL = &quot;https://briseboispackages.blob.core.windows.net/windows-powershell-dsc/DiskConfiguration.ps1.zip&quot;

$additionalParameters = New-Object -TypeName Hashtable
$additionalParameters[&quot;modulesUrl&quot;] = $ModuleURL

Switch-AzureMode AzureResourceManager

New-AzureResourceGroup -Name &quot;armmonstervm&quot; `
                       -Location &quot;westus&quot; `
                       -TemplateFile 'WindowsVirtualMachine.json' `
                       -TemplateParameterFile 'WindowsVirtualMachine.param.dev.json' `
                       @additionalParameters `
                       -Force -Verbose
</pre>
<h4>New-AzureResourceGroup Execution Trace</h4>
<pre class="brush: powershell; title: ; notranslate">
VERBOSE: 10:48:56 AM - Created resource group 'armmonstervm' in location 'westus'
VERBOSE: 10:48:57 AM - Template is valid.
VERBOSE: 10:48:58 AM - Create template deployment 'WindowsVirtualMachine'.
VERBOSE: 10:49:06 AM - Resource Microsoft.Storage/storageAccounts 'msarmbrisebois' provisioning status is running
VERBOSE: 10:49:11 AM - Resource Microsoft.Network/virtualNetworks 'msarmbriseboisvnet' provisioning status is running
VERBOSE: 10:49:13 AM - Resource Microsoft.Network/publicIPAddresses 'PublicIP' provisioning status is running
VERBOSE: 10:49:27 AM - Resource Microsoft.Network/publicIPAddresses 'PublicIP' provisioning status is succeeded
VERBOSE: 10:49:27 AM - Resource Microsoft.Network/virtualNetworks 'msarmbriseboisvnet' provisioning status is succeeded
VERBOSE: 10:49:32 AM - Resource Microsoft.Network/networkInterfaces 'VMNic' provisioning status is succeeded
VERBOSE: 10:49:32 AM - Resource Microsoft.Storage/storageAccounts 'msarmbrisebois' provisioning status is succeeded
VERBOSE: 10:49:40 AM - Resource Microsoft.Compute/virtualMachines 'msarmbrisebois' provisioning status is running
VERBOSE: 11:08:28 AM - Resource Microsoft.Compute/virtualMachines 'msarmbrisebois' provisioning status is succeeded
VERBOSE: 11:08:31 AM - Resource Microsoft.Compute/virtualMachines/extensions 'msarmbrisebois/dscExtension' provisioning status is running
VERBOSE: 11:16:27 AM - Resource Microsoft.Compute/virtualMachines/extensions 'msarmbrisebois/dscExtension' provisioning status is succeeded
</pre>
<p>Now that we have a Virtual Machine to work with, it&#8217;s time to use Remote Desktop.</p>
<pre class="brush: powershell; title: ; notranslate">
Switch-AzureMode AzureResourceManager

Get-AzureRemoteDesktopFile -ResourceGroupName 'armmonstervm' `
                           -Name 'msarmbrisebois' `
                           -LocalPath 'C:\Users\brisebois'
</pre>
<h3>Location of The DSC VM Extension Artifacts</h3>
<p>When the DSC Virtual Machine Extension executes, it installs DSC in <strong>C:\Packages\Plugins\Microsoft.Powershell.DSC\1.7.0.0</strong>. It will also download and extract our DSC Module to <strong>C:\Program Files\WindowsPowerShell\Modules</strong>.</p>
<h4>Location: C:\Packages\Plugins\Microsoft.Powershell.DSC\1.7.0.0</h4>
<p>This folder contains 3 important sub-folders that help us understand what is push to the Virtual Machine from the Azure Resource Manager and the status of the DSC execution.</p>
<h4>RuntimeSettings</h4>
<p>This folder contains the Extension Settings that allow us to validate that we have the correct settings in our Azure Resource Manager Template.</p>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;runtimeSettings&quot;: [{
        &quot;handlerSettings&quot;: {
            &quot;publicSettings&quot;: {
                &quot;ModulesUrl&quot;: &quot;https://briseboispackages.blob.core.windows.net/windows-powershell-dsc/DiskConfiguration.ps1.zip&quot;,
                &quot;SasToken&quot;: &quot;&quot;,
                &quot;ConfigurationFunction&quot;: &quot;DiskConfiguration.ps1\\DiskConfiguration&quot;,
                &quot;Properties&quot;: {
                    &quot;StoragePoolFriendlyName&quot;: &quot;storagespace0&quot;,
                    &quot;VirtualDiskFriendlyName&quot;: &quot;datadisk&quot;,
                    &quot;DriveSize&quot;: 35184372088832,
                    &quot;NumberOfColumns&quot;: 32
                }
            }
        }
    }]
}
</pre>
<h4>DSCWork</h4>
<p>This folder contains the <strong>configuration</strong> and the <strong>localhost.mof</strong> file. Use these assets to replay the DSC as if it were executed by the Extension.</p>
<pre class="brush: powershell; title: ; notranslate">
Start-DscConfiguration -Path 'C:\Packages\Plugins\Microsoft.Powershell.DSC\1.7.0.0\DSCWork\DiskConfiguration.ps1.0\DiskConfiguration' `
                       -ComputerName localhost `
                       -Force `
                       -wait `
                       -Verbose `
                       -Debug
</pre>
<p>This execution produces an output that surfaces issues. Use this to identify where the DSC fails and what to address.</p>
<pre class="brush: powershell; title: ; notranslate">
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSC
LocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer MSARMBRISEBOIS with user sid S-1-5-21-3103417715-464229043-512622935-500.
VERBOSE: An LCM method call arrived from computer MSARMBRISEBOIS with user sid S-1-5-21-3103417715-464229043-512622935-500.
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Set      ]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[StorageSpace]CreateStorageSpace]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[StorageSpace]CreateStorageSpace]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[StorageSpace]CreateStorageSpace]  in 1.5790 seconds.
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Set      ]  [[StorageSpace]CreateStorageSpace]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Set      ]  [[StorageSpace]CreateStorageSpace]  in 62.5030 seconds.
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[StorageSpace]CreateStorageSpace]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[VirtualDisk]CreateVirtualDisk]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[VirtualDisk]CreateVirtualDisk]
DEBUG: [MSARMBRISEBOIS]:                            [[VirtualDisk]CreateVirtualDisk] datadisk
DEBUG: [MSARMBRISEBOIS]:                            [[VirtualDisk]CreateVirtualDisk] False
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[VirtualDisk]CreateVirtualDisk]  in 0.0710 seconds.
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Set      ]  [[VirtualDisk]CreateVirtualDisk]
DEBUG: [MSARMBRISEBOIS]:                            [[VirtualDisk]CreateVirtualDisk] datadisk
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Set      ]  [[VirtualDisk]CreateVirtualDisk]  in 2.4500 seconds.
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[VirtualDisk]CreateVirtualDisk]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[Disk]InitializeDisk]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[Disk]InitializeDisk]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[Disk]InitializeDisk]  in 0.2260 seconds.
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Set      ]  [[Disk]InitializeDisk]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Set      ]  [[Disk]InitializeDisk]  in 0.3820 seconds.
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[Disk]InitializeDisk]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[DiskPartition]CreateDiskPartition]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[DiskPartition]CreateDiskPartition]
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[DiskPartition]CreateDiskPartition]  in 0.1530 seconds.
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ Start  Set      ]  [[DiskPartition]CreateDiskPartition]
Invalid Parameter
    + CategoryInfo          : InvalidArgument: (:) [], CimException
    + FullyQualifiedErrorId : StorageWMI 5,New-Partition
    + PSComputerName        : localhost
 
VERBOSE: [MSARMBRISEBOIS]: LCM:  [ End    Set      ]  [[DiskPartition]CreateDiskPartition]  in 0.5880 seconds.
The PowerShell DSC resource cCreateDiskPartition threw one or more non-terminating errors while running the Set-TargetResource 
functionality. These errors are logged to the ETW channel called Microsoft-Windows-DSC/Operational. Refer to this channel for more 
details.
    + CategoryInfo          : InvalidOperation: (:) [], CimException
    + FullyQualifiedErrorId : NonTerminatingErrorFromProvider
    + PSComputerName        : localhost
 
The SendConfigurationApply function did not succeed.
    + CategoryInfo          : NotSpecified: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : MI RESULT 1
    + PSComputerName        : localhost
 
VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 68.836 seconds
</pre>
<p>The error above is generated because of this following PowerShell.</p>
<pre class="brush: powershell; title: ; notranslate">
    Get-VirtualDisk -FriendlyName $VirtualDiskFriendlyName `
    | Get-Disk `
    | New-Partition -UseMaximumSize `
                    -AssignDriveLetter `
                    -DriveLetter Y `
    | Format-Volume
</pre>
<p>It failed because I used both the <strong>AssignDriveLetter</strong> and the <strong>DriveLetter</strong> parameters. Removing the DriveLetter parameter allowed the script to auto assign the next available drive letter.</p>
<h4>Status</h4>
<p>This folder contains the DSC Status files. Are a great way to get insight into what happened when the VM Extension ran.</p>
<pre class="brush: jscript; title: ; notranslate">
[{
    &quot;status&quot;: {
        &quot;substatus&quot;: [{
            &quot;status&quot;: &quot;success&quot;,
            &quot;code&quot;: 1,
            &quot;name&quot;: &quot;DscConfigurationLog&quot;,
            &quot;formattedMessage&quot;: {
                &quot;message&quot;: &quot;Perform operation \u0027Invoke CimMethod\u0027 with following parameters, \u0027\u0027methodName\u0027 = SendConfigurationApply,\u0027className\u0027 = MSFT_DSCLocalConfigurationManager,\u0027namespaceName\u0027 = root/Microsoft/Windows/DesiredStateConfiguration\u0027.\r\nAn LCM method call arrived from computer MSARMBRISEBOIS with user sid S-1-5-18.\r\nAn LCM method call arrived from computer MSARMBRISEBOIS with user sid S-1-5-18.\r\n[MSARMBRISEBOIS]: LCM:  [ Start  Set      ]\r\n[MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[StorageSpace]CreateStorageSpace]\r\n[MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[StorageSpace]CreateStorageSpace]\r\n[MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[StorageSpace]CreateStorageSpace]  in 1.5470 seconds.\r\n[MSARMBRISEBOIS]: LCM:  [ Skip   Set      ]  [[StorageSpace]CreateStorageSpace]\r\n[MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[StorageSpace]CreateStorageSpace]\r\n[MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[VirtualDisk]CreateVirtualDisk]\r\n[MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[VirtualDisk]CreateVirtualDisk]\r\n[MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[VirtualDisk]CreateVirtualDisk]  in 0.0780 seconds.\r\n[MSARMBRISEBOIS]: LCM:  [ Skip   Set      ]  [[VirtualDisk]CreateVirtualDisk]\r\n[MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[VirtualDisk]CreateVirtualDisk]\r\n[MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[Disk]InitializeDisk]\r\n[MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[Disk]InitializeDisk]\r\n[MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[Disk]InitializeDisk]  in 0.1450 seconds.\r\n[MSARMBRISEBOIS]: LCM:  [ Skip   Set      ]  [[Disk]InitializeDisk]\r\n[MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[Disk]InitializeDisk]\r\n[MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[DiskPartition]CreateDiskPartition]\r\n[MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[DiskPartition]CreateDiskPartition]\r\n[MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[DiskPartition]CreateDiskPartition]  in 0.1440 seconds.\r\n[MSARMBRISEBOIS]: LCM:  [ Skip   Set      ]  [[DiskPartition]CreateDiskPartition]\r\n[MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[DiskPartition]CreateDiskPartition]\r\n[MSARMBRISEBOIS]: LCM:  [ End    Set      ]    in  2.4610 seconds.\r\nOperation \u0027Invoke CimMethod\u0027 complete.\r\nTime taken for configuration job to complete is 18.63 seconds&quot;,
                &quot;lang&quot;: &quot;en-US&quot;
            }
        }],
        &quot;status&quot;: &quot;success&quot;,
        &quot;code&quot;: 1,
        &quot;formattedMessage&quot;: {
            &quot;message&quot;: &quot;DSC configuration was applied successfully.&quot;,
            &quot;lang&quot;: &quot;en-US&quot;
        }
    },
    &quot;timestampUTC&quot;: &quot;2015-05-20 17:27:50Z&quot;,
    &quot;version&quot;: &quot;1.0&quot;
}]
</pre>
<p>The substatus contains a capture of the log. This will contain details about the exceptions that occurred which DSC tried to apply the configuration.  </p>
<pre class="brush: plain; title: ; notranslate">
Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.
An LCM method call arrived from computer MSARMBRISEBOIS with user sid S-1-5-18.
An LCM method call arrived from computer MSARMBRISEBOIS with user sid S-1-5-18.
[MSARMBRISEBOIS]: LCM:  [ Start  Set      ]
[MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[StorageSpace]CreateStorageSpace]
[MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[StorageSpace]CreateStorageSpace]
[MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[StorageSpace]CreateStorageSpace]  in 1.5470 seconds.
[MSARMBRISEBOIS]: LCM:  [ Skip   Set      ]  [[StorageSpace]CreateStorageSpace]
[MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[StorageSpace]CreateStorageSpace]
[MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[VirtualDisk]CreateVirtualDisk]
[MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[VirtualDisk]CreateVirtualDisk]
[MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[VirtualDisk]CreateVirtualDisk]  in 0.0780 seconds.
[MSARMBRISEBOIS]: LCM:  [ Skip   Set      ]  [[VirtualDisk]CreateVirtualDisk]
[MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[VirtualDisk]CreateVirtualDisk]
[MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[Disk]InitializeDisk]
[MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[Disk]InitializeDisk]
[MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[Disk]InitializeDisk]  in 0.1450 seconds.
[MSARMBRISEBOIS]: LCM:  [ Skip   Set      ]  [[Disk]InitializeDisk]
[MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[Disk]InitializeDisk]
[MSARMBRISEBOIS]: LCM:  [ Start  Resource ]  [[DiskPartition]CreateDiskPartition]
[MSARMBRISEBOIS]: LCM:  [ Start  Test     ]  [[DiskPartition]CreateDiskPartition]
[MSARMBRISEBOIS]: LCM:  [ End    Test     ]  [[DiskPartition]CreateDiskPartition]  in 0.1440 seconds.
[MSARMBRISEBOIS]: LCM:  [ Skip   Set      ]  [[DiskPartition]CreateDiskPartition]
[MSARMBRISEBOIS]: LCM:  [ End    Resource ]  [[DiskPartition]CreateDiskPartition]
[MSARMBRISEBOIS]: LCM:  [ End    Set      ]    in  2.4610 seconds.
Operation 'Invoke CimMethod' complete.
Time taken for configuration job to complete is 18.63 seconds
</pre>
<h3>Location: C:\Program Files\WindowsPowerShell\Modules</h3>
<p>This folder contains the uncompressed DSC configuration and Modules that were packaged and uploaded to Azure Storage or any other accessible location.</p>
<h2>Debugging, Testing and Refining</h2>
<p>Now that we understand the environment that we have to work with, it&#8217;s time to dive in. </p>
<p>To start our debug session, we have to look at the status that was generated by DSC. This will give us something to work with. Then based on what we find, we can look at the configuration that was used to execute the DSC. Next based on our findings we can look at the DSC configuration and modules installed on the Virtual Machine. </p>
<p>Once we find out what has gone terribly wrong. We can fix the module in the target Virtual Machine and trigger the Start-DscConfiguration cmdlet. Using the produced output, we can iterate through dev &amp; test cycles until we reach our goal.</p>
<p>When we have something that works, we copy the DSC configuration and module out of the vm. Then we insert it into our Azure Resource Manager Template Solution. From this point on, it&#8217;s business as usual. We package the DSC configuration and modules. And finally, we test the entire pipeline by deploying the template to a new Azure Resource Group.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/arm/'>ARM</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/debugging/'>Debugging</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dsc/'>DSC</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iaas/'>IaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/rdp/'>RDP</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/remote-desktop/'>Remote Desktop</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/windows/'>Windows</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6560/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6560/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6560/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6560/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6560/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6560/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6560/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6560&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/05/20/debugging-desired-state-configuration-dsc-on-azure-vms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/05/bugzapper.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/05/bugzapper.jpg?w=150" medium="image">
			<media:title type="html">bugzapper</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Using  Azure Resource Manager (ARM) to Deploy a Monster VM</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/05/16/using-azure-resource-manager-arm-to-deploy-a-monster-vm/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/05/16/using-azure-resource-manager-arm-to-deploy-a-monster-vm/#comments</comments>
		<pubDate>Sat, 16 May 2015 18:00:14 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Azure Resource Manager]]></category>
		<category><![CDATA[Azure Storage]]></category>
		<category><![CDATA[Blobs Storage]]></category>
		<category><![CDATA[Configurations]]></category>
		<category><![CDATA[Data Disk]]></category>
		<category><![CDATA[DSC]]></category>
		<category><![CDATA[DSC Module]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Premium Storage]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[VM Extensions]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6455</guid>
		<description><![CDATA[Most applications that run in Microsoft Azure use a combination of resources (such as a database server, database, or website) to perform as designed. An Azure Resource Manager Template makes it possible for you to deploy and manage these resources together by using a JSON description of the resources and associated deployment parameters. This post illustrates how to build a virtual machine that has 32 data disks. It then details how to use Desired State Configuration (DSC) to stripe and prepare the disks for use.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6455&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/05/16/using-azure-resource-manager-arm-to-deploy-a-monster-vm/" target="_blank" title="Using  Azure Resource Manager (ARM) to Deploy a Monster&nbsp;VM"><img width="580" height="363" src="https://alexandrebrisebois.files.wordpress.com/2015/05/huge-shark.jpg?w=580" class="attachment-large wp-post-image" alt="huge-shark" /></a></p><h2>A Monster VM Azure Resource Manager Template</h2>
<p>In April I wrote a post about <a title="Building a Monster Virtual Machine on #Azure" href="https://alexandrebrisebois.wordpress.com/2015/04/29/building-a-monster-virtual-machine-on-azure/" target="_blank">building a monster Virtual Machine using PowerShell on Microsoft Azure</a>. Since then, Microsoft has released version 2 of the <a href="https://msdn.microsoft.com/en-us/library/azure/dn835138.aspx" target="_blank">Azure Resource Manager</a> (ARM). This version allows us to define a Virtual Machine, its data disks and its Desired State Configuration (DSC) VM Extensions as a template. Seeing this as a great opportunity, I decided to convert my first PowerShell script to an ARM template that would create a Virtual Machine and striped data disk.</p>
<h2>The Target Virtual Machine Configuration</h2>
<blockquote><p><strong>16</strong> Cores<br />
<strong>112</strong> GB of RAM<br />
<strong>800</strong> GB of local SSD for temp disk<br />
<strong>32</strong> TB for the data disk<br />
<strong>50,000</strong> IOPS for the data disk<br />
<strong>512</strong> MB per second for the data disk</p></blockquote>
<p><span id="more-6455"></span></p>
<h2>What is the Azure Resource Manager (ARM)?</h2>
<blockquote><p>Most applications that run in Microsoft Azure use a combination of resources (such as a database server, database, or website) to perform as designed. An Azure Resource Manager Template makes it possible for you to deploy and manage these resources together by using a JSON description of the resources and associated deployment parameters.</p></blockquote>
<h2>Azure Resource Manager Template</h2>
<p>Using the <a href="https://github.com/Azure/azure-quickstart-templates/tree/master/101-simple-windows-vm-data-disk">Windows Server Virtual Machine</a> template as a base, I delved into various templates from the <a href="https://github.com/Azure/azure-quickstart-templates" target="_blank">Azure Quickstart Templates</a>. These templates helped me figure out how to create an OS Disk in an Azure Premium Storage Account and how to attach thirty-two 1TB data disks.</p>
<p>The following is the template that resulted from this exercise. In order to, navigate and build this template, I used the Visual Studio JSON Explorer.</p>
<h2>WindowsVirtualMachine.json</h2>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.1&quot;,
    &quot;parameters&quot;: {
        &quot;newStorageAccountName&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique DNS Name for the Storage Account where the Virtual Machine's disks will be placed.&quot;
            }
        },
        &quot;adminUsername&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Username for the Virtual Machine.&quot;
            }
        },
        &quot;adminPassword&quot;: {
            &quot;type&quot;: &quot;securestring&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Password for the Virtual Machine.&quot;
            }
        },
        &quot;location&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Data Center&quot;
            },
            &quot;defaultValue&quot;: &quot;West US&quot;,
            &quot;allowedValues&quot;: [
                &quot;West US&quot;,
                &quot;East US 2&quot;,
                &quot;West Europe&quot;,
                &quot;Southeast Asia&quot;,
                &quot;Japan West&quot;
            ]
        },
        &quot;vmSize&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Virtual Machine Size&quot;
            },
            &quot;defaultValue&quot;: &quot;Standard_DS14&quot;,
            &quot;allowedValues&quot;: [
                &quot;Standard_DS14&quot;
            ]
        },
        &quot;vmName&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique Name for the Virtual Machine&quot;
            }
        },
        &quot;dnsNameForPublicIP&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;Unique DNS Name for the Public IP used to access the Virtual Machine.&quot;
            }
        },
        &quot;windowsOSVersion&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;defaultValue&quot;: &quot;2012-R2-Datacenter&quot;,
            &quot;allowedValues&quot;: [
                &quot;2008-R2-SP1&quot;,
                &quot;2012-Datacenter&quot;,
                &quot;2012-R2-Datacenter&quot;,
                &quot;Windows-Server-Technical-Preview&quot;
            ],
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;The Windows version for the VM. This will pick a fully patched image of this given Windows version. Allowed values: 2008-R2-SP1, 2012-Datacenter, 2012-R2-Datacenter, Windows-Server-Technical-Preview.&quot;
            }
        },
        &quot;modulesUrl&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;URL for the DSC configuration module. NOTE: Can be a Github url(raw) to the zip file&quot;
            }
        },
        &quot;configurationFunction&quot;: {
            &quot;type&quot;: &quot;string&quot;,
            &quot;metadata&quot;: {
                &quot;description&quot;: &quot;DSC configuration function to call&quot;
            }
        }
    },
    &quot;variables&quot;: {
        &quot;imagePublisher&quot;: &quot;MicrosoftWindowsServer&quot;,
        &quot;imageOffer&quot;: &quot;WindowsServer&quot;,
        &quot;OSDiskName&quot;: &quot;osdisk&quot;,
        &quot;sizeOfDiskInGB&quot;: &quot;1023&quot;,
        &quot;nicName&quot;: &quot;VMNic&quot;,
        &quot;addressPrefix&quot;: &quot;10.0.0.0/16&quot;,
        &quot;subnetName&quot;: &quot;Subnet&quot;,
        &quot;subnetPrefix&quot;: &quot;10.0.0.0/24&quot;,
        &quot;storageAccountType&quot;: &quot;Premium_LRS&quot;,
        &quot;publicIPAddressName&quot;: &quot;PublicIP&quot;,
        &quot;publicIPAddressType&quot;: &quot;Dynamic&quot;,
        &quot;vmStorageAccountContainerName&quot;: &quot;vhds&quot;,
        &quot;virtualNetworkName&quot;: &quot;[concat(parameters('vmName'),'vnet')]&quot;,
        &quot;vnetID&quot;: &quot;[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]&quot;,
        &quot;subnetRef&quot;: &quot;[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]&quot;
    },
    &quot;resources&quot;: [
        {
            &quot;type&quot;: &quot;Microsoft.Storage/storageAccounts&quot;,
            &quot;name&quot;: &quot;[parameters('newStorageAccountName')]&quot;,
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;StorageAccount&quot;
            },
            &quot;properties&quot;: {
                &quot;accountType&quot;: &quot;[variables('storageAccountType')]&quot;
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/publicIPAddresses&quot;,
            &quot;name&quot;: &quot;[variables('publicIPAddressName')]&quot;,
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;PublicIPAddress&quot;
            },
            &quot;properties&quot;: {
                &quot;publicIPAllocationMethod&quot;: &quot;[variables('publicIPAddressType')]&quot;,
                &quot;dnsSettings&quot;: {
                    &quot;domainNameLabel&quot;: &quot;[parameters('dnsNameForPublicIP')]&quot;
                }
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/virtualNetworks&quot;,
            &quot;name&quot;: &quot;[variables('virtualNetworkName')]&quot;,
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;VirtualNetwork&quot;
            },
            &quot;properties&quot;: {
                &quot;addressSpace&quot;: {
                    &quot;addressPrefixes&quot;: [
                        &quot;[variables('addressPrefix')]&quot;
                    ]
                },
                &quot;subnets&quot;: [
                    {
                        &quot;name&quot;: &quot;[variables('subnetName')]&quot;,
                        &quot;properties&quot;: {
                            &quot;addressPrefix&quot;: &quot;[variables('subnetPrefix')]&quot;
                        }
                    }
                ]
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Network/networkInterfaces&quot;,
            &quot;name&quot;: &quot;[variables('nicName')]&quot;,
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;NetworkInterface&quot;
            },
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]&quot;,
                &quot;[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]&quot;
            ],
            &quot;properties&quot;: {
                &quot;ipConfigurations&quot;: [
                    {
                        &quot;name&quot;: &quot;ipconfig1&quot;,
                        &quot;properties&quot;: {
                            &quot;privateIPAllocationMethod&quot;: &quot;Dynamic&quot;,
                            &quot;publicIPAddress&quot;: {
                                &quot;id&quot;: &quot;[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]&quot;
                            },
                            &quot;subnet&quot;: {
                                &quot;id&quot;: &quot;[variables('subnetRef')]&quot;
                            }
                        }
                    }
                ]
            }
        },
        {
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;type&quot;: &quot;Microsoft.Compute/virtualMachines&quot;,
            &quot;name&quot;: &quot;[parameters('vmName')]&quot;,
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;tags&quot;: {
                &quot;displayName&quot;: &quot;VirtualMachine&quot;
            },
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'))]&quot;,
                &quot;[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]&quot;
            ],
            &quot;properties&quot;: {
                &quot;hardwareProfile&quot;: {
                    &quot;vmSize&quot;: &quot;[parameters('vmSize')]&quot;
                },
                &quot;osProfile&quot;: {
                    &quot;computername&quot;: &quot;[parameters('vmName')]&quot;,
                    &quot;adminUsername&quot;: &quot;[parameters('adminUsername')]&quot;,
                    &quot;adminPassword&quot;: &quot;[parameters('adminPassword')]&quot;
                },
                &quot;storageProfile&quot;: {
                    &quot;imageReference&quot;: {
                        &quot;publisher&quot;: &quot;[variables('imagePublisher')]&quot;,
                        &quot;offer&quot;: &quot;[variables('imageOffer')]&quot;,
                        &quot;sku&quot;: &quot;[parameters('windowsOSVersion')]&quot;,
                        &quot;version&quot;: &quot;latest&quot;
                    },
                    &quot;osDisk&quot;: {
                        &quot;name&quot;: &quot;osdisk&quot;,
                        &quot;vhd&quot;: {
                            &quot;uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]&quot;
                        },
                        &quot;caching&quot;: &quot;ReadWrite&quot;,
                        &quot;createOption&quot;: &quot;FromImage&quot;
                    },
                    &quot;dataDisks&quot;: [
                        {
                            &quot;name&quot;: &quot;datadisk1&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 0,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','1','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk2&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 1,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','2','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk3&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 2,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','3','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk4&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 3,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','4','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk5&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 4,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','5','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk6&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 5,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','6','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk7&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 6,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','7','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk8&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 7,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','8','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk9&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 8,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','9','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk10&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 9,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','10','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk11&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 10,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','11','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk12&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 11,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','12','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk13&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 12,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','13','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk14&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 13,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','14','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk15&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 14,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','15','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk16&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 15,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','16','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk17&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 16,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','17','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk18&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 17,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','18','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk19&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 18,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','19','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk20&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 19,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','20','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk21&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 20,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','21','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk22&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 21,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','22','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk23&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 22,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','23','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk24&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 23,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','24','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk25&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 24,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','25','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk26&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 25,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','26','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk27&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 26,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','27','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk218&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 27,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','28','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk29&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 28,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','29','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk30&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 29,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','30','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk31&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 30,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','31','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        },
                        {
                            &quot;name&quot;: &quot;datadisk32&quot;,
                            &quot;diskSizeGB&quot;: &quot;[variables('sizeOfDiskInGB')]&quot;,
                            &quot;lun&quot;: 31,
                            &quot;caching&quot;: &quot;ReadOnly&quot;,
                            &quot;vhd&quot;: {
                                &quot;Uri&quot;: &quot;[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/','datadisk','32','.vhd')]&quot;
                            },
                            &quot;createOption&quot;: &quot;Empty&quot;
                        }
                    ]
                },
                &quot;networkProfile&quot;: {
                    &quot;networkInterfaces&quot;: [
                        {
                            &quot;id&quot;: &quot;[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]&quot;
                        }
                    ]
                }
            }
        },
        {
            &quot;type&quot;: &quot;Microsoft.Compute/virtualMachines/extensions&quot;,
            &quot;name&quot;: &quot;[concat(parameters('vmName'),'/', 'dscExtension')]&quot;,
            &quot;apiVersion&quot;: &quot;2015-05-01-preview&quot;,
            &quot;location&quot;: &quot;[parameters('location')]&quot;,
            &quot;dependsOn&quot;: [
                &quot;[concat('Microsoft.Compute/virtualMachines/', parameters('vmName'))]&quot;
            ],
            &quot;properties&quot;: {
                &quot;publisher&quot;: &quot;Microsoft.Powershell&quot;,
                &quot;type&quot;: &quot;DSC&quot;,
                &quot;typeHandlerVersion&quot;: &quot;1.7&quot;,
                &quot;settings&quot;: {
                    &quot;ModulesUrl&quot;: &quot;[parameters('modulesUrl')]&quot;,
                    &quot;SasToken&quot;: &quot;&quot;,
                    &quot;ConfigurationFunction&quot;: &quot;[parameters('configurationFunction')]&quot;,
                    &quot;Properties&quot;: {
                        &quot;StoragePoolFriendlyName&quot; : &quot;storagespace0&quot;,
                        &quot;VirtualDiskFriendlyName&quot; : &quot;datadisk&quot;,
                        &quot;DriveSize&quot;: 35184372088832,
                        &quot;NumberOfColumns&quot;: 32
                    }
                },
                &quot;protectedSettings&quot;: null
            }
        }
    ]
}
</pre>
<h2>Azure Resource Manager Template Parameters</h2>
<p>This file contains deployment specific parameter values for the Azure Resource Manager Template. As the name suggests, we can have multiple parameter files per project. If a parameter is missing from this file, it will be requested when the deployment is initiated.</p>
<h3>WindowsVirtualMachine.param.dev.json</h3>
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;$schema&quot;: &quot;https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#&quot;,
    &quot;contentVersion&quot;: &quot;1.0.0.1&quot;,
    &quot;parameters&quot;: {
        &quot;newStorageAccountName&quot;: {
            &quot;value&quot;: &quot;msarmbrisebois&quot;
        },
        &quot;adminUsername&quot;: {
            &quot;value&quot;: &quot;brisebois&quot;
        },
        &quot;dnsNameForPublicIP&quot;: {
            &quot;value&quot;: &quot;msarmbrisebois&quot;
        },
        &quot;vmName&quot;: {
            &quot;value&quot;: &quot;msarmbrisebois&quot;
        },
        &quot;windowsOSVersion&quot;: {
            &quot;value&quot;: &quot;2012-R2-Datacenter&quot;
        },
        &quot;configurationFunction&quot;: {
            &quot;value&quot;: &quot;DiskConfiguration.ps1\\DiskConfiguration&quot;
        }
    }
}
</pre>
<h2>Creating a Custom DSC</h2>
<p>This custom Desired State Configuration (DSC) stripes 32 Premium Data Disks using the DSC Virtual Machine Extension. To create this Module Iets borrowed from my earlier post <a href="https://alexandrebrisebois.wordpress.com/2015/05/08/a-custom-dsc-module-to-stripe-data-disks-on-azure-virtual-machines/" target="_blank">that create a custom DSC Module to Stripe data disks on Azure Virtual Machines</a>. First we need to make a few changes. We will start by breaking each step into its own module. Then we will add better test logic so that if one step fails, the DSC can be executed again.</p>
<p>The following scaffolding script builds out the files and folder structure for the DSC that we are building</p>
<h3>Scaffolding the DSC Module</h3>
<pre class="brush: powershell; title: ; notranslate">
New-xDscResource –Name cCreateStorageSpace `
                 -Property (New-xDscResourceProperty –Name FriendlyName `
                                                     –Type String `
                                                     -Attribute Key) `
                 -Path 'C:\Program Files\WindowsPowerShell\Modules\' `
                 -ModuleName cDiskTools `
                 -FriendlyName StorageSpace `
                 -Verbose

New-xDscResource –Name cCreateVirtualDisk `
                 -Property (New-xDscResourceProperty –Name FriendlyName `
                                                     –Type String `
                                                     -Attribute Key), `
                           (New-xDscResourceProperty –Name StoragePoolFriendlyName `
                                                     –Type String `
                                                     -Attribute Required),
                           (New-xDscResourceProperty –Name DriveSize `
                                                     –Type UInt64 `
                                                     -Attribute Required), `
                           (New-xDscResourceProperty –Name NumberOfColumns `
                                                     -Type Uint32 `
                                                     -Attribute Required) `
                 -Path 'C:\Program Files\WindowsPowerShell\Modules\' `
                 -ModuleName cDiskTools `
                 -FriendlyName VirtualDisk `
                 -Verbose

New-xDscResource –Name cInitializeDisk `
                 -Property (New-xDscResourceProperty –Name VirtualDiskFriendlyName `
                                                     –Type String `
                                                     -Attribute Key) `
                 -Path 'C:\Program Files\WindowsPowerShell\Modules\' `
                 -ModuleName cDiskTools `
                 -FriendlyName Disk `
                 -Verbose

New-xDscResource –Name cCreateDiskPartition `
                 -Property (New-xDscResourceProperty –Name VirtualDiskFriendlyName `
                                                     –Type String `
                                                     -Attribute Key) `
                 -Path 'C:\Program Files\WindowsPowerShell\Modules\' `
                 -ModuleName cDiskTools `
                 -FriendlyName DiskPartition `
                 -Verbose
</pre>
<p>Now that we have something to work with, let&#8217;s port the code from DSC I created for my earlier post. The following files reside in the following location C:\Program Files\WindowsPowerShell\Modules\cDiskTools\</p>
<h3>DSCResources\cCreateStorageSpace\cCreateStorageSpace.psm1</h3>
<p>The first module tests whether the storage space already exists. If it&#8217;s missing, the module will create it.</p>
<pre class="brush: powershell; title: ; notranslate">
function Get-TargetResource
{
	[CmdletBinding()]
	[OutputType([System.Collections.Hashtable])]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$FriendlyName
	)
}

function Set-TargetResource
{
	[CmdletBinding()]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$FriendlyName
	)

    New-StoragePool -FriendlyName $FriendlyName `
                    -StorageSubSystemUniqueId (Get-StorageSubSystem -FriendlyName '*Space*').uniqueID `
                    -PhysicalDisks (Get-PhysicalDisk -CanPool $true)
}

function Test-TargetResource
{
	[CmdletBinding()]
	[OutputType([System.Boolean])]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$FriendlyName
	)

    $result = [System.Boolean]

    try
    {
        $pool = Get-StoragePool -FriendlyName $FriendlyName -ErrorAction Ignore
        if(!$pool){
            $result = $false
        }else{
            $result = $true
        }
    }
    catch [System.Exception]
    {
        $result = $false
    }

    $result
}

Export-ModuleMember -Function *-TargetResource
</pre>
<h3>DSCResources\cCreateVirtualDisk\cCreateVirtualDisk.psm1</h3>
<p>The second module will check whether the virtual disk already exists. If it&#8217;s missing it will create it using the provided parameters.</p>
<pre class="brush: powershell; title: ; notranslate">
function Get-TargetResource
{
	[CmdletBinding()]
	[OutputType([System.Collections.Hashtable])]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$FriendlyName,

		[parameter(Mandatory = $true)]
		[System.String]
		$StoragePoolFriendlyName,

		[parameter(Mandatory = $true)]
		[System.UInt64]
		$DriveSize,

		[parameter(Mandatory = $true)]
		[System.UInt32]
		$NumberOfColumns
	)

}

function Set-TargetResource
{
	[CmdletBinding()]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$FriendlyName,

		[parameter(Mandatory = $true)]
		[System.String]
		$StoragePoolFriendlyName,

		[parameter(Mandatory = $true)]
		[System.UInt64]
		$DriveSize,

		[parameter(Mandatory = $true)]
		[System.UInt32]
		$NumberOfColumns
	)

    Write-Debug $FriendlyName

	New-VirtualDisk -FriendlyName $FriendlyName `
                    -StoragePoolFriendlyName $StoragePoolFriendlyName `
                    -Size $DriveSize `
                    -NumberOfColumns $NumberOfColumns `
                    -ProvisioningType Thin `
                    -ResiliencySettingName Simple

}

function Test-TargetResource
{
	[CmdletBinding()]
	[OutputType([System.Boolean])]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$FriendlyName,

		[parameter(Mandatory = $true)]
		[System.String]
		$StoragePoolFriendlyName,

		[parameter(Mandatory = $true)]
		[System.UInt64]
		$DriveSize,

		[parameter(Mandatory = $true)]
		[System.UInt32]
		$NumberOfColumns
	)

    Write-Debug $FriendlyName

    $result = [System.Boolean]

    try
    {
        $disk = Get-VirtualDisk -FriendlyName $FriendlyName -ErrorAction Ignore
        if(!$disk){
            $result = $false
        }else{
            $result = $true
        }
    }
    catch [System.Exception]
    {
        $result = $false
    }

    Write-Debug $result

    $result
}

Export-ModuleMember -Function *-TargetResource
</pre>
<h3>DSCResources\cInitializeDisk\cInitializeDisk.psm1</h3>
<p>This module then makes sure that the disk is initialized properly.</p>
<pre class="brush: powershell; title: ; notranslate">
function Get-TargetResource
{
	[CmdletBinding()]
	[OutputType([System.Collections.Hashtable])]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$VirtualDiskFriendlyName
	)

}

function Set-TargetResource
{
	[CmdletBinding()]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$VirtualDiskFriendlyName
	)

    Initialize-Disk -VirtualDisk (Get-VirtualDisk -FriendlyName $VirtualDiskFriendlyName) -PartitionStyle GPT -Confirm:$false
}

function Test-TargetResource
{
	[CmdletBinding()]
	[OutputType([System.Boolean])]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$VirtualDiskFriendlyName
	)

	$result = [System.Boolean]

    try
    {
        $virtualDisk = Get-VirtualDisk -FriendlyName $VirtualDiskFriendlyName -ErrorAction Stop
        $disk = Get-Disk -VirtualDisk $virtualDisk

        if($disk.PartitionStyle -eq 'GPT')
        {
           $result = $true
        }
        else
        {
           $result = $false
        }
    }
    catch [System.Exception]
    {
        $result = $false
    }

    $result
}

Export-ModuleMember -Function *-TargetResource
</pre>
<h3>DSCResources\cCreateDiskPartition\cCreateDiskPartition.psm1</h3>
<p>Finally, this module creates a partition, assigns a drive letter and formats it.</p>
<pre class="brush: powershell; title: ; notranslate">
function Get-TargetResource
{
	[CmdletBinding()]
	[OutputType([System.Collections.Hashtable])]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$VirtualDiskFriendlyName
	)
}

function Set-TargetResource
{
	[CmdletBinding()]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$VirtualDiskFriendlyName
	)

    Get-VirtualDisk -FriendlyName $VirtualDiskFriendlyName `
    | Get-Disk `
    | New-Partition -UseMaximumSize `
                    -AssignDriveLetter `
    | Format-Volume
}

function Test-TargetResource
{
	[CmdletBinding()]
	[OutputType([System.Boolean])]
	param
	(
		[parameter(Mandatory = $true)]
		[System.String]
		$VirtualDiskFriendlyName
	)

    $result = [System.Boolean]

    try
    {
        $virtualDisk = Get-VirtualDisk -FriendlyName $VirtualDiskFriendlyName -ErrorAction Stop
        $disk = Get-Disk -VirtualDisk $virtualDisk

        $partition = Get-Partition -DiskNumber $disk.Number

        if(!$partition.DriveLetter)
        {
           $result = $false
        }
        else
        {
           $result = $true
        }
    }
    catch [System.Exception]
    {
        $result = $false
    }

    $result
}

Export-ModuleMember -Function *-TargetResource
</pre>
<h2>DSC Configuration</h2>
<p>This configuration executes the DSC Modules listed above and specifies the total size of the drive that will be created and the number of columns to use. On Azure, the rule of thumb is 1 column per data disk.</p>
<pre class="brush: powershell; title: ; notranslate">
configuration DiskConfiguration {
 param (
   [String]$StoragePoolFriendlyName,
   [String]$VirtualDiskFriendlyName,
   [UInt64]$DriveSize = 32TB,
   [UInt32]$NumberOfColumns = 32
 )

 Import-DscResource -Module cDiskTools

 node localhost
 {
   Settings
   {
      DebugMode = 'All,ResourceScriptBreakAll'
      ConfigurationMode = 'ApplyAndAutoCorrect'
      RefreshMode = 'Disabled'
   }

   StorageSpace CreateStorageSpace
   {
     FriendlyName = $StoragePoolFriendlyName
   }

   VirtualDisk CreateVirtualDisk
   {
     FriendlyName = $VirtualDiskFriendlyName
     StoragePoolFriendlyName = $StoragePoolFriendlyName
     DriveSize = $DriveSize
     NumberOfColumns = $NumberOfColumns
   }

   Disk InitializeDisk
   {
     VirtualDiskFriendlyName = $VirtualDiskFriendlyName
   }

   DiskPartition CreateDiskPartition
   {
     VirtualDiskFriendlyName = $VirtualDiskFriendlyName
   }
 }
}
</pre>
<h2>Packaging and Deployment</h2>
<p>Getting the PowerShell DSC in Azure Storage can be done using the Publish-AzureVMDscConfiguration cmdlet. It can also be done by creating a zip file containing the DSC Module and the DSC Configuration. Then it&#8217;s up to you to upload the zip file to Azure Blob Storage. In the end the cmdlet is quite useful when you need to iterate quickly.</p>
<pre class="brush: powershell; title: ; notranslate">
Switch-AzureMode AzureServiceManagement

$ErrorActionPreference = &quot;stop&quot;

# set the storage account that will contain the DSC packages

Set-AzureSubscription -SubscriptionName (Get-AzureSubscription -Current).SubscriptionName -CurrentStorageAccountName 'briseboispackages'

# package and publish the DSC to the storage account

Publish-AzureVMDscConfiguration -ConfigurationPath 'C:\Program Files\WindowsPowerShell\Modules\cDiskTools\DiskConfiguration.ps1' -Force

# 

$currentStorageAccount = (Get-AzureSubscription -Current).CurrentStorageAccountName

$ModuleURL = &quot;https://$currentStorageAccount.blob.core.windows.net/windows-powershell-dsc/DiskConfiguration.ps1.zip&quot;

$additionalParameters = New-Object -TypeName Hashtable

$additionalParameters[&quot;modulesUrl&quot;] = $ModuleURL

Switch-AzureMode AzureResourceManager

# deploy the monster Virtual Machine

New-AzureResourceGroup -Name &quot;armmonstervm&quot; `
                       -Location &quot;westus&quot; `
                       -TemplateFile 'WindowsVirtualMachine.json' `
                       -TemplateParameterFile 'WindowsVirtualMachine.param.dev.json' `
                       @additionalParameters `
                       -Force -Verbose
</pre>
<p>The deployment produces the following output, that allows us to determine where things might have gone wrong.</p>
<pre class="brush: plain; title: ; notranslate">
VERBOSE: 5:04:36 PM - Created resource group 'armmonstervm' in location 'westus'
VERBOSE: 5:04:36 PM - Template is valid.
VERBOSE: 5:04:37 PM - Create template deployment 'WindowsVirtualMachine'.
VERBOSE: 5:04:42 PM - Resource Microsoft.Network/publicIPAddresses 'PublicIP' provisioning status is running
VERBOSE: 5:04:42 PM - Resource Microsoft.Network/virtualNetworks 'msarmbriseboisvnet' provisioning status is running
VERBOSE: 5:04:45 PM - Resource Microsoft.Storage/storageAccounts 'msarmbrisebois' provisioning status is running
VERBOSE: 5:04:54 PM - Resource Microsoft.Network/virtualNetworks 'msarmbriseboisvnet' provisioning status is succeeded
VERBOSE: 5:04:57 PM - Resource Microsoft.Network/publicIPAddresses 'PublicIP' provisioning status is succeeded
VERBOSE: 5:04:59 PM - Resource Microsoft.Network/networkInterfaces 'VMNic' provisioning status is succeeded
VERBOSE: 5:08:20 PM - Resource Microsoft.Compute/virtualMachines 'msarmbrisebois' provisioning status is running
VERBOSE: 5:08:20 PM - Resource Microsoft.Storage/storageAccounts 'msarmbrisebois' provisioning status is succeeded
VERBOSE: 5:22:03 PM - Resource Microsoft.Compute/virtualMachines/extensions 'msarmbrisebois/dscExtension' provisioning status is running
VERBOSE: 5:22:03 PM - Resource Microsoft.Compute/virtualMachines 'msarmbrisebois' provisioning status is succeeded
VERBOSE: 5:29:14 PM - Resource Microsoft.Compute/virtualMachines/extensions 'msarmbrisebois/dscExtension' provisioning status is succeeded
</pre>
<p>In a subsequent post, I will detail the steps that helped me to test and debug the Desired State Configuration used in this template.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/arm/'>ARM</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-resource-manager/'>Azure Resource Manager</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-storage/'>Azure Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blobs-storage/'>Blobs Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configurations/'>Configurations</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/data-disk/'>Data Disk</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dsc/'>DSC</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dsc-module/'>DSC Module</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iaas/'>IaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/json/'>JSON</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/premium-storage/'>Premium Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/vm-extensions/'>VM Extensions</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6455/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6455/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6455/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6455&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/05/16/using-azure-resource-manager-arm-to-deploy-a-monster-vm/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/05/huge-shark.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/05/huge-shark.jpg?w=150" medium="image">
			<media:title type="html">huge-shark</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>A Custom DSC Module to Stripe Data Disks on #Azure Virtual Machines</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/05/08/a-custom-dsc-module-to-stripe-data-disks-on-azure-virtual-machines/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/05/08/a-custom-dsc-module-to-stripe-data-disks-on-azure-virtual-machines/#comments</comments>
		<pubDate>Fri, 08 May 2015 07:00:50 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Data Disk]]></category>
		<category><![CDATA[Desired State Configuration]]></category>
		<category><![CDATA[DSC]]></category>
		<category><![CDATA[DSC Module]]></category>
		<category><![CDATA[Format]]></category>
		<category><![CDATA[Module]]></category>
		<category><![CDATA[NTFS]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[RAID0]]></category>
		<category><![CDATA[Stripe]]></category>
		<category><![CDATA[Thin]]></category>
		<category><![CDATA[Virtual Disk]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Volume]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6463</guid>
		<description><![CDATA[This post marks my first adventure with PowerShell Desired State Configuration. Over the past few weeks, there have been a few announcements around Microsoft Azure. Once of these, is an extended version of the Azure Resource Manager which brings us the ability to run PowerShell DSC on Virtual Machines. This update changes everything and I [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6463&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/05/08/a-custom-dsc-module-to-stripe-data-disks-on-azure-virtual-machines/" target="_blank" title="A Custom DSC Module to Stripe Data Disks on #Azure Virtual&nbsp;Machines"><img width="580" height="435" src="https://alexandrebrisebois.files.wordpress.com/2015/05/3520082084_b3dfa0aca8_z.jpg?w=580" class="attachment-large wp-post-image" alt="stripes" /></a></p><p>This post marks my first adventure with <a href="https://technet.microsoft.com/en-us/library/dn249912.aspx" target="_blank">PowerShell Desired State Configuration</a>. Over the past few weeks, there have been  a few announcements around Microsoft Azure. Once of these, is an extended version of the <a href="http://azure.microsoft.com/en-us/documentation/articles/resource-group-overview/" target="_blank">Azure Resource Manager</a> which brings us the ability to run PowerShell DSC on Virtual Machines. This update changes everything and I will delve into it in an upcoming post.</p>
<h1>DSC Module to Prepare a Stripe Volume</h1>
<p>Using the&nbsp;<a href="https://msconfiggallery.cloudapp.net/packages/xDSCResourceDesigner/" target="_blank">xDSCResourceDesigner</a> enabled by installing <a href="https://www.microsoft.com/en-us/download/details.aspx?id=46889" target="_blank">Windows Management Framework 5.0 Preview April 2015</a>, I was able to use the following commands to scaffold a Customer PowerShell Desired State (DSC) Module that allows me to stripe data disks on an Azure Virtual Machine.<span id="more-6463"></span></p>
<h3>Install the xDSCResourceDesigner Module</h3>
<pre class="brush: powershell; title: ; notranslate">
Install-Module -Name xDSCResourceDesigner
</pre>
<h3>scaffold a Customer PowerShell Desired State (DSC) Module</h3>
<pre class="brush: powershell; title: ; notranslate">
New-xDscResource –Name cStripeVHDsAndPrepareVolume `
                 -Property (New-xDscResourceProperty –Name DriveSize `
                                                     –Type UInt64 `
                                                     -Attribute Key), `
                           (New-xDscResourceProperty –Name NumberOfColumns `
                                                     -Type Uint32 `
                                                     -Attribute Required) `
                 -Path 'C:\Program Files\WindowsPowerShell\Modules\' `
                 -ModuleName cDiskTools `
                 -FriendlyName cDiskTools `
                 -Verbose
</pre>
<p>This will create many files in</p>
<pre class="brush: plain; title: ; notranslate">C:\Program Files\WindowsPowerShell\Modules\cDiskTools</pre>
<p>The file that interests us the most because this is where the logic is implemented.</p>
<pre class="brush: plain; title: ; notranslate">cDiskTools\DSCResources\StripeVHDsAndPrepareVolume\StripeVHDsAndPrepareVolume.psm1</pre>
<h2>Implementing the Custom DSC Module</h2>
<p><strong>Get-TargetResource</strong> – This function will always return a hastable. It’ll gather information about the task we wanted to know, and return them in a hashtable.</p>
<pre class="brush: powershell; title: ; notranslate">
function Get-TargetResource
{
	[CmdletBinding()]
	[OutputType([System.Collections.Hashtable])]
	param
	(
		[parameter(Mandatory = $true)]
		[System.UInt64]
		$DriveSize,

		[parameter(Mandatory = $true)]
		[System.UInt32]
		$NumberOfColumns
	)

    Try 
    {
        if (Test-Path $DriveLetter) 
        {
            Write-Debug 'F:/ exists on target.'
            @{
                DriveLetter = 'F'
                Mounted   = $true
            }
        }
        else {
             Write-Debug &quot;F:/ can't be found.&quot;
             @{
                DriveLetter = 'F'
                Mounted   = $false
             }
        }
    }
    Catch 
    {
        throw &quot;An error occured getting the F:/ drive informations. Error: $($_.Exception.Message)&quot;
    }
}
</pre>
<p><strong>Set-TargetResource</strong> – This function will apply what we want to do. In this case, it will create a Storage Space with all the disks that can be pooled. It will create a Virtual Disk and Initialize it. Then it will create a partition and assign a Drive Letter. Finally, it will Format the Volume.</p>
<pre class="brush: powershell; title: ; notranslate">
function Set-TargetResource
{
	[CmdletBinding()]
	param
	(
		[parameter(Mandatory = $true)]
		[System.UInt64]
		$DriveSize,

		[parameter(Mandatory = $true)]
		[System.UInt32]
		$NumberOfColumns
	)

    Write-Verbose 'Creating Storage Pool'

	New-StoragePool -FriendlyName 'LUN-0' `
                    -StorageSubSystemUniqueId (Get-StorageSubSystem -FriendlyName '*Space*').uniqueID `
                    -PhysicalDisks (Get-PhysicalDisk -CanPool $true)

    Write-Verbose 'Creating Virtual Disk'

    New-VirtualDisk -FriendlyName 'Datastore01' `
                    -StoragePoolFriendlyName 'LUN-0' `
                    -Size $DriveSize `
                    -NumberOfColumns $NumberOfColumns `
                    -ProvisioningType Thin `
                    -ResiliencySettingName Simple

    Start-Sleep -Seconds 20

    Write-Verbose 'Initializing Disk'

    Initialize-Disk -VirtualDisk (Get-VirtualDisk -FriendlyName 'Datastore01')
 
    Start-Sleep -Seconds 20

    $diskNumber = ((Get-VirtualDisk -FriendlyName 'Datastore01' | Get-Disk).Number)
 
    Write-Verbose 'Creating Partition'

    New-Partition -DiskNumber $diskNumber `
              -UseMaximumSize `
              -AssignDriveLetter `
              -DriveLetter F
    
    Start-Sleep -Seconds 20

    Write-Verbose 'Formatting Volume and Assigning Drive Letter'
    
    Format-Volume -DriveLetter F `
              -FileSystem NTFS `
              -NewFileSystemLabel 'Data' `
              -Confirm:$false `
              -Force
}
</pre>
<p><strong>Test-TargetResource</strong> – This function will test the system so see if the set-targetresource should be applied or not. It’ll always return a boolean.</p>
<pre class="brush: powershell; title: ; notranslate">
function Test-TargetResource
{
	[CmdletBinding()]
	[OutputType([System.Boolean])]
	param
	(
		[parameter(Mandatory = $true)]
		[System.UInt64]
		$DriveSize,

		[parameter(Mandatory = $true)]
		[System.UInt32]
		$NumberOfColumns
	)
    
    $result = [System.Boolean]
    Try 
    {
        if (Test-Path F) 
        {
            Write-Verbose 'F:/ exists on target.'
            $result = $true
        }
        else 
        {
            Write-Verbose &quot;F:/ can't be found.&quot;
            $result = $false
        }
    }
    Catch 
    {
        throw &quot;An error occured getting the F:/ drive informations. Error: $($_.Exception.Message)&quot;
    }
    $result
}
</pre>
<h3>Providing Metadata About The Module</h3>
<p>In order to be able to import a Module, it must provide metadata about itself, through a manifest file whose extension is <strong>psd1</strong>. In our case, it can be found at the root of our Module folder hierarchy.</p>
<pre class="brush: plain; title: ; notranslate">C:\Program Files\WindowsPowerShell\Modules\DiskTools\DiskTools.psd1</pre>
<blockquote><p>If you have multiple resource in your module, you will need a new <strong>psd1</strong> in each resource! And a root module should exists in the module manifest.</p></blockquote>
<p>Now, we need to verify that the module is found by PowerShell</p>
<pre class="brush: powershell; title: ; notranslate">
get-module -ListAvailable | ? Name -like &quot;cD*&quot;

ModuleType Version Name
---------- ------- -----------
Manifest   1.0     cDiskTools
</pre>
<p>Great, things seem to be in order. It&#8217;s time to write the DSC Configuration</p>
<pre class="brush: powershell; title: ; notranslate">
configuration DataDisk {
    param (
        [UInt64]$DriveSize = 32TB,
        [UInt32]$NumberOfColumns = 32             
    )

    Import-DscResource -module cDiskTools
    node localhost
    {   
        cDiskTools StripeVHDsAndPrepareVolume 
        {
            DriveSize = $DriveSize
            NumberOfColumns = $NumberOfColumns
        }
    }
}
DataDisk
</pre>
<h3>Testing The Module</h3>
<p>This step can be a bit tricky especially in a scenario where we need disks to sacrifice. In other words, I need a temporary need a Monster Virtual Machine to test this out! Fortunately I have a <a title="Building a Monster Virtual Machine on #Azure" href="https://alexandrebrisebois.wordpress.com/2015/04/29/building-a-monster-virtual-machine-on-azure/" target="_blank">script to create VM on Microsoft Azure</a> with 32 data disks.</p>
<p>Using the script from my previous post, I create a brand new monster. To test this new DSC Module, I logged into the VM using Remote Desktop (RDP). Then I fired up Windows PowerShell and installed the DSC Service.</p>
<pre class="brush: powershell; title: ; notranslate">
Add-WindowsFeature Dsc-Service
</pre>
<p>Copied my module to </p>
<pre class="brush: plain; title: ; notranslate">
C:\Program Files\WindowsPowerShell\Modules
</pre>
<p>And verified that it was found by PowerShell</p>
<pre class="brush: powershell; title: ; notranslate">
get-module -ListAvailable | ? Name -like &quot;cD*&quot;

ModuleType Version Name
---------- ------- -----------
Manifest   1.0     cDiskTools
</pre>
<p>Then I copied the DataDisk.ps1 configuration file to</p>
<pre class="brush: plain; title: ; notranslate">
C:\Configuration\
</pre>
<p>Executing DataDisk.ps1 produces a file (contents shown below) named <strong>localhost.mof</strong>. In this scenario, the file is used to apply the desired configuration to the localhost.</p>
<pre class="brush: plain; title: ; notranslate">
/*
@TargetNode='localhost'
@GeneratedBy=brisebois
@GenerationDate=05/08/2015 05:37:20
@GenerationHost=MSBRISEBOIS
*/

instance of cStripeVHDsAndPrepareVolume as $cStripeVHDsAndPrepareVolume1ref
{
ResourceID = &quot;[cDiskTools]StripeVHDsAndPrepareVolume&quot;;
 NumberOfColumns = 32;
 SourceInfo = &quot;C:\\Configuration\\DataDisk.ps1::10::9::cDiskTools&quot;;
 DriveSize = 35184372088832;
 ModuleName = &quot;cDiskTools&quot;;
 ModuleVersion = &quot;1.0&quot;;

};

instance of OMI_ConfigurationDocument
{
 Version=&quot;1.0.0&quot;;
 Author=&quot;brisebois&quot;;
 GenerationDate=&quot;05/08/2015 05:37:20&quot;;
 GenerationHost=&quot;MSBRISEBOIS&quot;;
};
</pre>
<p>Now it&#8217;s time to test drive our Custom DSC</p>
<pre class="brush: powershell; title: ; notranslate">
Start-DscConfiguration -Path C:\Configuration\DataDisk `
                       -ComputerName localhost `
                       -Force `
                       -wait `
                       -Verbose `
                       -Debug
</pre>
<p>If everything goes well we should get output that looks like the following </p>
<pre class="brush: plain; title: ; notranslate">
VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfiguration
Manager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.
VERBOSE: An LCM method call arrived from computer MSBRISEBOIS with user sid S-1-5-21-2374999437-3767087714-2116828215-500.
VERBOSE: [MSBRISEBOIS]: LCM:  [ Start  Set      ]
VERBOSE: [MSBRISEBOIS]: LCM:  [ Start  Resource ]  [[cDiskTools]StripeVHDsAndPrepareVolume]
VERBOSE: [MSBRISEBOIS]: LCM:  [ Start  Test     ]  [[cDiskTools]StripeVHDsAndPrepareVolume]
VERBOSE: [MSBRISEBOIS]:                            [[cDiskTools]StripeVHDsAndPrepareVolume] F:/ can't be found.
VERBOSE: [MSBRISEBOIS]: LCM:  [ End    Test     ]  [[cDiskTools]StripeVHDsAndPrepareVolume] in 0.2500 seconds.
VERBOSE: [MSBRISEBOIS]: LCM:  [ Start  Set      ]  [[cDiskTools]StripeVHDsAndPrepareVolume]
VERBOSE: [MSBRISEBOIS]:                            [[cDiskTools]StripeVHDsAndPrepareVolume] Creating Storage Pool
VERBOSE: [MSBRISEBOIS]:                            [[cDiskTools]StripeVHDsAndPrepareVolume] Creating Virtual Disk
VERBOSE: [MSBRISEBOIS]:                            [[cDiskTools]StripeVHDsAndPrepareVolume] Initializing Disk
VERBOSE: [MSBRISEBOIS]:                            [[cDiskTools]StripeVHDsAndPrepareVolume] Creating Partition
VERBOSE: [MSBRISEBOIS]:                            [[cDiskTools]StripeVHDsAndPrepareVolume] Formatting Volume and Assigning Drive Letter
VERBOSE: [MSBRISEBOIS]: LCM:  [ End    Set      ]  [[cDiskTools]StripeVHDsAndPrepareVolume] in 210.0800 seconds.
VERBOSE: [MSBRISEBOIS]: LCM:  [ End    Resource ]  [[cDiskTools]StripeVHDsAndPrepareVolume]
VERBOSE: [MSBRISEBOIS]: LCM:  [ End    Set      ]    in  226.3035 seconds.
VERBOSE: Operation 'Invoke CimMethod' complete.
VERBOSE: Time taken for configuration job to complete is 210.862 seconds
</pre>
<h2>In Closing</h2>
<p>Being a developer at heart, I never really took the time to play with PowerShell DSC. As Azure evolves, I&#8217;m pulled in a bunch of new directions and this is definitely one that I will continue to explore. Azure and Automation go hand in hand. It&#8217;s important to be capable to create environments in a repeatable and predictable manner. This is exactly what the Azure Resource Manager (ARM) and PowerShell DSC brings to the table. </p>
<p>This is a game changer for many ongoing projects who struggle with managing environment configurations across regions. Take some time and start digging into PowerShell DSC, your Infrastructure as a Service (IaaS) projects will definitely benefit from it.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/data-disk/'>Data Disk</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/desired-state-configuration/'>Desired State Configuration</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dsc/'>DSC</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dsc-module/'>DSC Module</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/format/'>Format</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/module/'>Module</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/ntfs/'>NTFS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/raid0/'>RAID0</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/stripe/'>Stripe</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/thin/'>Thin</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-disk/'>Virtual Disk</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/volume/'>Volume</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6463/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6463&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/05/08/a-custom-dsc-module-to-stripe-data-disks-on-azure-virtual-machines/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/05/3520082084_b3dfa0aca8_z.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/05/3520082084_b3dfa0aca8_z.jpg?w=150" medium="image">
			<media:title type="html">stripes</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Download Channel 9 Series using PowerShell</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/05/05/download-channel-9-series-using-powershell/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/05/05/download-channel-9-series-using-powershell/#comments</comments>
		<pubDate>Tue, 05 May 2015 15:16:01 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6428</guid>
		<description><![CDATA[ince bandwidth is a precious commodity, and that I don't always have the luxury of having an access point, I decided to re-purpose the script I used to download the Build and Ignite sessions. This new script has only one reason to be; it exists to download Series from Channel 9 so that I can watch them on the go.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6428&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/05/05/download-channel-9-series-using-powershell/" target="_blank" title="Download Channel 9 Series using&nbsp;PowerShell"><img width="580" height="306" src="https://alexandrebrisebois.files.wordpress.com/2015/05/2015-05-05_10h37_56-e1430836798930.png?w=580" class="attachment-large wp-post-image" alt="2015-05-05_10h37_56" /></a></p><h1>Download Channel 9 Series</h1>
<p>It&#8217;s learning season again, and I&#8217;m gearing up for lots of <strong>Azure</strong> this year. Between <a title="Download #Build 2015 Sessions Using PowerShell" href="https://alexandrebrisebois.wordpress.com/2015/05/04/download-build-2015-sessions-using-powershell/" target="_blank">Build</a>, <a title="Download Microsoft Ignite 2015 Sessions Using PowerShell" href="https://alexandrebrisebois.wordpress.com/2015/05/04/download-microsoft-ignite-2015-sessions-using-powershell/" target="_blank">Ignite</a>, the <a href="http://www.microsoftvirtualacademy.com/" target="_blank">Microsoft Virtual Academy</a> and the endless stream of content on <a href="http://channel9.msdn.com/" target="_blank">Channel 9</a>, it&#8217;s easy to feel overwhelmed!</p>
<p>Since bandwidth is a precious commodity, and that I don&#8217;t always have the luxury of having an access point, I decided to re-purpose the script I used to download the <a title="Download #Build 2015 Sessions Using PowerShell" href="https://alexandrebrisebois.wordpress.com/2015/05/04/download-build-2015-sessions-using-powershell/" target="_blank">Build</a> and <a title="Download Microsoft Ignite 2015 Sessions Using PowerShell" href="https://alexandrebrisebois.wordpress.com/2015/05/04/download-microsoft-ignite-2015-sessions-using-powershell/" target="_blank">Ignite</a> sessions. This new script has only one reason to be; it exists to download <a href="http://channel9.msdn.com/Browse/Series" target="_blank">Series from Channel 9</a> so that I can watch them on the go.</p>
<p>Going through the list of Series, I was amazed by the amount of new content. I found MVA sessions and a bunch of other interesting topics related to Azure.<span id="more-6428"></span></p>
<p>Feel free to use the comments section at the bottom of this post to suggest feeds that I should pay attention to.</p>
<h2>The Script</h2>
<p>To execute this script, I used Windows Powershell ISE and I manually download the Series that interest me. Browse through the series that I identified for myself. Who knows, you may find something of interest.</p>
<pre class="brush: powershell; title: ; notranslate">
function Get-Media
{
    [CmdletBinding()]
    param
    (
        [Object]
        $url,
        [Object]
        $title,
        [Object]
        $path
    )

    $u = New-Object System.Uri($url)
    $name = $title
    $extension = [System.IO.Path]::GetExtension($u.Segments[-1])
    $fileName = $name + $extension

    $fileName = $fileName -replace &quot;â€™&quot;, ''
    $fileName = $fileName -replace &quot;\?&quot;, ''
    $fileName = $fileName -replace &quot;:&quot;, ''
    $fileName = $fileName -replace '/', ''
    $fileName = $fileName -replace &quot;,&quot;, ''
    $fileName = $fileName -replace '&quot;', ''

    $fileName

    if (Test-Path($fileName)) {
        Write-Host 'Skipping file, already downloaded' -ForegroundColor Yellow
    }
    else
    {
        Invoke-WebRequest $url -OutFile (Join-Path -Path $path -ChildPath $fileName)
    }
}

function Get-VideosFromFeed
{
    [CmdletBinding()]
    param
    (
        [Object]
        $feedUrl,
        [Object]
        $folder,
        [Object]
        $path
    )

    $feed=[xml](New-Object System.Net.WebClient).DownloadString($feedUrl)

    $downloadPath = (Join-Path -Path $path -ChildPath $folder)

    if (Test-Path($downloadPath)) {
        Write-Host 'Skipping folder, already exists' -ForegroundColor Yellow
    }
    else
    {
        New-Item -Path $downloadPath -ItemType directory -WarningAction SilentlyContinue
    }

    foreach($i in $feed.rss.channel.item) {
        foreach($m in $i.group){
            foreach($u in $m.content `
                    | Where-Object { `
                            $_.url -like '*mid.mp4' `
                         } | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                     @{Name='title'; Expression = {$i.title}})
            {
                Get-Media -url $u.url -title $u.title -path $downloadPath
            }
        }
    }
}

$physicalPath = &quot;V:\Videos\Series&quot;

# Microsoft Datacenter vNext Preview: Bringing Azure to Your Datacenter
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Microsoft-Datacenter-vNext-Preview-Bringing-Azure-to-Your-Datacenter/RSS' -path $physicalPath -folder 'Data Center Preview'

# Microsoft Azure Fundamentals: Virtual Machines
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Microsoft-Azure-Fundamentals-Virtual-Machines/RSS' -path $physicalPath -folder 'Microsoft Azure Fundamentals Virtual Machines'

# Adding Microsoft Azure Search to Your Websites and Apps
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Adding-Microsoft-Azure-Search-to-Your-Websites-and-Apps/RSS' -path $physicalPath -folder 'Working with Azure Search'

# Docker for .NET Developers
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Docker-for-NET-Developers/RSS' -path $physicalPath -folder 'Docker for NET Devs'

# Storage Spaces Deep Dive
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Storage-Spaces-Deep-Dive/RSS' -path $physicalPath -folder 'Storage Spaces Deep Dive'

# Cloud DevCamp
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Cloud-DevCamp/RSS' -path $physicalPath -folder 'Cloud DevCamp'

# Microsoft Azure Back End for Gaming
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Microsoft-Azure-Back-End-for-Gaming/RSS' -path $physicalPath -folder 'Microsoft Azure Back End for Gaming'

# Azure App Service
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Windows-Azure-Web-Sites-Tutorials/RSS' -path $physicalPath -folder 'Azure App Service'

# Developing Solutions with Azure DocumentDB
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Developing-Solutions-with-Azure-DocumentDB/RSS' -path $physicalPath -folder 'Developing Solutions with Azure DocumentDB'

# Big Data Analytics with HDInsight
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Big-Data-Analytics-with-HDInsight/RSS' -path $physicalPath -folder 'Big Data Analytics with HDInsight'

# Microsoft Hybrid Cloud Best Practices for IT Pros
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Microsoft-Hybrid-Cloud-Best-Practices-for-IT-Pros/RSS' -path $physicalPath -folder 'Microsoft Hybrid Cloud Best Practices for IT Pros'

# Java on Microsoft Azure
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Java-on-Microsoft-Azure/RSS' -path $physicalPath -folder 'Java on Microsoft Azure'

# Azure Active Directory Core Skills
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Azure-Active-Directory-Core-Skills/RSS' -path $physicalPath -folder 'Azure Active Directory Core Skills'

# Managing Linux Workloads in Windows Server and System Center
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Managing-Linux-Workloads-in-Windows-Server-and-System-Center/RSS' -path $physicalPath -folder 'Managing Linux Workloads in Windows Server and System Center'

# All About Microsoft Azure Operational Insights
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/All-About-Microsoft-Azure-Operational-Insights/RSS' -path $physicalPath -folder 'All About Microsoft Azure Operational Insights'

# You ve Got Key Values! A Redis Jump Start
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Youve-Got-Key-Values-A-Redis-Jump-Start/RSS' -path $physicalPath -folder 'You ve Got Key Values! A Redis Jump Start'

# Azure Solution Training
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Azure-Solutions-Training/RSS' -path $physicalPath -folder 'Azure Solution Training'

# Advanced PowerShell Desired State Configuration (DSC) and Custom Resources
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Advanced-PowerShell-Desired-State-Configuration-DSC-and-Custom-Resources/RSS' -path $physicalPath -folder 'Advanced PowerShell Desired State Configuration (DSC) and Custom Resources'

# Getting Started with PowerShell Desired State Configuration (DSC)
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Getting-Started-with-PowerShell-Desired-State-Configuration-DSC/RSS' -path $physicalPath -folder 'Getting Started with PowerShell Desired State Configuration (DSC)'

# Polyglot Persistence: Choosing the Right Azure Storage Mix
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Polyglot-Persistence-Choosing-the-Right-Azure-Storage-Mix/RSS' -path $physicalPath -folder 'Polyglot Persistence Choosing the Right Azure Storage Mix'

# Getting Started with Microsoft Azure Active Directory
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Getting-Started-with-Microsoft-Azure-Active-Directory/RSS' -path $physicalPath -folder 'Getting Started with Microsoft Azure Active Directory'

# MEAN Stack Jump Start
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/MEAN-Stack-Jump-Start/RSS' -path $physicalPath -folder 'MEAN Stack Jump Start'

# Managing Your Systems on Microsoft Azure with Chef
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Managing-Your-Systems-on-Microsoft-Azure-with-Chef/RSS' -path $physicalPath -folder 'Managing Your Systems on Microsoft Azure with Chef'

# Connect(On Demand);
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/ConnectOn-Demand/RSS' -path $physicalPath -folder 'Connect(On Demand)'

# Partner Profitability: Cloud Transformation Series
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Partner-Profitability-Cloud-Transformation-Series/RSS' -path $physicalPath -folder 'Partner Profitability Cloud Transformation Series'

# Web API Design
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Web-API-Design/RSS' -path $physicalPath -folder 'Web API Design'

# Developing Microsoft SQL Server Databases
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Developing-Microsoft-SQL-Server-Databases/RSS' -path $physicalPath -folder 'Developing Microsoft SQL Server Databases'

# Monitor Workloads with System Center Operations Manager
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Monitor-Workloads-with-System-Center-Operations-Manager/RSS' -path $physicalPath -folder 'Monitor Workloads with System Center Operations Manager'

# Azure HDInsight Service
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Getting-started-with-Windows-Azure-HDInsight-Service/RSS' -path $physicalPath -folder 'Azure HDInsight Service'

# Automate Workloads with System Center Orchestrator
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Automate-Workloads-with-System-Center-Orchestrator/RSS' -path $physicalPath -folder 'Automate Workloads with System Center Orchestrator'

# Open Source for DevOps Practices
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Open-Source-for-DevOps-Practices/RSS' -path $physicalPath -folder 'Open Source for DevOps Practices'

# Developing Microsoft Azure Solutions
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Developing-Microsoft-Azure-Solutions/RSS' -path $physicalPath -folder 'Developing Microsoft Azure Solutions'

# Architecting Microsoft Azure Solutions
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Architecting-Microsoft-Azure-Solutions/RSS' -path $physicalPath -folder 'Architecting Microsoft Azure Solutions'

# Getting Great Performance out of Azure
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Getting-Great-Performance-out-of-Azure/RSS' -path $physicalPath -folder 'Getting Great Performance out of Azure'

# Azure Networking Fundamentals for IT Pros
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Azure-Networking-Fundamentals-for-IT-Pros/RSS' -path $physicalPath -folder 'Azure Networking Fundamentals for IT Pros'

# PHP for Azure
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/PHP-for-Azure/RSS' -path $physicalPath -folder 'PHP for Azure'

# You ve Got Documents! A MongoDB Jump Start
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Youve-Got-Documents-A-MongoDB-Jump-Start/RSS' -path $physicalPath -folder 'You ve Got Documents - A MongoDB Jump Start'

# Designing Solutions for SQL Server
Get-VideosFromFeed -feedUrl 'http://channel9.msdn.com/Series/Designing-Solutions-for-SQL-Server/RSS' -path $physicalPath -folder 'Designing Solutions for SQL Server'
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6428/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6428/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6428/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6428&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/05/05/download-channel-9-series-using-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/05/2015-05-05_10h37_56-e1430836798930.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/05/2015-05-05_10h37_56-e1430836798930.png?w=150" medium="image">
			<media:title type="html">2015-05-05_10h37_56</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Download Microsoft Ignite 2015 Sessions Using PowerShell</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/05/04/download-microsoft-ignite-2015-sessions-using-powershell/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/05/04/download-microsoft-ignite-2015-sessions-using-powershell/#comments</comments>
		<pubDate>Tue, 05 May 2015 03:26:48 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[2015]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[Ignite]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6413</guid>
		<description><![CDATA[Download All Sessions in SD Quality Download Sessions Based on Filters in SD QualityFiled under: Microsoft Azure Tagged: 2015, Download, Ignite, Microsoft Azure, PowerShell<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6413&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/05/04/download-microsoft-ignite-2015-sessions-using-powershell/" target="_blank" title="Download Microsoft Ignite 2015 Sessions Using&nbsp;PowerShell"><img width="580" height="121" src="https://alexandrebrisebois.files.wordpress.com/2015/05/1dac3c83-b376-4cad-a889-c44f2a555c4f.png?w=580" class="attachment-large wp-post-image" alt="1dac3c83-b376-4cad-a889-c44f2a555c4f" /></a></p><h1>Download All Sessions in SD Quality</h1>
<pre class="brush: powershell; title: ; notranslate">
$feedUrl = 'http://s.ch9.ms/Events/Ignite/2015/RSS'
 
[Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath
function Get-Media
{
    [CmdletBinding()]
    param
    (
        [Object]
        $url,
        [Object]
        $title
    )
     
    $u = New-Object System.Uri($url)
    $name = $title
    $extension = [System.IO.Path]::GetExtension($u.Segments[-1])
    $fileName = $name + $extension

    $fileName = $fileName -replace &quot;â€™&quot;, ''
    $fileName = $fileName -replace &quot;\?&quot;, ''
    $fileName = $fileName -replace &quot;:&quot;, ''
    $fileName = $fileName -replace '/', ''
    $fileName = $fileName -replace &quot;,&quot;, ''
    $fileName = $fileName -replace '&quot;', ''

    $fileName
            
    if (Test-Path($fileName)) {
        Write-Host 'Skipping file, already downloaded' -ForegroundColor Yellow
    }
    else
    {
        Invoke-WebRequest $url -OutFile $fileName
    }
}
  
$feed=[xml](New-Object System.Net.WebClient).DownloadString($feedUrl)
 
foreach($i in $feed.rss.channel.item) {
    foreach($m in $i.group){
        foreach($u in $m.content `
                | Where-Object { `
                        $_.url -like '*mid.mp4' `
                     } | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                 @{Name='title'; Expression = {$i.title}})
        {
            Get-Media -url $u.url -title $u.title
        }             
    }
}

# Find and Download Keynotes

foreach($i in $feed.rss.channel.item) {
    foreach($m in $i.group){
        foreach($u in $m.content `
                | Where-Object { `
                        $_.url -like '*KEY0*' `
                        -and $_.type -eq 'video/mp4' `
                       
                     } `
                     | Select-Object -Unique `
                     | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                 @{Name='title'; Expression = {$i.title}})
        {
            Get-Media -url $u.url -title $u.title
        }             
    }
}
</pre>
<p><span id="more-6413"></span></p>
<h2>Download Sessions Based on Filters in SD Quality</h2>
<pre class="brush: powershell; title: ; notranslate">
$feedUrl = 'http://s.ch9.ms/Events/Ignite/2015/RSS'
  
[Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath
function Get-Media
{
    [CmdletBinding()]
    param
    (
        [Object]
        $url,
        [Object]
        $title
    )
      
    $u = New-Object System.Uri($url)
    $name = $title
    $extension = [System.IO.Path]::GetExtension($u.Segments[-1])
    $fileName = $name + $extension
 
    $fileName = $fileName -replace &quot;â€™&quot;, ''
    $fileName = $fileName -replace &quot;\?&quot;, ''
    $fileName = $fileName -replace &quot;:&quot;, ''
    $fileName = $fileName -replace '/', ''
    $fileName = $fileName -replace &quot;,&quot;, ''
    $fileName = $fileName -replace '&quot;', ''
 
    $fileName
             
    if (Test-Path($fileName)) {
        Write-Host 'Skipping file, already downloaded' -ForegroundColor Yellow
    }
    else
    {
        Invoke-WebRequest $url -OutFile $fileName
    }
}
   
$feed=[xml](New-Object System.Net.WebClient).DownloadString($feedUrl)
  
foreach($i in $feed.rss.channel.item) {
    foreach($m in $i.group){
        foreach($u in $m.content `
                | Where-Object { `
                        $_.url -like '*mid.mp4' `

                        # Filter by keywords
                        -and ($i.description.'#cdata-section' -like '*azure*' `
                              -or $i.title -like '*azure*' `

                         ) `
                     } | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                 @{Name='title'; Expression = {$i.title}})
        {
            #Get-Media -url $u.url -title $u.title
            Write-Output $u.title
        }
    }
}
 
# Find and Download Keynotes
 
foreach($i in $feed.rss.channel.item) {
    foreach($m in $i.group){
        foreach($u in $m.content `
                | Where-Object { `
                        $_.url -like '*KEY0*' `
                        -and $_.type -eq 'video/mp4' `                        
                     } `
                     | Select-Object -Unique `
                     | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                 @{Name='title'; Expression = {$i.title}})
        {
            Write-Output $u.title
            #Get-Media -url $u.url -title $u.title
        }             
    }
}
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/2015/'>2015</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/download/'>Download</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/ignite/'>Ignite</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6413/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6413/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6413/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6413/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6413/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6413/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6413/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6413/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6413/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6413/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6413/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6413/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6413/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6413/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6413&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/05/04/download-microsoft-ignite-2015-sessions-using-powershell/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/05/1dac3c83-b376-4cad-a889-c44f2a555c4f.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/05/1dac3c83-b376-4cad-a889-c44f2a555c4f.png?w=150" medium="image">
			<media:title type="html">1dac3c83-b376-4cad-a889-c44f2a555c4f</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Download #Build 2015 Sessions Using PowerShell</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/05/04/download-build-2015-sessions-using-powershell/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/05/04/download-build-2015-sessions-using-powershell/#comments</comments>
		<pubDate>Mon, 04 May 2015 16:51:46 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[2015]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6406</guid>
		<description><![CDATA[Download All Sessions in SD Quality Download Sessions Based on Filters in SD QualityFiled under: Microsoft Azure Tagged: 2015, Build, Download, Microsoft Azure, PowerShell<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6406&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/05/04/download-build-2015-sessions-using-powershell/" target="_blank" title="Download #Build 2015 Sessions Using&nbsp;PowerShell"><img width="580" height="151" src="https://alexandrebrisebois.files.wordpress.com/2015/05/be1b9a2a-6ad4-4bcd-91d4-238ebb1f0c88.png?w=580" class="attachment-large wp-post-image" alt="be1b9a2a-6ad4-4bcd-91d4-238ebb1f0c88" /></a></p><h1>Download All Sessions in SD Quality</h1>
<pre class="brush: powershell; title: ; notranslate">
$feedUrl = 'http://s.ch9.ms/Events/Build/2015/RSS'
 
[Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath
function Get-Media
{
    [CmdletBinding()]
    param
    (
        [Object]
        $url,
        [Object]
        $title
    )
     
    $u = New-Object System.Uri($url)
    $name = $title
    $extension = [System.IO.Path]::GetExtension($u.Segments[-1])
    $fileName = $name + $extension

    $fileName = $fileName -replace &quot;â€™&quot;, ''
    $fileName = $fileName -replace &quot;\?&quot;, ''
    $fileName = $fileName -replace &quot;:&quot;, ''
    $fileName = $fileName -replace '/', ''
    $fileName = $fileName -replace &quot;,&quot;, ''
    $fileName = $fileName -replace '&quot;', ''

    $fileName
            
    if (Test-Path($fileName)) {
        Write-Host 'Skipping file, already downloaded' -ForegroundColor Yellow
    }
    else
    {
        Invoke-WebRequest $url -OutFile $fileName
    }
}
  
$feed=[xml](New-Object System.Net.WebClient).DownloadString($feedUrl)
 
foreach($i in $feed.rss.channel.item) {
    foreach($m in $i.group){
        foreach($u in $m.content `
                | Where-Object { `
                        $_.url -like '*mid.mp4' `
                     } | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                 @{Name='title'; Expression = {$i.title}})
        {
            Get-Media -url $u.url -title $u.title
        }             
    }
}

# Find and Download Keynotes

foreach($i in $feed.rss.channel.item) {
    foreach($m in $i.group){
        foreach($u in $m.content `
                | Where-Object { `
                        $_.url -like '*KEY0*' `
                        -and $_.type -eq 'video/mp4' `                       
                     } `
                     | Select-Object -Unique `
                     | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                 @{Name='title'; Expression = {$i.title}})
        {
            Get-Media -url $u.url -title $u.title
        }             
    }
}
</pre>
<p><span id="more-6406"></span></p>
<h2>Download Sessions Based on Filters in SD Quality</h2>
<pre class="brush: powershell; title: ; notranslate">
$feedUrl = 'http://s.ch9.ms/Events/Build/2015/RSS'
 
[Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath
function Get-Media
{
    [CmdletBinding()]
    param
    (
        [Object]
        $url,
        [Object]
        $title
    )
     
    $u = New-Object System.Uri($url)
    $name = $title
    $extension = [System.IO.Path]::GetExtension($u.Segments[-1])
    $fileName = $name + $extension

    $fileName = $fileName -replace &quot;â€™&quot;, ''
    $fileName = $fileName -replace &quot;\?&quot;, ''
    $fileName = $fileName -replace &quot;:&quot;, ''
    $fileName = $fileName -replace '/', ''
    $fileName = $fileName -replace &quot;,&quot;, ''
    $fileName = $fileName -replace '&quot;', ''

 
    $fileName
            
    if (Test-Path($fileName)) {
        Write-Host 'Skipping file, already downloaded' -ForegroundColor Yellow
    }
    else
    {
        Invoke-WebRequest $url -OutFile $fileName
    }
}
  
$feed=[xml](New-Object System.Net.WebClient).DownloadString($feedUrl)
 
foreach($i in $feed.rss.channel.item) {
    foreach($m in $i.group){
        foreach($u in $m.content `
                | Where-Object { `
                        $_.url -like '*mid.mp4' `
                        -and ($i.description.'#cdata-section' -like '*azure*' `
                              -or $i.title -like '*azure*' `
                         ) `
                     } | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                 @{Name='title'; Expression = {$i.title}})
        {
            Get-Media -url $u.url -title $u.title
        }             
    }
}

# Find and Download Keynotes

foreach($i in $feed.rss.channel.item) {
    foreach($m in $i.group){
        foreach($u in $m.content `
                | Where-Object { `
                        $_.url -like '*KEY0*' `
                        -and $_.type -eq 'video/mp4' `
                     } `
                     | Select-Object -Unique `
                     | Select-Object -Property @{Name='url'; Expression = {$_.url}}, `
                                                 @{Name='title'; Expression = {$i.title}})
        {
            Get-Media -url $u.url -title $u.title
        }             
    }
}
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/2015/'>2015</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/build/'>Build</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/download/'>Download</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6406/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6406/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6406/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6406/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6406/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6406/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6406/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6406/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6406/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6406/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6406/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6406/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6406/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6406/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6406&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/05/04/download-build-2015-sessions-using-powershell/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/05/be1b9a2a-6ad4-4bcd-91d4-238ebb1f0c88.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/05/be1b9a2a-6ad4-4bcd-91d4-238ebb1f0c88.png?w=150" medium="image">
			<media:title type="html">be1b9a2a-6ad4-4bcd-91d4-238ebb1f0c88</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Sometimes You Just Have to Scale Up!</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/05/01/sometimes-you-just-have-to-scale-up/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/05/01/sometimes-you-just-have-to-scale-up/#comments</comments>
		<pubDate>Fri, 01 May 2015 13:30:59 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Azure Storage]]></category>
		<category><![CDATA[Blobs Storage]]></category>
		<category><![CDATA[Dev & Test]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[OS Disk]]></category>
		<category><![CDATA[Page Blob]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[VHD]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Virtual Machines]]></category>
		<category><![CDATA[VM Image]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=1118</guid>
		<description><![CDATA[As I move from project to project, the resource requirements vary, and sometimes I need more resources. Fortunately we can scale our Virtual Machines up and down through PowerShell and the Azure Portal.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=1118&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/05/01/sometimes-you-just-have-to-scale-up/" target="_blank" title="Sometimes You Just Have to Scale&nbsp;Up!"><img width="580" height="348" src="https://alexandrebrisebois.files.wordpress.com/2014/12/2015-04-29_08h49_40.png?w=580" class="attachment-large wp-post-image" alt="2015-04-29_08h49_40" /></a></p><p>In my last <a title="A Dev and Test Adventure on #Azure" href="https://alexandrebrisebois.wordpress.com/2015/03/27/a-dev-and-test-adventure-on-azure/" target="_blank">blog post</a> I shared about how I use a Microsoft Azure Virtual Machine as my development machine. It&#8217;s been a month since I made this drastic change, and I must admit that it&#8217;s been pretty cool! The Azure Virtual Machine has provided me with more agility in my hectic schedule. I&#8217;ve been able to start my day from one machine, move to a different machine and continue from where I left off. I no longer deal with putting my machine to sleep or trying to remember where I was when I left off. When I log off from one machine, I log back in right where I left off.</p>
<h1>It&#8217;s Getting Tight</h1>
<p>As I move from project to project, the resource requirements vary, and sometimes I need more resources. Fortunately, we can scale our Virtual Machines up and down through PowerShell and the Azure Portal.<span id="more-1118"></span> I usually work with a Standard D2 Virtual Machine, that translates to 2 Cores 7 GB of RAM and a 100GB SSD Temp Disk. On some occasions, I scale-up to a Standard D4, that translates to 8 Cores 28GB of RAM and a 400GB SSD Temp Disk.</p>
<pre class="brush: powershell; title: ; notranslate">
$serviceName = 'mydevmachine'
$name = 'mydevmachine'

# Stop the Azure VM
Stop-AzureVM -Name $name -ServiceName $serviceName -Force

# Get a reference to the Azure VM
$vm = Get-AzureVM -Name $name -ServiceName $serviceName

# Wait for the VM to reach the StoppedDeallocated State
Write-Output $('VM state is '+ $vm.InstanceStatus)

while( $vm.InstanceStatus -ne 'StoppedDeallocated')
{
    Start-Sleep -s 10
    $vm = Get-AzureVM -Name $name -ServiceName $serviceName
    Write-Output $('VM state is '+ $vm.InstanceStatus)
}

# Set the Instance Size &amp; Update the WM
Set-AzureVMSize -InstanceSize Standard_D4 -VM $vm | Update-AzureVM

# Start the Azure VM
Start-AzureVM -Name $name -ServiceName $serviceName

# Wait for the VM to reach the ReadyRole State
$vm = Get-AzureVM -Name $name -ServiceName $serviceName
Write-Output $('VM state is '+ $vm.InstanceStatus)

while( $vm.InstanceStatus -ne 'ReadyRole')
{
    Start-Sleep -s 10
    $vm = Get-AzureVM -Name $name -ServiceName $serviceName
    Write-Output $('VM state is '+ $vm.InstanceStatus)
}

# VM Boot Grace Period
Start-Sleep -s 60

# Download and launch a Remote Desktop Session to the resized Azure VM
Get-AzureRemoteDesktopFile -Name $name -ServiceName $serviceName -Launch
</pre>
<h2>UH OH!</h2>
<p>The instance size we are looking for isn’t available? Don’t worry about it just yet. Not all Azure server racks are created equal. This means that if the Virtual Machine was initially created as a Standard A1, the configurations we are looking for might not be available. Consequentially, scaling to a newer Virtual Machine configuration requires us to take a different approach. First off, let&#8217;s find out if the Virtual Machine Instance Size is available in our Data Center.</p>
<pre class="brush: powershell; title: ; notranslate">
Get-AzureLocation `
 | Where-Object {$_.VirtualMachineRoleSizes -contains 'A9'} `
 | Select-Object -Property Name

Name
----
South Central US
West US
East US
North Europe
West Europe
Japan East
</pre>
<p>If for some reason, the Data Center doesn&#8217;t have the desired Virtual Machine Instance Size available. We can review the list of Instance Sizes for a specific Data Center. Then we can decide whether we want to migrate to another Data Center or chose to use a different Virtual Machine Instance Size.</p>
<pre class="brush: powershell; title: ; notranslate">
Get-AzureLocation `
| Where-Object -Property Name -EQ 'East US 2' `
| Select-Object -ExpandProperty VirtualMachineRoleSizes

A5
A6
A7
Basic_A0
Basic_A1
Basic_A2
Basic_A3
Basic_A4
ExtraLarge
ExtraSmall
Large
Medium
Small
Standard_D1
Standard_D11
Standard_D12
Standard_D13
Standard_D14
Standard_D2
Standard_D3
Standard_D4
Standard_DS1
Standard_DS11
Standard_DS12
Standard S_DS13
Standard_DS14
Standard_DS2
Standard_DS3
Standard_DS4
Standard_G1
Standard_G2
Standard_G3
Standard_G4
Standard_G5
</pre>
<p>As of April 30th 2015, the East US 2 Data Center has the D, DS and G Series but it does not have A8, A9, A10 or A11 Virtual Machine configurations. Scaling to A9 Virtual Machine, that translates to 16 Cores 112 GB of RAM, 382GB Temp Disk, 40Gbit/s InfiniBand network and remote direct memory access (RDMA) would require me to move my Virtual Machine to the East US Data Center.</p>
<h2>It&#8217;s Time to Move</h2>
<p>The first step towards moving, is to capture an Image of the Virtual Machine that we want to move. Before we start, be sure that the Virtual Machine is in a StoppedDeallocated state.</p>
<pre class="brush: powershell; title: ; notranslate">
$servicename = &quot;mydevmachine&quot;
$vmname = &quot;mydevmachine&quot;

Get-AzureVM -ServiceName $servicename `
            -Name $vmname `
| Stop-AzureVM -Force
</pre>
<p>Then capture the Virtual Machine Image and give it a meaningful name</p>
<pre class="brush: powershell; title: ; notranslate">
Save-AzureVMImage –ServiceName $servicename `
                  –Name $vmname `
                  –ImageName &quot;BriseboisDevMachine&quot; `
                  –OSState &quot;Specialized&quot; `
                  -Verbose
</pre>
<p>Create a Storage Account Context</p>
<pre class="brush: powershell; title: ; notranslate">
# Source Storage Account Context
$sourceStorageAccountName = &quot;briseboisms1&quot;
$sourceKey = (Get-AzureStorageKey -StorageAccountName $sourceStorageAccountName).Primary
$sourceContext = New-AzureStorageContext –StorageAccountName $sourceStorageAccountName `
                                         -StorageAccountKey $sourceKey
</pre>
<p>Then find the VHD created by the Save-AzureVMImage cmdlet.</p>
<pre class="brush: powershell; title: ; notranslate">
Get-AzureStorageBlob -Container 'vhds' -Context $sourceContext

Container Uri: https://briseboisms.blob.core.windows.net/vhds

Name                                   BlobType  Length        ContentType              LastModified                 SnapshotTime
----                                   --------  ------        -----------              ------------                 ------------
BriseboisDevMachine-os-2015-04-30.vhd  PageBlob  136367309312  application/octet-stream 4/30/2015 9:58:31 PM +00:00
</pre>
<p>Create a Storage Account in the Data Center that has the desired Virtual Machine Instance Size.</p>
<pre class="brush: powershell; title: ; notranslate">
$destinationStorageAccountName = 'briseboisuseast1'

New-AzureStorageAccount -StorageAccountName $destinationStorageAccountName `
                        -Location 'East US' `
                        -Type 'Standard_GRS'
</pre>
<p>Copy the VHD created by the Save-AzureVMImage cmdlet to the newly Storage Account.</p>
<pre class="brush: powershell; title: ; notranslate">
$blobName = 'BriseboisDevMachine-os-2015-04-30.vhd'
$container = 'vhds'

# Destination Storage Account Contex
$destinationKey = (Get-AzureStorageKey -StorageAccountName $destinationStorageAccountName).Primary
$destinationContext = New-AzureStorageContext –StorageAccountName $destinationStorageAccountName `
                                              -StorageAccountKey $destinationKey  

# Create the destination container
New-AzureStorageContainer -Name $container `
                          -Context $destinationContext 

# Copy the blob
$blobCopy = Start-AzureStorageBlobCopy -DestContainer $container `
                                       -DestContext $destinationContext `
                                       -SrcBlob $blobName `
                                       -Context $sourceContext `
                                       -SrcContainer $container

# Blob Copy Progress
while(($blobCopy | Get-AzureStorageBlobCopyState).Status -eq &quot;Pending&quot;)
{
    Start-Sleep -s 30
    $blobCopy | Get-AzureStorageBlobCopyState
}
</pre>
<p>Now it&#8217;s time to re-hydrate the Virtual Machine with the desired Instance Size</p>
<pre class="brush: powershell; title: ; notranslate">
# Add the Captured Virtual Machine as a VM Image
Add-AzureVMImage -ImageName BriseboisDevMachineEast `
                 -OS Windows `
                 -MediaLocation &quot;https://$destinationStorageAccountName.blob.core.windows.net/vhds/$blobName&quot;

# Verify that the VM Image has been added as expected
Get-AzureVMImage | Where-Object {$_.Location -eq 'East US'} `
                 | Where-Object {$_.ImageName -eq 'BriseboisDevMachineEast'} `
                 | Select-Object { $_.ImageName , $_.Location }

# Switch the CurrentStorageAccount to the destination Storage Account
Set-AzureSubscription -SubscriptionName 'Visual Studio Ultimate with MSDN' `
                      -CurrentStorageAccountName $destinationStorageAccountName

# Create the Virtual Machine using the newly created VM Image
New-AzureQuickVM -Windows `
-ServiceName BriseboisDev `
-Name BriseboisDev `
-ImageName BriseboisDevMachineEast `
-InstanceSize 'A9' `
-Password 'MY-PASSWORD' `
-Location 'East US' `
-AdminUsername 'MY-USERNAME' `
-Verbose
</pre>
<p>Once the Virtual Machine is running, we can RDP into it and resume our operations.</p>
<pre class="brush: powershell; title: ; notranslate">
# Download and Launch RDP file for the new Azure VM
Get-AzureRemoteDesktopFile -ServiceName BriseboisDevMachineEast `
                           -Name BriseboisDevMachineEast `
                           -Launch
</pre>
<h3>Note</h3>
<blockquote><p>Creating Larger Virtual Machines may take more time than what you would expect for smaller Virtual Machine Instance Sizes. This is because Azure has to find a location with enough resources to provision the instance. If you shut down a large Virtual Machine, you may encounter a situation where the Azure fabric is unable to start the Virtual Machine. One way to solve this, is to re-size the Virtual Machine by using a technique similar with the one found in the first section of this post. This will result in Azure to create an instance in a rack that has enough resources to meet the Virtual Machine Instance Size requirements.</p></blockquote>
<a href="http://azure.microsoft.com/blog/2015/03/19/allocation-failure-and-remediation/"><img class="aligncenter wp-image-6370 size-full" src="https://alexandrebrisebois.files.wordpress.com/2014/12/allocationblogpost3.png?w=580" alt=""   /></a>
<h2>Resources</h2>
<ul>
<li><a href="http://azure.microsoft.com/blog/2014/05/01/vm-image-powershell-how-to-blog-post/" target="_blank">VM Image PowerShell ‘How To’ Blog Post</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/articles/virtual-machines-capture-image-windows-server/" target="_blank">How to Capture a Windows Virtual Machine to Use as a Template</a></li>
<li><a href="http://azure.microsoft.com/blog/2014/10/22/migrate-azure-virtual-machines-between-storage-accounts/" target="_blank">Migrate Azure Virtual Machines between Storage Accounts</a></li>
<li><a href="http://blogs.msdn.com/b/mast/archive/2014/11/20/recovering-azure-vm-by-attaching-os-disk-to-another-azure-vm.aspx" target="_blank">Recover Azure VM by attaching OS disk to another Azure VM</a></li>
<li><a title="Failed to Start Virtual Machine" href="https://social.msdn.microsoft.com/forums/azure/en-us/6d52acbe-10c2-46cb-84e8-721b7ce60846/failed-to-start-virtual-machine" target="_blank">Failed to Start Virtual Machine</a></li>
<li><a href="http://azure.microsoft.com/blog/2015/03/19/allocation-failure-and-remediation/" target="_blank">Allocation Failure and Remediation</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-storage/'>Azure Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blobs-storage/'>Blobs Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dev-test/'>Dev &amp; Test</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iaas/'>IaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/migration/'>Migration</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/os-disk/'>OS Disk</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/page-blob/'>Page Blob</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/vhd/'>VHD</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machines/'>Virtual Machines</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/vm-image/'>VM Image</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/1118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/1118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/1118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/1118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/1118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/1118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/1118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/1118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/1118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/1118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/1118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/1118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/1118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/1118/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=1118&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/05/01/sometimes-you-just-have-to-scale-up/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/12/2015-04-29_08h49_40.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/2015-04-29_08h49_40.png?w=150" medium="image">
			<media:title type="html">2015-04-29_08h49_40</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/allocationblogpost3.png" medium="image" />
	</item>
		<item>
		<title>Building a Monster Virtual Machine on #Azure</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/04/29/building-a-monster-virtual-machine-on-azure/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/04/29/building-a-monster-virtual-machine-on-azure/#comments</comments>
		<pubDate>Wed, 29 Apr 2015 21:14:20 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Blobs Storage]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Data Disk]]></category>
		<category><![CDATA[Format]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Premium Storage]]></category>
		<category><![CDATA[Storage Space]]></category>
		<category><![CDATA[Stripe]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Volume]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6311</guid>
		<description><![CDATA[Microsoft Azure is all about the opportunity to push back on known boundaries. In the last couple of months, I dealt with some scenarios where on-premises Data Centers ran out of capacity. Consequently, we were not able to push our tests as far as we would have liked. Taking the work loads to Microsoft Azure gave us the <a href="https://alexandrebrisebois.wordpress.com/2013/02/20/floor-it-then-kick-it-back-a-notch/" target="_blank">opportunity to stretch workloads to their limits</a>.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6311&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/04/29/building-a-monster-virtual-machine-on-azure/" target="_blank" title="Building a Monster Virtual Machine on&nbsp;#Azure"><img width="580" height="499" src="https://alexandrebrisebois.files.wordpress.com/2015/04/2322_201208225522551qjrv.jpg?w=580" class="attachment-large wp-post-image" alt="2322_201208225522551qJrV" /></a></p><p>Microsoft Azure is all about the opportunity to push back on known boundaries. In the last couple of months, I dealt with some scenarios where on-premises Data Centers ran out of capacity. Consequently, we were not able to push our tests as far as we would have liked. Taking the work loads to Microsoft Azure gave us the <a href="https://alexandrebrisebois.wordpress.com/2013/02/20/floor-it-then-kick-it-back-a-notch/" target="_blank">opportunity to stretch workloads to their limits</a>.</p>
<p>In one of these scenarios, the workload was limited to 16 aging physical machines, and the time required to process the data was not acceptable. We needed to find ways to reduce the compute time, and had means to accomplish this on-premises. Pushing this workload to its limits, we deployed it on Microsoft Azure and provisioned it with well over 256 cores. We ended up processing workloads so fast that we now had the opportunity to run them multiple times a day. This newly discovered agility gave us the ability to refine the workload processes without disturbing ongoing business activities.</p>
<p>The first scenario was all about the lack of compute resources necessary to push a workload to its full potential. In a second scenario, we needed an impressive amount of resources within a single Virtual Machine. This blog post is all about how we created this Monster VM.</p>
<h1>Building a Monster VM</h1>
<h2>The Requirement</h2>
<blockquote><p><strong>16</strong> Cores<br />
<strong>112</strong> GB of RAM<br />
<strong>800</strong> GB of local SSD for temp disk<br />
<strong>32</strong> TB for the data disk<br />
<strong>50,000</strong> IOPS&nbsp;for the data disk<br />
<strong>512</strong> MB per second for the data disk
</p></blockquote>
<p>Let&#8217;s think about that spec for a second. That&#8217;s monstrous! And we&#8217;re going to build it!<span id="more-6311"></span></p>
<h2>The BUILD</h2>
<p>The first thing we need to do is set up our environment.</p>
<pre class="brush: powershell; title: ; notranslate">
# Login to Azure
Add-AzureAccount

# Find a subscription to work with
Get-AzureSubscription

# set Azure Subscription
Select-AzureSubscription -SubscriptionName 'MSDN' `
                         -Default

Select-AzureSubscription -SubscriptionName 'MSDN' `
                         -Current

# Create a new Storage Premium Account
New-AzureStorageAccount -StorageAccountName 'monstervmstorage' `
                        -Location 'East US 2' `
                        -Type 'Premium_LRS'

# set Azure Subscription Storage Account
Set-AzureSubscription -SubscriptionName 'MSDN' `
                      -CurrentStorageAccountName 'monstervmstorage'
</pre>
<p>Ok, now it&#8217;s time to create our Virtual Machine. It&#8217;s composed of 32 1TB P3 Premium Storage Data Disks.</p>
<pre class="brush: powershell; title: ; notranslate">
# Find a windows server VM Image Name
$imageName = (Get-AzureVMImage `
    | Where-Object -Property Label `
    -Match 'Windows Server 2012 R2 Datacenter')[0].ImageName

# Create a Standard DS14 Instance using as OS Disk
# stored in Azure Premium Storage
$storageAccount = 'monstervmstorage'
$adminName = 'MrAzure'
$adminPassword = 'SecurePassword!'
$vmName ='monstervmms'
$location = 'East US 2'
$vmSize ='Standard_DS14'

$vmConfig = New-AzureVMConfig -Name $vmName `
                              -ImageName $imageName `
                              -InstanceSize $vmSize

$vmConfig | Add-AzureProvisioningConfig -Windows `
                                        -AdminUsername $adminName `
                                        -Password $adminPassword

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 0' `
                              -LUN 0 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 1' `
                              -LUN 1 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 2' `
                              -LUN 2 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 3' `
                              -LUN 3 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 4' `
                              -LUN 4 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 5' `
                              -LUN 5 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 6' `
                              -LUN 6 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 7' `
                              -LUN 7 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 8' `
                              -LUN 8 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 9' `
                              -LUN 9 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 10' `
                              -LUN 10 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 11' `
                              -LUN 11 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 12' `
                              -LUN 12 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 13' `
                              -LUN 13 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 14' `
                              -LUN 14 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 15' `
                              -LUN 15 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 16' `
                              -LUN 16 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 17' `
                              -LUN 17 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 18' `
                              -LUN 18 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 19' `
                              -LUN 19 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 20' `
                              -LUN 20 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 21' `
                              -LUN 21 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 22' `
                              -LUN 22 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 23' `
                              -LUN 23 `
                              -HostCaching ReadOnly
$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 24' `
                              -LUN 24 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 25' `
                              -LUN 25 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 26' `
                              -LUN 26 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 27' `
                              -LUN 27 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 28' `
                              -LUN 28 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 29' `
                              -LUN 29 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 30' `
                              -LUN 30 `
                              -HostCaching ReadOnly

$vmConfig | Add-AzureDataDisk -CreateNew `
                              -DiskSizeInGB 1023 `
                              -DiskLabel 'Disk 31' `
                              -LUN 31 `
                              -HostCaching ReadOnly

New-AzureVM -ServiceName $vmName `
            -Location $location `
            -VMs $vmConfig -Verbose
</pre>
<p>Wait for it!</p>
<pre class="brush: powershell; title: ; notranslate">
# Wait for the VM to reach the ReadyRole State
$vm = Get-AzureVM -Name $vmName -ServiceName $vmName
Write-Output $('VM state is '+ $vm.InstanceStatus)

while( $vm.InstanceStatus -ne 'ReadyRole')
{
    Start-Sleep -s 10
    $vm = Get-AzureVM -Name $vmName -ServiceName $vmName
    Write-Output $('VM state is '+ $vm.InstanceStatus)
}
</pre>
<p>The next steps need to occur on the Virtual Machine itself. Remote Desktop into the Virtual Machine.</p>
<pre class="brush: powershell; title: ; notranslate">
Get-AzureRemoteDesktopFile -Name $vmName -ServiceName $vmName -Launch
</pre>
<p>Start Windows PowerShell ISE as an Administrator</p>
<p>Create a Storage Space to regroup the 32 1 TB data disks that we created along with the Virtual Machine.</p>
<pre class="brush: powershell; title: ; notranslate">
New-StoragePool -FriendlyName 'LUN-32TB' `
-StorageSubSystemUniqueId (Get-StorageSubSystem -FriendlyName '*Space*').uniqueID `
-PhysicalDisks (Get-PhysicalDisk -CanPool $true)
</pre>
<p>Create a Virtual Disk using the Storage Space. Be sure to set the number of columns equal to the number of disks. This will make sure that the Virtual Machine is able to benefit from the combined stripe IO.</p>
<pre class="brush: powershell; title: ; notranslate">
New-VirtualDisk -FriendlyName 'Datastore01' `
-StoragePoolFriendlyName 'LUN-32TB' -Size 32TB -NumberOfColumns 32 `
-ProvisioningType Thin -ResiliencySettingName Simple
</pre>
<p>Now it&#8217;s time to initialize the disk, to create a partition and to mount the disk.</p>
<pre class="brush: powershell; title: ; notranslate">
Initialize-Disk -VirtualDisk (Get-VirtualDisk -FriendlyName 'Datastore01')

$diskNumber = ((Get-VirtualDisk -FriendlyName 'Datastore01' | Get-Disk).Number)

New-Partition -DiskNumber $diskNumber `
              -UseMaximumSize `
              -AssignDriveLetter
</pre>
<p>Finally, we need to format the disk</p>
<pre class="brush: powershell; title: ; notranslate">
Format-Volume -DriveLetter F `
              -FileSystem NTFS `
              -NewFileSystemLabel 'Data' `
              -Confirm:$false `
              -Force
</pre>
<p>That&#8217;s it! Now we can go crazy and push this <strong>Monstrous Virtual Machine</strong> to its limits.</p>
<h2>Resources</h2>
<ul>
<li><a href="http://azure.microsoft.com/en-us/documentation/articles/storage-premium-storage-preview-portal/" target="_blank">Premium Storage: High-Performance Storage for Azure Virtual Machine Workloads</a></li>
<li><a href="http://azure.microsoft.com/en-us/pricing/details/storage/" target="_blank">Azure Storage Pricing</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blobs-storage/'>Blobs Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/data-disk/'>Data Disk</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/format/'>Format</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iaas/'>IaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/premium-storage/'>Premium Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/storage-space/'>Storage Space</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/stripe/'>Stripe</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/volume/'>Volume</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6311/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6311/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6311/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6311/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6311/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6311/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6311/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6311/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6311&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/04/29/building-a-monster-virtual-machine-on-azure/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/04/2322_201208225522551qjrv.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/04/2322_201208225522551qjrv.jpg?w=150" medium="image">
			<media:title type="html">2322_201208225522551qJrV</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>A Dev and Test Adventure on #Azure</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/03/27/a-dev-and-test-adventure-on-azure/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/03/27/a-dev-and-test-adventure-on-azure/#comments</comments>
		<pubDate>Fri, 27 Mar 2015 13:03:30 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Developer]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Remote Desktop]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Windows Server]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6259</guid>
		<description><![CDATA[Recently, I decided to give myself a break. Using my MSDN Benefits, I provisioned a Virtual Machine with Visual Studio 2015 preview. Then I started to build out my brand-new developer machine. As a developer who's been around azure for quite a while, I'm surprised that it took me this long to make this transition. I can now work from any physical computer. I can install all my tools, and I am no longer limited to 8GB of RAM.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6259&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/03/27/a-dev-and-test-adventure-on-azure/" target="_blank" title="A Dev and Test Adventure on&nbsp;#Azure"><img width="580" height="382" src="https://alexandrebrisebois.files.wordpress.com/2015/03/dev-machine.png?w=580" class="attachment-large wp-post-image" alt="dev-machine" /></a></p><p>Back in 2013 I wrote about <a title="Create a Dev &amp; Test Environment in Minutes!" href="https://alexandrebrisebois.wordpress.com/2013/08/13/create-a-dev-test-environment-in-minutes/" target="_blank">creating a Dev &amp; Test environments in minutes</a>. This post was all about the benefits and the flexibility of creating environments that support our development efforts.</p>
<p>Since then, I noticed that Microsoft regularly creates Virtual Machine templates for MSDN Subscribers that allow them to test software through their MSDN Benefits. Luckily, they have provided us with templates that are pre-configured with various flavors of Visual Studio.<br />
<span id="more-6259"></span><br />
<a href="https://alexandrebrisebois.files.wordpress.com/2015/03/visual-studio-vms.png"><img class="aligncenter wp-image-6267 size-full" src="https://alexandrebrisebois.files.wordpress.com/2015/03/visual-studio-vms.png?w=580" alt="Visual-Studio-VMs"   /></a></p>
<p>As a developer, I am called to work on various projects, and I have many versions of Visual Studio installed. Over the past few months, I started working with multiple physical machines that I must maintain. By now, you can imagine that every tool that I decide to use, adds more maintenance. Updates, patches and betas take up a lot of my time away&nbsp;from actual work. To help me focus on producing value for the business, I use a good number of third party tools, with a limited number of licenses. This creates a challenge for me, because I have to pick and chose where I install these tools.</p>
<p>Recently, I decided to give myself a break. Using my MSDN Benefits, I provisioned a Virtual Machine with Visual Studio 2015 preview. Then I started to build out my brand-new developer machine. As a developer who&#8217;s been around azure for quite a while, I&#8217;m surprised that it took me this long to make this transition. I can now work from any physical computer. I can install all my tools, and I am no longer limited to 8GB of RAM.</p>
<p>I feel like a kid in a candy shop! I can scale my Virtual Machine to meet my needs and pay only for what I use. A few minutes before my work session, I use the following PowerShell script to start my Virtual Machine. Once, it&#8217;s ready, the Remote Desktop file is downloaded and launched.</p>
<pre class="brush: powershell; title: ; notranslate">
$vm = Get-AzureVm -ServiceName 'my-dev-vm-name'

if($vm.InstanceStatus -ne 'ReadyRole')
{
    Start-AzureVM -ServiceName $vm.ServiceName -Name $vm.Name -Verbose
    
    # Wait for the VM to reach the ReadyRole State
    $vm = Get-AzureVM -Name $vm.Name -ServiceName $vm.ServiceName
    Write-Output $('VM state is '+ $vm.InstanceStatus)
 
    while( $vm.InstanceStatus -ne 'ReadyRole')
    {
        Start-Sleep -s 10
        $vm = Get-AzureVM -Name $vm.Name -ServiceName $vm.ServiceName

        Write-Output $('VM state is '+ $vm.InstanceStatus)
    }

    # Boot grace period of 60 seconds
    Start-Sleep -s 60
        
    Get-AzureRemoteDesktopFile -ServiceName $vm.ServiceName -Name $vm.Name -Launch

}else
{
    Write-Output 'Already ReadyRole'
    Get-AzureRemoteDesktopFile -ServiceName $vm.ServiceName -Name $vm.Name -Launch
}
</pre>
<p>Taking this a few steps further, you could create an app that would allow you to start the Virtual Machine from the bus using your Smart Watch.</p>
<p>Then when the time comes to call it quits, I use the following PowerShell script to shut down and deallocate my Virtual Machine. This is when I stop paying for compute.</p>
<pre class="brush: powershell; title: ; notranslate">
$vm = Get-AzureVm -ServiceName 'my-dev-vm-name'

if($vm.InstanceStatus -eq 'StoppedDeallocated')
{
   Write-Output 'Already StoppedDeallocated'

}else
{
    Stop-AzureVM -ServiceName $vm.ServiceName -Name $vm.Name -Force -Verbose
}
</pre>
<p>This feature could also be added to the mobile app that I alluded to above, so that you could shutdown the Virtual Machine from your commute home.</p>
<p>Being in a hurry, I sometimes forget to shutdown the Virtual Machine, so I use <a href="http://azure.microsoft.com/en-us/documentation/services/automation/" target="_blank">Azure Automation</a> to <a href="https://gallery.technet.microsoft.com/scriptcenter/Stop-Windows-Azure-Virtual-821896a8" target="_blank">Stop Azure Virtual Machines on a Schedule</a>. Usually, I scheduled the runbook to run at 19h00. This gives me a short grace period after 17h30 and helps me go offline for the night.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/developer/'>Developer</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/development/'>Development</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/remote-desktop/'>Remote Desktop</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/tools/'>Tools</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/visual-studio/'>Visual Studio</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/windows-server/'>Windows Server</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6259/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6259/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6259/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6259&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/03/27/a-dev-and-test-adventure-on-azure/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/03/dev-machine.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/03/dev-machine.png?w=150" medium="image">
			<media:title type="html">dev-machine</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/03/visual-studio-vms.png" medium="image">
			<media:title type="html">Visual-Studio-VMs</media:title>
		</media:content>
	</item>
		<item>
		<title>Scaling #Azure Cloud Services to Zero</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/03/16/scaling-azure-cloud-services-to-zero/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/03/16/scaling-azure-cloud-services-to-zero/#comments</comments>
		<pubDate>Mon, 16 Mar 2015 21:20:16 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Azure Storage]]></category>
		<category><![CDATA[Blob]]></category>
		<category><![CDATA[Blobs Storage]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Queue Storage]]></category>
		<category><![CDATA[Runbook]]></category>
		<category><![CDATA[Schedule]]></category>
		<category><![CDATA[Worker Role]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6211</guid>
		<description><![CDATA[The Challenge As developers, we deal with lots of complexity, and this is a good thing. It forces us to be creative, and sometimes to go beyond our known universe to overcome challenges. Microsoft Azure is designed to help us make the right choices. It imposes performance targets through a multitude of mechanisms like throttling [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6211&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/03/16/scaling-azure-cloud-services-to-zero/" target="_blank" title="Scaling #Azure Cloud Services to&nbsp;Zero"><img width="580" height="339" src="https://alexandrebrisebois.files.wordpress.com/2015/03/scaling-down-to-zero.png?w=580" class="attachment-large wp-post-image" alt="Scaling-down-to-zero" /></a></p><h2>The Challenge</h2>
<p>As developers, we deal with lots of complexity, and this is a good thing. It forces us to be creative, and sometimes to go beyond our known universe to overcome challenges.</p>
<p>Microsoft Azure is designed to help us make the right choices. It imposes performance targets through a multitude of mechanisms like throttling and quotas. One of which, I’m sure you have come to know, is that we cannot scale a Cloud Service to zero instances. Let&#8217;s stop for a moment and think about this limitation for a second. How would you creatively overcome this challenge?<span id="more-6211"></span></p>
<h2>Being Creative</h2>
<p>Unlike Virtual Machines, Cloud Services incur costs when they are stopped. In order to stop paying, we must delete the deployment. These are the constraints that we must compose with.</p>
<p>Deleting a deployment comes with added complexity. It introduces significant latency, because it takes a few minutes for a Cloud Service to reach a ready state. Therefore, scenarios that are time sensitive are not satisfied by these workflows.</p>
<p>In a post about <a title="Scaling #Azure Cloud Services Up and Down Like Clockwork" href="https://alexandrebrisebois.wordpress.com/2014/12/29/scaling-azure-cloud-services-up-and-down-like-clockwork/" target="_blank">scaling Cloud Services</a>, I shared a PowerShell runbook that can deploy packages from Azure Storage based on a schedule. It was originally built to deploy a scaled-up Cloud Service package to satisfy peak loads and to deploy a scaled-down Cloud Service package for the quite hours. This same script can be used as a starting point for the following scenarios.</p>
<blockquote><p>Plan for a grace period between job executions, so that deployments have time to complete. As Cloud Services transition, they rarely provide any value, so try to come up with a good scheduling strategy. This will help you maximize your investment.</p></blockquote>
<p><span style="color:#404040;font-size:18px;font-weight:bold;line-height:25.200000762939px;">Scenario: Deploying a Package based on Queue Length</span></p>
<p>This scenario is depicted in the diagram above. Using Azure Automation, and a scheduled job, we can monitor the depth of a queue. When the queue reaches the targeted depth, the runbook deploys the Cloud Service.</p>
<p>The deployed Cloud Service is responsible for processing messages from the monitored queue.</p>
<p>Every time the job executes, it monitors the depth of a queue. If the queue is below the targeted depth, the runbook deletes the deployment.</p>
<h4>Step By Step</h4>
<ol>
<li>Trigger Azure Automation deployment job.</li>
<li>Check whether queue depth is greater than target.</li>
<li>Check whether there is an active deployment.</li>
<li>Download Cloud Service Configurations and deploy the Cloud Service package from Azure Storage.</li>
<li>The deployed Cloud Service is functional and operating as expected.</li>
<li>Trigger Azure Automation deployment job.</li>
<li>Check whether queue depth is below the target.</li>
<li>Check whether there is an active deployment.</li>
<li>Delete the active deployment.</li>
</ol>
<h3>Scenario: Deploying a Package based on a Schedule</h3>
<p><img class="aligncenter size-full wp-image-6221" src="https://alexandrebrisebois.files.wordpress.com/2015/03/scaling-down-to-zero-second-scenario.png?w=580&#038;h=355" alt="Scaling-down-to-zero-second-scenario" width="580" height="355" /><br />
In this scenario, we use Azure Scheduler to deploy a Cloud Service to a Production slot. This can be quite useful for end of day processing. Scaling down to zero occurs based on a predefined schedule. This triggers an Azure Automation job that checks whether a Cloud Service is currently deployed. If it discovers an active deployment, it deletes it.</p>
<h4>Step By Step</h4>
<ol>
<li>Trigger Azure Automation deployment job.</li>
<li>Check whether there is an active deployment.</li>
<li>Download Cloud Service Configurations and deploy the Cloud Service package from Azure Storage.</li>
<li>The deployed Cloud Service is functional and operating as expected.</li>
<li>Trigger Azure Automation delete deployment job.</li>
<li>Check whether there is an active deployment.</li>
<li>Delete the active deployment.</li>
</ol>
<h2>Deploying a Cloud Service</h2>
<p>Taken from my previous post about <a title="Scaling #Azure Cloud Services Up and Down Like Clockwork" href="https://alexandrebrisebois.wordpress.com/2014/12/29/scaling-azure-cloud-services-up-and-down-like-clockwork/" target="_blank">scaling Cloud Services</a>, this script can be taken as a starting point for your deployment efforts. In practice, this runbook deploys a Cloud Service package and its configuration from Azure Storage to a production slot.</p>
<p>Please refer to my previous <a title="Scaling #Azure Cloud Services Up and Down Like Clockwork" href="https://alexandrebrisebois.wordpress.com/2014/12/29/scaling-azure-cloud-services-up-and-down-like-clockwork/" target="_blank">post</a> for detailed instructions and for a complete example.</p>
<pre class="brush: powershell; title: ; notranslate">
workflow Invoke-DeployPackage
{
   param
   (
      [parameter(Mandatory=$true, `
                 HelpMessage = 'The name given to the Windows PowerShell Credentials located in the Assets of this Azure Automation instance')]
      [String]
      $AzureCredentialsName,

      [parameter(Mandatory=$true, `
                 HelpMessage = 'The name of the Microsoft Azure Subscription that contains the resources your wish to deploy')]
      [String]
      $AzureSubscriptionName,

      [parameter(Mandatory=$true, `
                 HelpMessage = 'The name of the service you wish to deploy')]
      [String]
      $ServiceName,

      [parameter(Mandatory=$true, `
                 HelpMessage = 'The location of the service your with to deploy I.E. &quot;East US&quot;')]
      [String]
      $ServiceLocation,

      [parameter(Mandatory=$true, `
                 HelpMessage = 'The name of the Microsoft Azure storage account that contains the Cloud Service Packages')]
      [String]
      $StorageAccountName,

      [parameter(Mandatory=$true, `
                 HelpMessage = 'The name of the Blob container that contains the Cloud Service Packages')]
      [String]
      $StorageContainerName,

      [parameter(Mandatory=$true, HelpMessage = 'The name of the Cloud Service Package file')]
      [String]
      $PackageBlobName,

      [parameter(Mandatory=$true, HelpMessage = 'The name of the Cloud Service Configurations file')]
      [String]
      $ConfigurationBlobName
    )

    $VerbosePreference = 'Continue'

    # Mark the start time of the script execution
    $StartTime = Get-Date

    $DeploymentLable = $ServiceName + ' (' + $StartTime +')'

    Write-Verbose ('Connecting to Microsoft Azure')

    $Credentials = Get-AutomationPSCredential `
                       -Name $AzureCredentialsName

    Add-AzureAccount `
       -Credential $Credentials

    InlineScript{

        Write-Verbose ('Selecting Azure Subscription')

        Select-AzureSubscription -SubscriptionName $Using:AzureSubscriptionName

        $StorageAccount = (Get-AzureStorageAccount -StorageAccountName $Using:StorageAccountName).Label

        Write-Verbose ('Setting the Azure Subscription and Storage Accounts')

        Set-AzureSubscription `
            -SubscriptionName $Using:AzureSubscriptionName `
            -CurrentStorageAccount $StorageAccount

        Write-Verbose ('[Start] Validating Azure cloud service environment {0}' -f $Using:ServiceName)

        try
        {
            $CloudService = Get-AzureService `
                                -ServiceName $Using:ServiceName

            Write-Verbose ('cloud service {0} in location {1} exist!' -f $Using:ServiceName, $Using:ServiceLocation)
        }
        catch
        {
            #Create
            Write-Verbose ('[Start] creating cloud service {0} in location {1}' -f $Using:ServiceName, $Using:ServiceLocation)

            New-AzureService `
                -ServiceName $Using:ServiceName `
                -Location $Using:ServiceLocation

            Write-Verbose ('[Finish] creating cloud service {0} in location {1}' -f $Using:ServiceName, $Using:ServiceLocation)
        }

        Write-Verbose ('[Finish] Validating Azure cloud service environment {0}' -f $Using:ServiceName)

        $TempFileLocation = &quot;C:\$Using:ConfigurationBlobName&quot;

        Write-Verbose ('Downloading Service Configurations from Azure Storage')

        Get-AzureStorageBlobContent `
            -Container $Using:StorageContainerName `
            -Blob  $Using:ConfigurationBlobName `
            -Destination $TempFileLocation `
            -Force

        Write-Verbose('Downloaded Configuration File: '+ $TempFileLocation)

        Write-Verbose('Getting Package Url from Azure Storage: '+ $Using:PackageBlobName)

        $blob = $(Get-AzureStorageBlob -Blob $Using:PackageBlobName -Container $Using:StorageContainerName)

        $PackageUri = $blob.ICloudBlob.Uri.AbsoluteUri

        Write-Verbose('Package Url: '+ $PackageUri)

        try
        {
            Write-Verbose('Attempting to Update an Existing Deployment')
            Set-AzureDeployment `
                -Package $PackageUri `
                -Configuration $TempFileLocation `
                -Slot Production `
                -Mode Simultaneous `
                -Label $Using:DeploymentLable `
                -ServiceName  $Using:ServiceName `
                -Upgrade `
                -Force `
                -Verbose

        }catch
        {
            Write-Output $error

            Write-Verbose('Attempting to Deploy the service')

            New-AzureDeployment `
                -Package $PackageUri `
                -Configuration $TempFileLocation `
                -Slot Production `
                -Label $Using:DeploymentLable `
                -ServiceName  $Using:ServiceName `
                -Verbose
        }
    }
}
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-storage/'>Azure Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blob/'>Blob</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blobs-storage/'>Blobs Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/package/'>Package</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/queue-storage/'>Queue Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/runbook/'>Runbook</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/schedule/'>Schedule</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/worker-role/'>Worker Role</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6211/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6211&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/03/16/scaling-azure-cloud-services-to-zero/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/03/scaling-down-to-zero.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/03/scaling-down-to-zero.png?w=150" medium="image">
			<media:title type="html">Scaling-down-to-zero</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/03/scaling-down-to-zero-second-scenario.png" medium="image">
			<media:title type="html">Scaling-down-to-zero-second-scenario</media:title>
		</media:content>
	</item>
		<item>
		<title>Scaling an FTP Ingestion Service Using #Azure Traffic Manager</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/03/10/scaling-an-ftp-ingestion-service-using-azure-traffic-manager/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/03/10/scaling-an-ftp-ingestion-service-using-azure-traffic-manager/#comments</comments>
		<pubDate>Tue, 10 Mar 2015 16:30:15 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[ActionBlock]]></category>
		<category><![CDATA[Blob]]></category>
		<category><![CDATA[Blobs Storage]]></category>
		<category><![CDATA[BlockBlob]]></category>
		<category><![CDATA[CName]]></category>
		<category><![CDATA[Dataflow]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[Endpoint]]></category>
		<category><![CDATA[Firewall]]></category>
		<category><![CDATA[FTP]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[Passive Mode]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Stateful FTP Filtering]]></category>
		<category><![CDATA[Storage Account]]></category>
		<category><![CDATA[TCP]]></category>
		<category><![CDATA[Traffic Manager]]></category>
		<category><![CDATA[Virtual Machine]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6139</guid>
		<description><![CDATA[Scaling an FTP Ingestion Service Making an FTP Ingestion Service Highly Available (HA) can be a challenge. On Azure, we can take advantage of the Microsoft Azure Traffic Manager to direct users to the closest FTP Server. In this specific scenario, we assume that all FTP Servers are configured the same way and that users only [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6139&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/03/10/scaling-an-ftp-ingestion-service-using-azure-traffic-manager/" target="_blank" title="Scaling an FTP Ingestion Service Using #Azure Traffic&nbsp;Manager"><img width="580" height="431" src="https://alexandrebrisebois.files.wordpress.com/2015/03/using-azure-traffic-manager-to-scale-out-an-ftp-ingestion-endpoint.png?w=580" class="attachment-large wp-post-image" alt="using-azure-traffic-manager-to-scale-out-an-ftp-ingestion-endpoint" /></a></p><h1>Scaling an FTP Ingestion Service</h1>
<p>Making an FTP Ingestion Service Highly Available (HA) can be a challenge. On Azure, we can take advantage of the <a href="https://alexandrebrisebois.wordpress.com/2013/07/23/windows-azure-traffic-manager-high-performance-availability-resiliency/" target="_blank">Microsoft Azure Traffic Manager</a> to direct users to the <a href="https://alexandrebrisebois.wordpress.com/2015/02/11/moving-to-azure-find-the-closest-azure-data-center/" target="_blank">closest FTP Server</a>. In this specific scenario, we assume that all FTP Servers are configured the same way and that users only have write access. When a document is uploaded over FTP, it is moved to a <a href="http://azure.microsoft.com/en-us/documentation/articles/storage-create-storage-account/" target="_blank">Microsoft Azure Storage Account</a> that is used as persistent storage.<span id="more-6139"></span></p>
<blockquote><p>Note: Ingress Bandwidth is free on Azure. Sending a document from one Data Center to an other is considered Egress Bandwidth from the origin. So be sure that you take this into consideration when you estimate operational costs for this kind of scenario.</p></blockquote>
<h2>The Communication Flow</h2>
<ol>
<li>Using the <strong>CName</strong> FTP Client contacts <strong>Microsoft Azure Traffic Manager</strong> and is provided with the IP of a healthy Endpoint</li>
<li>The FTP Client connects directly with the healthy Endpoint
<ol>
<li>The FTP Client uploads a document</li>
</ol>
</li>
<li>The application moves the document to <strong>Microsoft Azure Storage</strong></li>
</ol>
<h2>The Setup</h2>
<p>To implement this scenario, we must start by creating 4 Virtual Machines. Then we configure each FTP Server to use <a href="http://slacksite.com/other/ftp.html" target="_blank">Passive Mode</a>. On Azure, we need to activate the <a href="http://www.checkpoint.com/smb/help/z100g/7.5/7082.htm" target="_blank">Stateful FTP Filtering</a> on the firewall of each Virtual Machine so that traffic is allowed to reach the FTP Server.</p>
<p>The following is a command line that can be used to enable Stateful FTP Filtering.</p>
<pre class="brush: plain; title: ; notranslate">
netsh advfirewall set global StatefulFtp enable
</pre>
<p>Configure FTP Server users on each Virtual Machine with write-only permissions. This ensures that communication is one-way and that transferred documents remain inaccessible from the outside. Furthermore, because the users are the same on all FTP Servers, clients can be load-balanced without any side effects.</p>
<p>Create the <a href="http://azure.microsoft.com/en-us/documentation/articles/storage-create-storage-account/" target="_blank">Microsoft Azure Storage Account</a> that is used to collect the documents. Be sure to create the Storage Account in the Data Center that hosts the application that processes the transferred documents. Before we exit our Azure Management Environment (web portal or PowerShell), let&#8217;s make sure that we have created <strong>Input Endpoints</strong> for<strong> ports 80 </strong>and<strong> 21</strong>. These ports will be used by IIS and by the FTP Server.</p>
<p>Now that we have a <a href="http://azure.microsoft.com/en-us/documentation/articles/storage-create-storage-account/" target="_blank">Storage Account</a> we can deploy, and configure auto-start for the application that moves documents to a <a href="http://azure.microsoft.com/en-us/documentation/articles/storage-create-storage-account/" target="_blank">Microsoft Azure Storage</a>.</p>
<p>Configure Internet Information Services (IIS) on each Virtual Machine. This service hosts a static HTML page that is used by the Microsoft Azure Traffic Manager health probes. This enables the Traffic Manager to identify degraded nodes and to redirect traffic to healthy nodes.</p>
<p>Create a Microsoft Azure Traffic Manager and Endpoints from each machine. Provide FTP Clients with the Traffic Manager URL.</p>
<h2>More on Azure Traffic Manager</h2>
<p>Azure Traffic Manager gives us with a lot of flexibility. By providing us with 10 levels of Traffic Manager Profiles, we can compose complex routing strategies. We can add and remove Endpoints from Traffic Manager and we can use weighted distribution of network traffic for scenarios like Testing in Production (A/B Testing).</p>
<p>The in the following scenario, we the first Profile is used to find the closest deployment to the connected client. Then using a Round Robin Profile we distribute FTP Clients evenly over the Virtual Machines available to the selected region. Earlier I spoke of flexibility, well in this scenario, I have the possibility of adding more FTP Server instances in some regions in order to scale to demand. Adding and removing FTP Server instances can be achieved without downtime. Find out more by visiting the <a href="https://msdn.microsoft.com/en-us/library/azure/hh744833.aspx" target="_blank">Traffic Manager Overview</a>.</p>
<img class="aligncenter size-full wp-image-6180" src="https://alexandrebrisebois.files.wordpress.com/2015/03/trafic-manager-with-profies.png?w=580&#038;h=544" alt="trafic manager with profies" width="580" height="544" />
<h2>Moving Files to Azure Storage</h2>
<p>The missing piece in this scenario is a program that moves documents from each Virtual Machine to <a href="http://azure.microsoft.com/en-us/documentation/articles/storage-create-storage-account/" target="_blank">Microsoft Azure Storage</a>. The following <strong>sample</strong> uses the <a href="https://msdn.microsoft.com/en-us/library/hh228603(v=vs.110).aspx" target="_blank">Dataflow (Task Parallel Library)</a> to control the maximum degree of parallelism (the number of documents that can be uploaded in parallel).</p>
<p>The console application starts by creating a Blob Container. Then it queues move tasks for each document present in the monitored directory. The <strong>ActionBlock</strong> takes care of processing each task to completion. Once all documents are moved, the application waits for a few seconds and starts over.</p>
<pre class="brush: csharp; title: ; notranslate">
internal class Program
{
  private static void Main(string[] args)
  {
    var mdop = ConfigurationManager.AppSettings[&quot;maxDegreeOfParallelism&quot;];
    var maxDegreeOfParallelism = Convert.ToInt32(mdop);

    var cs = ConfigurationManager.AppSettings[&quot;connectionString&quot;];
    var account = CloudStorageAccount.Parse(cs);
    var containerName = ConfigurationManager.AppSettings[&quot;container&quot;];

    var c = account.CreateCloudBlobClient()
                    .GetContainerReference(containerName);
    c.CreateIfNotExists();

    while (true)
    {
      var block = new ActionBlock&lt;FileInfo&gt;(info =&gt;
          TryMoveFile(account, containerName, info),
          new ExecutionDataflowBlockOptions
          {
              MaxDegreeOfParallelism = maxDegreeOfParallelism
          });

      var path = ConfigurationManager.AppSettings[&quot;directoryPath&quot;];
      var directory = new DirectoryInfo(path);

      var fileInfos = directory.GetFiles();

      foreach (var info in fileInfos)
          block.Post(info);

      block.Complete();

      block.Completion.Wait();

      Task.Delay(TimeSpan.FromSeconds(5)).Wait();
    }
  }

  private static void TryMoveFile(CloudStorageAccount account,
                                  string containerName,
                                  FileInfo info)
  {
    try
    {
        MoveFile(account, containerName, info);
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
  }

  private static void MoveFile(CloudStorageAccount account,
                                  string containerName,
                                  FileInfo info)
  {
    var client = account.CreateCloudBlobClient();
    var container = client.GetContainerReference(containerName);

    var fileName = Path.GetFileName(info.FullName);
    var blobRerefence = container.GetBlockBlobReference(fileName);

    using (var fileStream = info.Open(FileMode.Open))
    {
        Console.WriteLine(&quot;Moving &quot; + info.FullName);
        blobRerefence.UploadFromStream(fileStream);
    }
    info.Delete();
    Console.WriteLine(&quot;Moved &quot; + info.FullName);
  }
}
</pre>
<p>The application&#8217;s configurations are listed below. Let&#8217;s take a moment to review them.</p>
<ul>
<li>The <strong>directory path</strong> is the folder where documents are placed once they are received by the FTP Server.</li>
<li>The <strong>maximum degree of parallelism</strong> is the number of concurrent uploads. Be sure to keep this number reasonable. If the number is too high, it will have a negative impact on the overall solution.</li>
<li>The <strong>connection string</strong> is the <a href="http://azure.microsoft.com/en-us/documentation/articles/storage-create-storage-account/" target="_blank">Microsoft Azure Storage</a> connection string.</li>
<li>The <strong>container</strong> is the place where document blobs are stored.</li>
</ul>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;configuration&gt;
   &lt;startup&gt;
      &lt;supportedRuntime version=&quot;v4.0&quot; sku=&quot;.NETFramework,Version=v4.5&quot; /&gt;
   &lt;/startup&gt;
   &lt;appSettings&gt;
      &lt;add key=&quot;directoryPath&quot; value=&quot;C:\ftp-files&quot;/&gt;
      &lt;add key=&quot;maxDegreeOfParallelism&quot; value=&quot;4&quot;/&gt;
      &lt;add key=&quot;connectionString&quot; value=&quot;[connection string]&quot;/&gt;
      &lt;add key=&quot;container&quot; value=&quot;ftp&quot;/&gt;
   &lt;/appSettings&gt;
&lt;/configuration&gt;
</pre>
<p>In order to start this application, we are presented with a few options. First we can configure it to execute when the Virtual Machine starts up. Secondly we can convert this to a Windows Service and install it on the Virtual Machine. And finally, we can start the application through Azure Automation and PowerShell. Which of these options should be implemented? I leave this choice to you.</p>
<h2>Summary</h2>
<p>The solution described in this post corresponds to the ingestion of documents. It does not cover what you do with the documents once they are persisted in <a href="http://azure.microsoft.com/en-us/documentation/articles/storage-create-storage-account/" target="_blank">Microsoft Azure Storage Account</a>. I leave that to your creativity and for future adventures. The scenario described above, uses <a href="https://alexandrebrisebois.wordpress.com/2013/07/23/windows-azure-traffic-manager-high-performance-availability-resiliency/" target="_blank">Microsoft Azure Traffic Manager</a> to scale out and FTP Ingestion Service. The FTP Servers are configured the same way across all instances, and users only have write access. When a document is uploaded over FTP, it is moved to a <a href="http://azure.microsoft.com/en-us/documentation/articles/storage-create-storage-account/" target="_blank">Microsoft Azure Storage Account</a> that is used as persistent storage.</p>
<p>This is a common scenario when we exchange information between companies. <strong>The FTP protocol is still quite relevant in 2015</strong>. It&#8217;s a trusted technology, that many understand fairly well. Most legacy systems integrate with it and it can be deployed rather quickly.</p>
<p>Scaling out FTP Severs works well when clients are not reading from the FTP Server. It&#8217;s <span id="ws-word-wrapper-117" class=""><span id="ws-token-117" class="word-border ws-token" title="">especially</span></span> useful when you need to receive a large quantity of files from your partners.</p>
<p>Remember, the <a href="https://alexandrebrisebois.wordpress.com/2013/07/23/windows-azure-traffic-manager-high-performance-availability-resiliency/" target="_blank">Microsoft Azure Traffic Manager</a> is a DNS based solution. That means that it works with TCP traffic and with HTTP traffic. Feel free to test out your scenarios and to share your experiences using the comments section below.</p>
<h2>Resources</h2>
<ul>
<ul>
<li><a href="http://stackoverflow.com/a/18713618" target="_blank">How to Setup FTP on Azure VM</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/hh744833.aspx" target="_blank">Traffic Manager Overview</a></li>
<li><a title="About Traffic Manager Load Balancing Methods" href="https://msdn.microsoft.com/en-us/library/azure/dn339010.aspx" target="_blank">About Traffic Manager Load Balancing Methods</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/dn339013.aspx" target="_blank">About Traffic Manager Monitoring</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/hh745750.aspx" target="_blank">How Do I Configure Traffic Manager?</a></li>
<li><a href="https://msdn.microsoft.com/library/dn690250.aspx" target="_blank">Azure Traffic Manager Cmdlets</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/hh228603(v=vs.110).aspx" target="_blank">Dataflow (Task Parallel Library)</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/hh228609(v=vs.110).aspx" target="_blank">How to: Specify the Degree of Parallelism in a Dataflow Block</a></li>
</ul>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/actionblock/'>ActionBlock</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blob/'>Blob</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blobs-storage/'>Blobs Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blockblob/'>BlockBlob</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cname/'>CName</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dataflow/'>Dataflow</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dns/'>DNS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/endpoint/'>Endpoint</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/firewall/'>Firewall</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/ftp/'>FTP</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/http/'>HTTP</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iis/'>IIS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/passive-mode/'>Passive Mode</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/stateful-ftp-filtering/'>Stateful FTP Filtering</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/storage-account/'>Storage Account</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/tcp/'>TCP</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/traffic-manager/'>Traffic Manager</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6139/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6139&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/03/10/scaling-an-ftp-ingestion-service-using-azure-traffic-manager/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/03/using-azure-traffic-manager-to-scale-out-an-ftp-ingestion-endpoint.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/03/using-azure-traffic-manager-to-scale-out-an-ftp-ingestion-endpoint.png?w=150" medium="image">
			<media:title type="html">using-azure-traffic-manager-to-scale-out-an-ftp-ingestion-endpoint</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/03/trafic-manager-with-profies.png" medium="image">
			<media:title type="html">trafic manager with profies</media:title>
		</media:content>
	</item>
		<item>
		<title>Lift and Shift of a Windows Service to Microsoft #Azure</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/02/22/lift-and-shift-of-a-windows-service-to-microsoft-azure/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/02/22/lift-and-shift-of-a-windows-service-to-microsoft-azure/#comments</comments>
		<pubDate>Sun, 22 Feb 2015 22:25:40 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[ANSI]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Configurations]]></category>
		<category><![CDATA[Guest OS]]></category>
		<category><![CDATA[Lift & Shift]]></category>
		<category><![CDATA[PaaS]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Roles]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Windows Service]]></category>
		<category><![CDATA[Worker Role]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6112</guid>
		<description><![CDATA[Having written about lifting and shifting a Console Application, I decided to mirror the scenario and describe how a similar method can be used to lift and shift a Windows Service to Microsoft Azure. Moving a Service&#160;to Microsoft Azure Every time I dig a little deeper into Azure, I’m amazed at how much there is [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6112&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/02/22/lift-and-shift-of-a-windows-service-to-microsoft-azure/" target="_blank" title="Lift and Shift of a Windows Service to Microsoft&nbsp;#Azure"><img width="580" height="385" src="https://alexandrebrisebois.files.wordpress.com/2015/02/lift-and-shift-service.jpg?w=580" class="attachment-large wp-post-image" alt="lift-and-shift-service" /></a></p><blockquote><p>Having written about <a href="https://alexandrebrisebois.wordpress.com/2014/12/14/lift-and-shift-of-a-console-appication-to-microsoft-azure/" title="Lift and Shift of a Console Appication to Microsoft #Azure">lifting and shifting a Console Application</a>, I decided to mirror the scenario and describe how a similar method can be used to lift and shift a <strong>Windows Service</strong> to <strong>Microsoft Azure</strong>.</p></blockquote>
<h1>Moving a Service&nbsp;to Microsoft Azure</h1>
<p>Every time I dig a little deeper into Azure, I’m amazed at how much there is to know. Having done a few projects with Cloud Services in the past, I thought it would be interesting to see if it was possible to lift and shift a Windows Service&nbsp;into an Azure Worker Role.</p>
<blockquote><p><strong>Lift and Shift</strong>: The action of moving a workload to a new environment, without altering the application’s code.</p></blockquote>
<p><span id="more-6112"></span></p>
<h3>Prerequisites</h3>
<blockquote>
<h4>☁ Tools</h4>
<p>Using the <a href="http://www.microsoft.com/web/downloads/platform.aspx" target="_blank">Microsoft Web Platform Installer</a> install the latest <strong>Microsoft Azure PowerShell with Microsoft Azure SDK</strong>.</p>
<h4>☁ Microsoft Azure Account</h4>
<p>In order to deploy your workload to Microsoft Azure, be sure to have an account. You can create a <a href="http://azure.microsoft.com/en-us/pricing/free-trial/" target="_blank">Free Trial Account</a> on the <a href="http://www.azure.com" target="_blank">azure.com</a> website.</p></blockquote>
<h2>Creating a Worker Role without Visual Studio</h2>
<blockquote><p>A <a href="http://msdn.microsoft.com/en-us/library/azure/jj155995.aspx" target="_blank">Worker Role</a> is a role that is useful for generalized development, and may perform background processing for a <a href="http://msdn.microsoft.com/en-us/library/azure/jj155995.aspx" target="_blank">Web Role</a>. When you have a need for a background process that performs long running or intermittent tasks, you should use this role.</p></blockquote>
<p>Let&#8217;s fire-up <strong>Windows PowerShell ISE</strong> and navigate to the folder where you want to create your Cloud Service. For this blog post, I created a new folder, <strong>demo-lift-and-shift</strong>, in my Documents.</p>
<pre class="brush: plain; title: ; notranslate">
C:\users\&lt;user id&gt;\Documents\demo-lift-and-shift-service
</pre>
<p>In the PowerShell console, execute the following commands.</p>
<pre class="brush: powershell; title: ; notranslate">
# Create the Cloud Service
New-AzureServiceProject -ServiceName 'service-lift-and-shift' -Verbose

# Create the Worker Role
Add-AzureWorkerRole -Name 'ServiceWorkerRole' -Instances 1 -Verbose
</pre>
<p>These two commands will produce the following files and documents. This represents the Cloud Service project. It contains the configurations and the Cloud Service definition.</p>
<img class="aligncenter size-full wp-image-6118" src="https://alexandrebrisebois.files.wordpress.com/2015/02/cloud-service.png?w=580" alt="cloud-service"   />
<p>The <strong>ServiceDefinition.csdef</strong> was created by PowerShell when we executed the <strong>New-AzureServiceProject</strong> command. Then it was updated when we executed the <strong>Add-AzureWorkerRole</strong>. The following is the unchanged version of the service definition. Since it is missing a few pieces, I will show you what to change in order to be able to deploy your brand-new service to Microsoft Azure.</p>
<blockquote><p>The <strong>ServiceDefinition.csdef</strong> file contains the metadata that is required by the Azure environment for the requirements of your cloud service, including what roles it contains. This file also contains configuration settings that apply to all instances. These configuration settings can be read at runtime using the Azure Service Hosting Runtime API. This file cannot be updated while your service is running in Azure.</p></blockquote>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;ServiceDefinition xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; name=&quot;service-lift-and-shift&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition&quot;&gt;
  &lt;WorkerRole name=&quot;ServiceWorkerRole&quot;&gt;
    &lt;Startup&gt;
      &lt;Task commandLine=&quot;setup_worker.cmd &amp;gt; log.txt&quot; executionContext=&quot;elevated&quot;&gt;
        &lt;Environment&gt;
          &lt;Variable name=&quot;EMULATED&quot;&gt;
            &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
          &lt;/Variable&gt;
          &lt;Variable name=&quot;RUNTIMEID&quot; value=&quot;&quot; /&gt;
          &lt;Variable name=&quot;RUNTIMEURL&quot; value=&quot;&quot; /&gt;
        &lt;/Environment&gt;
      &lt;/Task&gt;
      &lt;Task commandLine=&quot;.\startup.cmd &amp;gt; startup_log.txt&quot; executionContext=&quot;elevated&quot; /&gt;
    &lt;/Startup&gt;
    &lt;Endpoints&gt;
      &lt;InputEndpoint name=&quot;HttpIn&quot; protocol=&quot;tcp&quot; port=&quot;80&quot; /&gt;
    &lt;/Endpoints&gt;
    &lt;Runtime&gt;
      &lt;Environment&gt;
        &lt;Variable name=&quot;PORT&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[@name='HttpIn']/@port&quot; /&gt;
        &lt;/Variable&gt;
        &lt;Variable name=&quot;EMULATED&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
        &lt;/Variable&gt;
      &lt;/Environment&gt;
      &lt;EntryPoint&gt;
        &lt;ProgramEntryPoint commandLine=&quot;worker.cmd&quot; setReadyOnProcessStart=&quot;true&quot; /&gt;
      &lt;/EntryPoint&gt;
    &lt;/Runtime&gt;
  &lt;/WorkerRole&gt;
&lt;/ServiceDefinition&gt;
</pre>
<h3>Specify a Role (Virtual Machine) size</h3>
<p>The size of the role determines the number of CPU cores, the memory capacity, and the local file system size that is allocated to a running instance. The following</p>
<ul>
<li>ExtraSmall (1 CPU, 768 MB RAM, 19 GB DISK)</li>
<li>Small (1 CPU, 1.75 GB RAM, 224 GB DISK)</li>
<li>Medium (2 CPU. 2.5 GB RAM, 489 GB DISK)</li>
<li>Large (4 CPU 7 GB RAM, 999 GB DISK)</li>
<li>ExtraLarge (8 CPU, 14 GB RAM, 2039 GB DISK)</li>
</ul>
<p>Considerations to&nbsp;help you decide on&nbsp;the correct&nbsp;size for your workload</p>
<blockquote>
<ol>
<li>Instances can now be configured to use a D-series VM. These are designed to run applications that demand higher compute power and temporary disk performance. D-series VMs provide faster processors, a higher memory-to-core ratio, and a solid-state drive (SSD) for the temporary disk. For details, see the announcement on the Azure blog, New D-Series Virtual Machine Sizes.</li>
<li>Web roles and worker roles require more temporary disk space than Azure Virtual Machines because of system requirements. The system files reserve 4 GB of space for the Windows page file, and 2 GB of space for the Windows dump file.</li>
<li>The OS disk contains the Windows guest OS and includes the Program Files folder (including installations done via startup tasks unless you specify another disk), registry changes, the System32 folder, and the .NET framework.</li>
<li>The local resource disk contains Azure logs and configuration files, Azure Diagnostics (which includes your IIS logs), and any local storage resources you define.</li>
<li>The apps (application) disk is where your .cspkg is extracted and includes your website, binaries, role host process, startup tasks, web.config, and so on.</li>
</ol>
</blockquote>
<p>More details about <a href="http://msdn.microsoft.com/library/azure/dn197896.aspx" target="_blank">Virtual Machine and Cloud Service Sizes for Azure</a> can be found in the official Azure documentation.</p>
<p>For this example we will use a <strong>Medium</strong> sized role (Virtual Machine) for our Cloud Service.</p>
<p><strong>Replace</strong></p>
<pre class="brush: xml; title: ; notranslate">
&lt;WorkerRole name=&quot;ServiceWorkerRole&quot;&gt;
</pre>
<p><strong>By</strong></p>
<pre class="brush: xml; title: ; notranslate">
&lt;WorkerRole name=&quot;ServiceWorkerRole&quot; vmsize=&quot;Medium&quot;&gt;
</pre>
<h3>Specify a Guest OS Version</h3>
<p>Guest OS families and versions have a release date, a disabled date, and an expiration date. As of the release date, a Guest OS version can be manually selected in the management portal. A Guest OS is removed from the management portal on or after its &#8220;disabled&#8221; date. It is then &#8220;in transition&#8221; but is supported with limited ability to update a deployment. The expiration date is when a version or family is scheduled to be removed from the Azure system completely. Cloud services still running on a version when it expires will be stopped, deleted or force upgraded to a newer version, as detailed in the <a href="http://msdn.microsoft.com/en-us/library/azure/dn750847.aspx">Azure Guest OS Supportability and Retirement Policy</a>. Microsoft supports at least two recent versions of each supported Guest OS family.</p>
<p>Available Families as of December 2014</p>
<ul>
<li><strong>FAMILY 4</strong><br />
Windows Server 2012 R2<br />
Supports .NET 4.0, 4.5, 4.5.1, 4.5.2</li>
<li><strong>FAMILY 3</strong><br />
Windows Server 2012<br />
Supports .NET 4.0, 4.5</li>
<li><strong>FAMILY 2</strong><br />
Windows Server 2008 R2 SP1<br />
Supports .NET 3.5, 4.0</li>
</ul>
<p>More details about <a href="http://msdn.microsoft.com/en-us/library/azure/ee924680.aspx" target="_blank">Azure Guest OS Releases</a> can be found in the official Azure documentation.</p>
<img class="aligncenter size-full wp-image-6118" src="https://alexandrebrisebois.files.wordpress.com/2015/02/cloud-service.png?w=580" alt="cloud-service"   />
<p>The&nbsp;<strong>ServiceConfiguration.{Environment}.cscfg</strong> was created by PowerShell when we executed the <strong>Add-AzureWorkerRole</strong> PowerShell&nbsp;command.</p>
<blockquote><p>The configuration of the settings for your cloud service is determined by the values in the ServiceConfiguration.cscfg file. You specify the number of instances that you want to deploy for each role in this file. The values for the configuration settings that you defined in the service definition file are added to the service configuration file. The thumbprints for any management certificates that are associated with the cloud service are also added to the file. The <a href="http://msdn.microsoft.com/en-us/library/azure/ee758710.aspx" target="_blank">Azure Service Configuration Schema (.cscfg File)</a> provides the allowable format for a service configuration file.</p></blockquote>
<p>The following is the unchanged version of the <strong>ServiceConfiguration.Cloud.cscfg</strong> file. Since it is missing a few pieces, I will show you what to change in order to be able to deploy your brand-new service to Microsoft Azure.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;ServiceConfiguration xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
                      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
                      serviceName=&quot;service-lift-and-shift&quot;
                      osFamily=&quot;2&quot;
                      osVersion=&quot;*&quot;
                      xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration&quot;&gt;
  &lt;Role name=&quot;ServiceWorkerRole&quot;&gt;
    &lt;ConfigurationSettings /&gt;
    &lt;Instances count=&quot;1&quot; /&gt;
    &lt;Certificates /&gt;
  &lt;/Role&gt;
&lt;/ServiceConfiguration&gt;
</pre>
<p>For this example we will keep <strong>Family 2</strong> because our Windows Service is built using .Net 2.0.</p>
<p>We also kept <strong>osVersion=&#8221;*&#8221;</strong> to allow the Azure Fabric to continuously patch the Guest OS.</p>
<h2>Packaging a Windows Service as a Cloud Service</h2>
<p>The <strong>ServiceWorkerRole</strong> folder contains the files and documents that compose our new <strong>Azure Worker Role</strong></p>
<img class="aligncenter wp-image-6127 size-full" src="https://alexandrebrisebois.files.wordpress.com/2015/02/cloud-service-21.png?w=580" alt=""   />
<p>Place the files that compose the Windows Service in this folder.</p>
<img class="aligncenter wp-image-6128 size-full" src="https://alexandrebrisebois.files.wordpress.com/2015/02/cloud-service-31.png?w=580" alt=""   />
<p>Be sure to include the application&#8217;s dependencies such that nothing stops the application from running once it is deployed to an Azure Worker Role. If, for some reason, the application does not seem to run as expected, refer to my earlier <a href="https://alexandrebrisebois.wordpress.com/2014/08/07/busy-starting-role-sites-were-deployed-azure-role-diagnostics/" target="_blank">blog post that shared techniques to investigate and debug Azure Roles</a>.</p>
<p>Before we package the Azure Cloud Service, we must update the <strong>startup.cmd</strong> file. This file contains the startup script&nbsp;that is executed before the&nbsp;<strong>worker.cmd</strong>.&nbsp;The following is the initial version of the file.</p>
<pre class="brush: plain; title: ; notranslate">
:: Placeholder for role startup

echo SUCCESS
exit /b 0
</pre>
<p>The required updates include, installing the Windows Service and making sure that it has started by executing the <strong>startup.ps1</strong> PowerShell script.</p>
<pre class="brush: plain; title: ; notranslate">
D:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /LogToConsole=false DemoWindowsService.exe

REM   Attempt to set the execution policy by using PowerShell version 2.0 syntax.
PowerShell -Version 2.0 -ExecutionPolicy Unrestricted .\startup.ps1 &gt;&gt; &quot;%TEMP%\StartupLog.txt&quot; 2&gt;&amp;1

IF %ERRORLEVEL% EQU -393216 (
   REM   PowerShell version 2.0 isn't available. Set the execution policy by using the PowerShell version 1.0 calling method.

   PowerShell -Command &quot;Set-ExecutionPolicy Unrestricted&quot; &gt;&gt; &quot;%TEMP%\StartupLog.txt&quot; 2&gt;&amp;1
   PowerShell .\startup.ps1 &gt;&gt; &quot;%TEMP%\StartupLog.txt&quot; 2&gt;&amp;1
)

REM   If an error occurred, return the errorlevel.
EXIT /B %errorlevel%

echo SUCCESS
exit /b 0
</pre>
<p>The <strong>startup.ps1</strong> PowerShell script Starts the DemoWindowsService Windows Service. This example is basic and would benefit from much error handling. For example, we could make sure that the service exists and that it is stopped before we call the <strong>Start-Service</strong> command. Then we could verify that it has indeed started.</p>
<pre class="brush: powershell; title: ; notranslate">
$srv = 'DemoWindowsService'
Start-Service -Name $srv
</pre>
<p>The <strong>worker.cmd</strong>&nbsp;file contains the application loop that is executed by the&nbsp;Azure Worker role.&nbsp;The generated file contains a script that blocks the execution of the host thread and makes the Azure Fabric act as if the application was running.</p>
<pre class="brush: plain; title: ; notranslate">
:workerLoop

:: Do work
ping 123.45.67.89 -n 1 -w 1000000 &amp;gt; nul

goto workerLoop
</pre>
<p>In order to allow the Azure Cloud Service to self heal, I recommend that add logic that monitors the state of the Windows Service. If the Windows service stops, try to start it again. If that fails, your script should end the loop and allow the command line to complete its execution. This termination even signals the Azure Fabric to recycle the Role and to self heal.</p>
<p>When changes are made to CMD script files, we must ensure that they are saved using the <strong>ANSI Encoding</strong>. Failing to do so may prevent the CMD script from executing.</p>
<p>Now that we have a Windows Service configured to be installed and executed in a Worker Role, it&#8217;s time to package the Cloud Service. In <strong>Windows PowerShell ISE</strong> and navigate back to the folder that contains the Cloud Service.</p>
<p>The Cloud Service for this blog post is at the following location:</p>
<pre class="brush: plain; title: ; notranslate">
C:\users\&lt;user id&gt;\Documents\demo-lift-and-shift-service
</pre>
<p>In the PowerShell console, execute the following commands.</p>
<pre class="brush: powershell; title: ; notranslate">
# Package the Cloud Service
Save-AzureServiceProjectPackage
</pre>
<p>This produces a package named <strong>cloud_package.cspkg</strong>, which is required for the service&#8217;s deployment.</p>
<img class="aligncenter wp-image-6132 size-full" src="https://alexandrebrisebois.files.wordpress.com/2015/02/cloud-service-4.png?w=580" alt=""   />
<h2>Deploying the Cloud Service</h2>
<p>This step has a prerequisite. We must start by importing a publish profile from our Microsoft Azure Subscription. PowerShell will use it to publish our Cloud Service to our Microsoft Azure.</p>
<p>In the PowerShell console, execute the following commands.</p>
<pre class="brush: powershell; title: ; notranslate">
# Opens a website that allows us to download the Publish Profile
# associated with our Microsoft Azure Subscription
Get-AzurePublishSettingsFile
</pre>
<p>Save the publish settings files to your downloads folder then import it using the following command.</p>
<pre class="brush: powershell; title: ; notranslate">
Import-AzurePublishSettingsFile -PublishSettingsFile 'C:\Users\&lt;user id&gt;\Downloads\&lt;subscription name&gt;-credentials.publishsettings'
</pre>
<p>We are now ready to publish our brand-new Cloud Service. The following command will create a new storage account to upload our package. This is the default behavior because we did not provide a storage account for the command. We specified a name for the service, a location (datacenter), a slot (production or staging) and a deployment name. For more information about the <a href="http://msdn.microsoft.com/en-us/library/azure/dn495166.aspx" target="_blank">Publish-AzureServiceProject command please refer to the official documentation</a>.</p>
<pre class="brush: powershell; title: ; notranslate">
Publish-AzureServiceProject -ServiceName 'service-lift-and-shift'
                            -Location 'East US'
                            -Slot 'Production'
                            -DeploymentName '2015-02-14-15-46'
                            -Verbose
</pre>
<p>If the Publish-AzureServiceProject&nbsp;command is executed with the -Verbose flag, it will produce a detailed output that allows you to understand what is happening. It&#8217;s also very useful when you need to debug a failed deployment.</p>
<pre class="brush: powershell; title: ; notranslate">
WARNING: Publishing service-lift-and-shift to Microsoft Azure. This may take several minutes...
WARNING: 3:47:10 PM - Preparing runtime deployment for service 'service-lift-and-shift'
WARNING: 3:47:11 PM - Verifying storage account 'serviceliftandshift'...
WARNING: 3:47:43 PM - Preparing deployment for service-lift-and-shift with Subscription ID: dfbedef7-xxxx-xxxx-xxxx-650ca03208ee...
WARNING: 3:47:47 PM - Connecting...
WARNING: 3:47:48 PM - Creating...
WARNING: 3:47:49 PM - Created hosted service 'service-lift-and-shift'.
WARNING: 3:47:49 PM - Uploading Package to storage service serviceliftandshift...
WARNING: 3:47:56 PM - Starting...
WARNING: 3:48:30 PM - Created Deployment ID: 03e36c62a5f74d5f9ebd0a2ec0b16880.
WARNING: 3:48:30 PM - Initializing...
WARNING: 3:51:49 PM - Instance ServiceWorkerRole_IN_0 of role ServiceWorkerRole is busy.
WARNING: 3:52:22 PM - Instance ServiceWorkerRole_IN_0 of role ServiceWorkerRole is ready.

PersistentVMDowntime : Microsoft.WindowsAzure.Commands.Utilities.CloudService.Model.PersistentVMDowntimeInfo
Name                 : 2015-02-14-15-46
DeploymentSlot       : Production
PrivateID            : 03e36c62a5f74d5f9ebd0a2ec0b16880
Status               : Running
Label                : service-lift-and-shift
Configuration        : ...
RoleInstanceList     : {ServiceWorkerRole}
UpgradeStatus        :
UpgradeDomainCount   : 1
RoleList             : {ServiceWorkerRole}
SdkVersion           : 2.5.6496.10
Locked               : False
RollbackAllowed      : False
VirtualNetworkName   :
CreatedTime          : 2015-02-14 3:47:58 PM
LastModifiedTime     : 2015-02-14 3:52:23 PM
ExtendedProperties   : {}
Dns                  :
VirtualIPs           : {Microsoft.WindowsAzure.Commands.Utilities.CloudService.Model.VirtualIP}
</pre>
<p>Once the Cloud Service has completed its deployment, you can log into the <a href="https://manage.windowsazure.com" target="_blank">https://manage.windowsazure.com</a> portal and you will be able to monitor and alter its configurations.</p>
<p>Because this solution does not rely on the .NET Azure SDK and since the CMD script has an infinite loop, we do not see a recycling status for a faulted Azure Worker Role. If we observe a high CPU, which could be unexpected, it could be because the Cloud Service was deployed with the wrong Guest OS Family. This can cause the Windows Service to continuously fail to start. The CMD worker script is blocked and prevents the Cloud Service from restarting. Consequently, updating the ServiceConfiguration.Cloud.cscfg file with the correct Guest OS Family and redeploying the Cloud Service can solve the issue.</p>
<p>Out of curiosity, you can configured the Remote Desktop Extension through the management portal and peaked into the provisioned instance. This will allow you to validate whether the Windows Service starts as expected.</p>
<h2>Bringing it All Together</h2>
<p>Azure Worker Roles support a surprising variety of scenarios! Here&#8217;s a quick recap of the steps taken to Lift &amp; Shift a Windows Service to Microsoft Azure.</p>
<pre class="brush: powershell; title: ; notranslate">
# Create the Cloud Service
New-AzureServiceProject -ServiceName 'service-lift-and-shift' -Verbose

# Create the Worker Role
Add-AzureWorkerRole -Name 'ServiceWorkerRole' -Instances 1 -Verbose
</pre>
<p>Update the configurations files with the proper Guest OS Family and with the desired VM Size for your Cloud Service. Then copy the Windows Service and its dependencies to the Role&#8217;s folder. Don&#8217;t forget to update the startup.cmd script file and to add the startup.ps1 file so that the service may install the Windows Service and ensure that it is started.</p>
<pre class="brush: powershell; title: ; notranslate">
# Package the Cloud Service
Save-AzureServiceProjectPackage

# Publish the Package to Microsoft Azure
Publish-AzureServiceProject -ServiceName 'service-lift-and-shift'
                            -Location 'East US'
                            -Slot 'Production'
                            -DeploymentName '2015-02-14-15-46'
                            -Verbose
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/ansi/'>ANSI</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configurations/'>Configurations</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/guest-os/'>Guest OS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/lift-shift/'>Lift &amp; Shift</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/paas/'>PaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/package/'>Package</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/roles/'>Roles</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/windows-service/'>Windows Service</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/worker-role/'>Worker Role</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/xml/'>XML</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6112/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6112&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/02/22/lift-and-shift-of-a-windows-service-to-microsoft-azure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/02/lift-and-shift-service.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/lift-and-shift-service.jpg?w=150" medium="image">
			<media:title type="html">lift-and-shift-service</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/cloud-service.png" medium="image">
			<media:title type="html">cloud-service</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/cloud-service.png" medium="image">
			<media:title type="html">cloud-service</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/cloud-service-21.png" medium="image" />

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/cloud-service-31.png" medium="image" />

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/cloud-service-4.png" medium="image" />
	</item>
		<item>
		<title>Opening Windows Firewall Ports on #Azure Cloud Services</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/02/19/opening-windows-firewall-ports-on-azure-cloud-services/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/02/19/opening-windows-firewall-ports-on-azure-cloud-services/#comments</comments>
		<pubDate>Thu, 19 Feb 2015 17:30:04 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Firewall]]></category>
		<category><![CDATA[Port]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Roles]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Virtual Network]]></category>
		<category><![CDATA[VNet]]></category>
		<category><![CDATA[Web Role]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Worker Role]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6083</guid>
		<description><![CDATA[Opening Ports on Cloud Services There are scenarios that warrants us to open ports of the Windows Firewall. Imagine an application that coordinates work across many compute nodes. The workload coordinator needs to know and manage each compute node. The diagram above, depicts a Virtual Machine that has direct access to instances of a Cloud [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6083&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/02/19/opening-windows-firewall-ports-on-azure-cloud-services/" target="_blank" title="Opening Windows Firewall Ports on #Azure Cloud&nbsp;Services"><img width="580" height="446" src="https://alexandrebrisebois.files.wordpress.com/2015/02/configuring-internal-endpoints-cloud-services.png?w=580" class="attachment-large wp-post-image" alt="Configuring Internal Endpoints Cloud Services" /></a></p><h1>Opening Ports on Cloud Services</h1>
<p>There are scenarios that warrants us to open ports of the Windows Firewall. Imagine an application that coordinates work across many compute nodes. The workload coordinator needs to know and manage each compute node.</p>
<p>The diagram above, depicts a Virtual Machine that has direct access to instances of a Cloud Service without going through a Load Balancer. Both the Virtual Machine and Cloud Service are deployed to a Virtual Network on Microsoft Azure. Using <a title="Configuring Internal Endpoints on #Azure Cloud Services" href="https://alexandrebrisebois.wordpress.com/2015/02/17/configuring-internal-endpoints-on-azure-cloud-services/" target="_blank">Internal Endpoints</a> in this scenario, would not yield the desired configuration. Endpoints are defined at the Cloud Service boundary and are IP addresses belong to the Data Center&#8217;s Network Address Space. Therefore, In order to allow the Virtual Machine to communicate over specific ports to individual Cloud Service instances, we need to use PowerShell and a Startup Task to configure the Windows Firewall.<span id="more-6083"></span></p>
<h3>Using PowerShell to Open a Port</h3>
<pre class="brush: powershell; title: ; notranslate">
$port = New-Object -ComObject HNetCfg.FWOpenPort
$port.Port = 8080
$port.Name = 'Compute Node Inbound Port'
$port.Enabled = $true

$fwMgr = New-Object -ComObject HNetCfg.FwMgr
$profile = $fwMgr.LocalPolicy.CurrentProfile
$profile.GloballyOpenPorts.Add($port)
</pre>
<h3>Using a Command Line to Open a Port</h3>
<pre class="brush: plain; title: ; notranslate">
REM   Add a firewall rule in a startup task.

REM   Add an inbound rule requiring security and encryption for TCP port 8080 traffic.
netsh advfirewall firewall add rule name=&quot;Require Encryption for Inbound TCP/8080&quot; protocol=TCP dir=in localport=8080 security=authdynenc action=allow &gt;&gt; &quot;%TEMP%\StartupLog.txt&quot; 2&gt;&amp;1

REM   If an error occurred, return the errorlevel.
EXIT /B %errorlevel%
</pre>
<h3>Configuring a Cloud Service Startup Task</h3>
<blockquote><p>Startup tasks are actions that are taken before your roles begin. Startup tasks are defined in the ServiceDefinition.csdef file by using the Task element within the Startup element. Frequently startup tasks are batch files, but they can also be console applications, or batch files that start PowerShell scripts.</p></blockquote>
<p>We have two options to open Ports on the Windows Firewall. For this post, I will use PowerShell because it has more steps. This example can be used as a starting point to run other PowerShell scripts from Startup Tasks.</p>
<h3>Cloud Service &#8211; ServiceDefinition.csdef</h3>
<p>The Startup Task is defined on a per role basis. In our case, we must elevate the execution context so that we may interact with the Windows Firewall.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;ServiceDefinition xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; name=&quot;ComputeService&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition&quot;&gt;
	&lt;WorkerRole name=&quot;Compute&quot; vmsize=&quot;Standard_D1&quot;&gt;
		&lt;Startup&gt;
			&lt;Task commandLine=&quot;.\startup.cmd &amp;gt; startup_log.txt&quot; executionContext=&quot;elevated&quot; /&gt;
		&lt;/Startup&gt;
		&lt;Runtime executionContext=&quot;elevated&quot;&gt;
			&lt;EntryPoint&gt;
				&lt;ProgramEntryPoint commandLine=&quot;worker.cmd&quot; setReadyOnProcessStart=&quot;true&quot; /&gt;
			&lt;/EntryPoint&gt;
		&lt;/Runtime&gt;
	&lt;/WorkerRole&gt;
&lt;/ServiceDefinition&gt;
</pre>
<h3>Command Line &#8211; startup.cmd</h3>
<p>This command file elevates the execution policy for PowerShell, then it executes the startup.ps1 file. It&#8217;s important to note that every time the command line is executed, it produces a StartupLog file, which helps to confirm that everything ran as expected. If an error occurs, this log file can save you countless hours of debugging by providing insights about what may have gone wrong.</p>
<pre class="brush: plain; title: ; notranslate">
REM   Attempt to set the execution policy by using PowerShell version 2.0 syntax.
PowerShell -Version 2.0 -ExecutionPolicy Unrestricted .\startup.ps1 &gt;&gt; &quot;%TEMP%\StartupLog.txt&quot; 2&gt;&amp;1

IF %ERRORLEVEL% EQU -393216 (
   REM   PowerShell version 2.0 isn't available. Set the execution policy by using the PowerShell version 1.0 calling method.

   PowerShell -Command &quot;Set-ExecutionPolicy Unrestricted&quot; &gt;&gt; &quot;%TEMP%\StartupLog.txt&quot; 2&gt;&amp;1
   PowerShell .\startup.ps1 &gt;&gt; &quot;%TEMP%\StartupLog.txt&quot; 2&gt;&amp;1
)

REM   If an error occurred, return the errorlevel.
EXIT /B %errorlevel%

echo SUCCESS
exit /b 0
</pre>
<h3>PowerShell &#8211; startup.ps1</h3>
<p>This file contains the PowerShell script listed above. This is also the place where we can configure other aspects of out Cloud Service via PowerShell.</p>
<pre class="brush: powershell; title: ; notranslate">
$port = New-Object -ComObject HNetCfg.FWOpenPort
$port.Port = 8080
$port.Name = 'Compute Node Inbound Port'
$port.Enabled = $true

$fwMgr = New-Object -ComObject HNetCfg.FwMgr
$profile = $fwMgr.LocalPolicy.CurrentProfile
$profile.GloballyOpenPorts.Add($port)
</pre>
<h3>Packaging</h3>
<p>For this to work, we need to place the Command Line and PowerShell files at the root of the Cloud Service Role. If you are using Visual Studio to create your package, be sure to set both files to <strong>Copy Always</strong> otherwise they will be missing from the resulting package. If you are using PowerShell to create the package, the CmdLet will take everything from the role&#8217;s directory.</p>
<h2>Deploying the Cloud Service</h2>
<p>There is nothing different about deploying a Cloud Service that has Startup Tasks. Using your tool of preference, create a new Cloud Service package and deploy it to Microsoft Azure.</p>
<p>Using PowerShell to package the Cloud Service requires you to navigate to the Cloud Service directory and execute the&nbsp;<strong>Save-AzureServiceProjectPackage</strong> command. This will produce a <strong>cloud_package.cspkg</strong> package file.</p>
<p>To deploy Azure Cloud Services, I usually use PowerShell. This is an example of what you may write yourself.</p>
<pre class="brush: powershell; title: ; notranslate">
New-AzureDeployment `
                -Package 'C:\\cloud_package.cspkg' `
                -Configuration 'C:\\ServiceConfiguration.Cloud.cscfg' `
                -Slot Production `
                -Label 'Compute-2015-02-17' `
                -ServiceName  'DemoCloudService' `
                -Name 'DemoCloudService' `
                -Verbose
</pre>
<h2>Resources</h2>
<ul>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/hh180155.aspx" target="_blank">Run Startup Tasks in Azure</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/jj129544.aspx" target="_blank">Strategies for Writing Startup Tasks that can run Multiple Times</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/jj129545.aspx" target="_blank">Best Practices for Startup Tasks</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/gg456327.aspx" target="_blank">Define Startup Tasks for a Role</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/gg432991.aspx" target="_blank">Define Environment Variables Before a Role Starts</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/hh974419.aspx" target="_blank">Use Local Storage to Store Files During Startup</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/hh974417.aspx" target="_blank">Make a Startup Task Perform Different Actions on the Compute Emulator and the Cloud</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/hh974418.aspx" target="_blank">Use AppCmd.exe to Configure IIS at Startup</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/jj156208.aspx" target="_blank">Add Firewall Rules By Using a Startup Task</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/gg557553.aspx" target="_blank">WebRole Schema</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/gg557552.aspx" target="_blank">WorkerRole Schema</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configuration/'>Configuration</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/firewall/'>Firewall</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/port/'>Port</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/roles/'>Roles</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-network/'>Virtual Network</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/vnet/'>VNet</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/web-role/'>Web Role</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/windows/'>Windows</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/worker-role/'>Worker Role</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/xml/'>XML</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6083/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6083/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6083/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6083/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6083/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6083/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6083/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6083/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6083/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6083/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6083/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6083/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6083/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6083/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6083&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/02/19/opening-windows-firewall-ports-on-azure-cloud-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/02/configuring-internal-endpoints-cloud-services.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/configuring-internal-endpoints-cloud-services.png?w=150" medium="image">
			<media:title type="html">Configuring Internal Endpoints Cloud Services</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Configuring Internal Endpoints on #Azure Cloud Services</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/02/17/configuring-internal-endpoints-on-azure-cloud-services/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/02/17/configuring-internal-endpoints-on-azure-cloud-services/#comments</comments>
		<pubDate>Tue, 17 Feb 2015 18:06:39 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Port]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Roles]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Virtual Network]]></category>
		<category><![CDATA[VNet]]></category>
		<category><![CDATA[Web Role]]></category>
		<category><![CDATA[Worker Role]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6056</guid>
		<description><![CDATA[The configuration of an Internal Endpoint is done through the Service Definition.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6056&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/02/17/configuring-internal-endpoints-on-azure-cloud-services/" target="_blank" title="Configuring Internal Endpoints on #Azure Cloud&nbsp;Services"><img width="580" height="246" src="https://alexandrebrisebois.files.wordpress.com/2015/02/internalendpoint.png?w=580" class="attachment-large wp-post-image" alt="InternalEndpoint" /></a></p><h1>Configuring Internal Endpoints</h1>
<p>There are many scenarios where Internal Endpoints make sense. Imagine a web application that needs to communicate with a middle tier. The communication between both Cloud Services does not need to leave Microsoft Azure networks. The diagram above depicts a scenario where a Web Role has access to a middle tier Cloud Service without going through the public Internet.</p>
<blockquote><p>Role instances running in a Cloud Service on Microsoft Azure communicate through internal and external connections that vary depending on the type of communication that is needed. An internal endpoint can connect by using a protocol of HTTP, TCP or UDP.</p></blockquote>
<p>The configuration of an Internal Endpoint is done through the <strong>Service Definition</strong>. Below is the template used to describe what can be done in terms of Endpoint configurations.&nbsp;<span id="more-6056"></span></p>
<h3>Service Definition Endpoint Template</h3>
<pre class="brush: xml; title: ; notranslate">
&lt;Endpoints&gt;
  &lt;InputEndpoint certificate=&quot;&lt;certificate-name&gt;&quot; ignoreRoleInstanceStatus=&quot;[true|false]&quot; name=&quot;&lt;input-endpoint-name&gt;&quot; protocol=&quot;[http|https|tcp|udp]&quot; localPort=&quot;&lt;port-number&gt;&quot; port=&quot;&lt;port-number&gt;&quot; loadBalancerProbe=”&lt;load-balancer-probe-name&gt;” /&gt;
  &lt;InternalEndpoint name=&quot;&lt;internal-endpoint-name&gt;&quot; protocol=&quot;[http|tcp|udp|any]&quot; port=&quot;&lt;port-number&gt;&quot;&gt;
     &lt;FixedPort port=&quot;&lt;port-number&gt;&quot;/&gt;
     &lt;FixedPortRange min=&quot;&lt;minium-port-number&gt;&quot; max=&quot;&lt;maximum-port-number&gt;&quot;/&gt;
  &lt;/InternalEndpoint&gt;
  &lt;InstanceInputEndpoint name=&quot;&lt;instance-input-endpoint-name&gt;&quot; localPort=&quot;&lt;port-number&gt;&quot; protocol=&quot;[udp|tcp]&quot;&gt;
     &lt;AllocatePublicPortFrom&gt;
        &lt;FixedPortRange min=&quot;&lt;minium-port-number&gt;&quot; max=&quot;&lt;maximum-port-number&gt;&quot;/&gt;
     &lt;/AllocatePublicPortFrom&gt;
  &lt;/InstanceInputEndpoint&gt;
&lt;/Endpoints&gt;
</pre>
<h3>The Endpoints Element</h3>
<blockquote><p>Describes the collection of input (external), internal, and instance input endpoints for a role. This element is the parent of the <strong>InputEndpoint</strong>, <strong>InternalEndpoint</strong>, and <strong>InstanceInputEndpoint</strong> elements.</p>
<p>Input and Internal endpoints are allocated separately. A service can have a total of 25 input, internal, and instance input endpoints which can be allocated across the 25 roles allowed in a service. For example, if have 5 roles you can allocate 5 input endpoints per role or you can allocate 25 input endpoints to a single role or you can allocate 1 input endpoint each to 25 roles.</p></blockquote>
<h2>Sample ServiceDefinition</h2>
<p>The following sample defines an <strong>Internal Endpoint</strong> names <strong>TcpListener </strong>which <strong>opens ports between 1000 and 2000</strong>.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;ServiceDefinition xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; name=&quot;briseboisDemo3&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition&quot;&gt;
  &lt;WorkerRole name=&quot;Compute&quot;&gt;
    &lt;Startup&gt;
      &lt;Task commandLine=&quot;setup_worker.cmd &amp;gt; log.txt&quot; executionContext=&quot;elevated&quot;&gt;
        &lt;Environment&gt;
          &lt;Variable name=&quot;EMULATED&quot;&gt;
            &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
          &lt;/Variable&gt;
          &lt;Variable name=&quot;RUNTIMEID&quot; value=&quot;&quot; /&gt;
          &lt;Variable name=&quot;RUNTIMEURL&quot; value=&quot;&quot; /&gt;
        &lt;/Environment&gt;
      &lt;/Task&gt;
      &lt;Task commandLine=&quot;.\startup.cmd &amp;gt; startup_log.txt&quot; executionContext=&quot;elevated&quot; /&gt;
    &lt;/Startup&gt;
    &lt;Endpoints&gt;
      &lt;InternalEndpoint name=&quot;TcpListener&quot; protocol=&quot;tcp&quot;&gt;
        &lt;FixedPortRange min=&quot;1000&quot; max=&quot;2000&quot; /&gt;
      &lt;/InternalEndpoint&gt;
    &lt;/Endpoints&gt;
    &lt;Runtime&gt;
      &lt;Environment&gt;
        &lt;Variable name=&quot;EMULATED&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
        &lt;/Variable&gt;
      &lt;/Environment&gt;
      &lt;EntryPoint&gt;
        &lt;ProgramEntryPoint commandLine=&quot;worker.cmd&quot; setReadyOnProcessStart=&quot;true&quot; /&gt;
      &lt;/EntryPoint&gt;
    &lt;/Runtime&gt;
  &lt;/WorkerRole&gt;
&lt;/ServiceDefinition&gt;
</pre>
<h2>Deploying the Cloud Service</h2>
<p>There is nothing different about deploying a Cloud Service that exposes Internal Endpoints. Using your tool of preference, create a new Cloud Service package and deploy it to Microsoft Azure.</p>
<p>Using PowerShell to package the Cloud Service requires you to navigate to the Cloud Service directory and execute the&nbsp;<strong>Save-AzureServiceProjectPackage</strong> command. This will produce a <strong>cloud_package.cspkg</strong> package file.</p>
<p>To deploy Azure Cloud Services, I usually use PowerShell. This is an example of what you may write yourself.</p>
<pre class="brush: powershell; title: ; notranslate">
New-AzureDeployment `
                -Package 'C:\\cloud_package.cspkg' `
                -Configuration 'C:\\ServiceConfiguration.Cloud.cscfg' `
                -Slot Production `
                -Label 'Compute-2015-02-17' `
                -ServiceName  'DemoCloudService' `
                -Name 'DemoCloudService' `
                -Verbose
</pre>
<h2>Resources</h2>
<ul>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/hh180158.aspx" target="_blank">Enable Communication for Role Instances in Azure</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/gg557553.aspx" target="_blank">WebRole Schema</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/gg557552.aspx" target="_blank">WorkerRole Schema</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configuration/'>Configuration</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/port/'>Port</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/roles/'>Roles</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-network/'>Virtual Network</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/vnet/'>VNet</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/web-role/'>Web Role</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/worker-role/'>Worker Role</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/xml/'>XML</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6056/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6056/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6056/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6056/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6056/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6056/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6056/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6056/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6056/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6056/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6056/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6056/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6056/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6056/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6056&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/02/17/configuring-internal-endpoints-on-azure-cloud-services/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/02/internalendpoint.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/internalendpoint.png?w=150" medium="image">
			<media:title type="html">InternalEndpoint</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Deploying an #Azure Cloud Service That Requires Elevated Privileges</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/02/17/deploying-an-azure-cloud-service-that-requires-elevated-privileges/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/02/17/deploying-an-azure-cloud-service-that-requires-elevated-privileges/#comments</comments>
		<pubDate>Tue, 17 Feb 2015 15:16:11 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Runtime Configuration]]></category>
		<category><![CDATA[Web Role]]></category>
		<category><![CDATA[Worker Role]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6039</guid>
		<description><![CDATA[Configuring Elevated Privileges There are various scenarios that require us to execute applications with elevated privileges. It&#8217;s common for this requirement to surface during lift and shift efforts. This configuration is done in the Service Definition file. It requires us to specify the Runtime Execution Context to elevated. Runtime Configuration Template This template uses the [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6039&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/02/17/deploying-an-azure-cloud-service-that-requires-elevated-privileges/" target="_blank" title="Deploying an #Azure Cloud Service That Requires Elevated&nbsp;Privileges"><img width="528" height="242" src="https://alexandrebrisebois.files.wordpress.com/2015/02/deploying.png?w=528" class="attachment-large wp-post-image" alt="Deploying" /></a></p><h1>Configuring Elevated Privileges</h1>
<p>There are various scenarios that require us to execute applications with elevated privileges. It&#8217;s common for this requirement to surface during <a href="https://alexandrebrisebois.wordpress.com/2014/12/14/lift-and-shift-of-a-console-appication-to-microsoft-azure/" target="_blank">lift and shift efforts</a>.</p>
<p>This configuration is done in the Service Definition file. It requires us to specify the <strong>Runtime Execution Context</strong> to <strong>elevated</strong>.</p>
<h3>Runtime Configuration Template</h3>
<p>This template uses the <strong>ProgramEntryPoint </strong>as an EntryPoint. Roles also support <strong>NetFxEntryPoint</strong>.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;Runtime executionContext=&quot;[limited|elevated]&quot;&gt;
   &lt;Environment&gt;
     &lt;Variable name=&quot;&lt;variable-name&gt;&quot; value=&quot;&lt;variable-value&gt;&quot;&gt;
      &lt;RoleInstanceValue xpath=&quot;&lt;xpath-to-role-environment-settings&gt;&quot;/&gt;
    &lt;/Variable&gt;
  &lt;/Environment&gt;
  &lt;EntryPoint&gt;
     &lt;ProgramEntryPoint commandLine=&quot;worker.cmd&quot; setReadyOnProcessStart=&quot;true&quot; /&gt;
   &lt;/EntryPoint&gt;
&lt;/Runtime&gt;
</pre>
<p><span id="more-6039"></span></p>
<h3>Sample ServiceDefinition</h3>
<p>This sample ServiceDefinition was generated using the <strong>Add-AzureWorkerRole</strong> PowerShell command.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;ServiceDefinition xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; name=&quot;briseboisDemo3&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition&quot;&gt;
  &lt;WorkerRole name=&quot;Compute&quot;&gt;
    &lt;Startup&gt;
      &lt;Task commandLine=&quot;setup_worker.cmd &amp;gt; log.txt&quot; executionContext=&quot;elevated&quot;&gt;
        &lt;Environment&gt;
          &lt;Variable name=&quot;EMULATED&quot;&gt;
            &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
          &lt;/Variable&gt;
          &lt;Variable name=&quot;RUNTIMEID&quot; value=&quot;&quot; /&gt;
          &lt;Variable name=&quot;RUNTIMEURL&quot; value=&quot;&quot; /&gt;
        &lt;/Environment&gt;
      &lt;/Task&gt;
      &lt;Task commandLine=&quot;.\startup.cmd &amp;gt; startup_log.txt&quot; executionContext=&quot;elevated&quot; /&gt;
    &lt;/Startup&gt;
    &lt;Endpoints&gt;
      &lt;InputEndpoint name=&quot;HttpIn&quot; protocol=&quot;tcp&quot; port=&quot;80&quot; /&gt;
    &lt;/Endpoints&gt;
    &lt;Runtime executionContext=&quot;elevated&quot;&gt;
      &lt;Environment&gt;
        &lt;Variable name=&quot;PORT&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[@name='HttpIn']/@port&quot; /&gt;
        &lt;/Variable&gt;
        &lt;Variable name=&quot;EMULATED&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
        &lt;/Variable&gt;
      &lt;/Environment&gt;
      &lt;EntryPoint&gt;
        &lt;ProgramEntryPoint commandLine=&quot;worker.cmd&quot; setReadyOnProcessStart=&quot;true&quot; /&gt;
      &lt;/EntryPoint&gt;
    &lt;/Runtime&gt;
  &lt;/WorkerRole&gt;
&lt;/ServiceDefinition&gt;
</pre>
<h2>Deploying the Cloud Service</h2>
<p>There is nothing different about deploying a Cloud Service that executes with elevated privileges. Using your tool of preference, create a new Cloud Service package and deploy it to Microsoft Azure.</p>
<p>Using PowerShell to package the Cloud Service requires you to navigate to the Cloud Service directory and execute the&nbsp;<strong>Save-AzureServiceProjectPackage</strong> command. This will produce a <strong>cloud_package.cspkg</strong> package file.</p>
<p>To deploy Azure Cloud Services, I usually use PowerShell. This is an example of what you may write yourself.</p>
<pre class="brush: powershell; title: ; notranslate">
New-AzureDeployment `
                -Package 'C:\\cloud_package.cspkg' `
                -Configuration 'C:\\ServiceConfiguration.Cloud.cscfg' `
                -Slot Production `
                -Label 'Compute-2015-02-17' `
                -ServiceName  'DemoCloudService' `
                -Name 'DemoCloudService' `
                -Verbose
</pre>
<h2>Resources</h2>
<ul>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/gg557553.aspx" target="_blank">WebRole Schema</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/gg557552.aspx" target="_blank">WorkerRole Schema</a></li>
<li><a href="http://justazure.com/microsoft-azure-cloud-services-part-2-anatomy-cloud-service/" target="_blank">Microsoft Azure Cloud Services Part 2: Anatomy of a Cloud Service</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/deployment/'>Deployment</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/runtime-configuration/'>Runtime Configuration</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/web-role/'>Web Role</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/worker-role/'>Worker Role</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6039/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6039/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6039/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6039/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6039/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6039/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6039/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6039/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6039/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6039/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6039/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6039/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6039/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6039/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6039&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/02/17/deploying-an-azure-cloud-service-that-requires-elevated-privileges/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/02/deploying.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/deploying.png?w=150" medium="image">
			<media:title type="html">Deploying</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Deploying a Cloud Services to A Virtual Network (VNet) on #Azure</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/02/15/deploying-a-cloud-services-to-a-virtual-network-vnet-on-azure/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/02/15/deploying-a-cloud-services-to-a-virtual-network-vnet-on-azure/#comments</comments>
		<pubDate>Sun, 15 Feb 2015 21:20:20 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Roles]]></category>
		<category><![CDATA[Subnet]]></category>
		<category><![CDATA[Virtual Network]]></category>
		<category><![CDATA[VNet]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=6018</guid>
		<description><![CDATA[In order to deploy a Cloud Service to a Virtual Network, we must add Network Configuration section to the Service Configuration file.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6018&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/02/15/deploying-a-cloud-services-to-a-virtual-network-vnet-on-azure/" target="_blank" title="Deploying a Cloud Services to A Virtual Network (VNet) on&nbsp;#Azure"><img width="569" height="351" src="https://alexandrebrisebois.files.wordpress.com/2015/02/deploying-to-a-virtual-network.png?w=569" class="attachment-large wp-post-image" alt="Deploying to a Virtual Network" /></a></p><h1>Deploying a Cloud Service to a VNet</h1>
<p>In a recent post about <a title="Getting to Know #Azure Virtual Networks" href="https://alexandrebrisebois.wordpress.com/2015/02/15/getting-to-know-azure-virtual-networks/" target="_blank">Microsoft Azure Virtual Networks</a>,  I made the recommendation that Cloud Services should be deployed to Microsoft Azure Virtual Networks. The driving factor behind this recommendation comes from my personal real-world experience, where I learned the hard way, that <strong>moving a deployed Cloud Service to a Virtual Network meant downtime&#8230;</strong><span id="more-6018"></span></p>
<h2>Getting it Done</h2>
<p>In order to deploy a Cloud Service to a Virtual Network, we must add Network Configuration section to the Service Configuration file. The following is the updated&nbsp;<strong>ServiceConfiguration.Cloud.cscfg</strong> that specified that my Cloud Service is to be deployed to my Virtual Network called <strong>AzureVNet</strong> and more specifically to its Subnet called <strong>MiddleTier</strong>.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;ServiceConfiguration xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; serviceName=&quot;briseboisDemo3&quot; osFamily=&quot;4&quot; osVersion=&quot;*&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration&quot;&gt;

  &lt;Role name=&quot;Compute&quot;&gt;
    &lt;Instances count=&quot;5&quot; /&gt;
  &lt;/Role&gt;

  &lt;NetworkConfiguration&gt;
    &lt;!-- Name of the target Virtual Network --&gt;
    &lt;VirtualNetworkSite name=&quot;AzureVNet&quot; /&gt;

    &lt;!-- Associating a Role to a Specific Subnet by name --&gt;
    &lt;AddressAssignments&gt;
      &lt;InstanceAddress roleName=&quot;Compute&quot;&gt;
        &lt;Subnets&gt;
          &lt;Subnet name=&quot;MiddleTier&quot; /&gt;
        &lt;/Subnets&gt;
      &lt;/InstanceAddress&gt;
    &lt;/AddressAssignments&gt;
  &lt;/NetworkConfiguration&gt;
&lt;/ServiceConfiguration&gt;
</pre>
<p>Looking at these configuration updates, you may be asking whether we have to do anything else to successfully deploy to a Virtual Network. The answer is no, there is nothing more to it. Fire up PowerShell or your favorite tool to deploy your updated Cloud Service package to Azure. </p>
<p>I used the following Network Configuration to create my test Virtual Network.   </p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;NetworkConfiguration xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration&quot;&gt;
  &lt;VirtualNetworkConfiguration&gt;
    &lt;Dns /&gt;
    &lt;VirtualNetworkSites&gt;
      &lt;VirtualNetworkSite name=&quot;AzureVNet&quot; Location=&quot;East US 2&quot;&gt;
        &lt;AddressSpace&gt;
          &lt;AddressPrefix&gt;10.0.0.0/24&lt;/AddressPrefix&gt;
        &lt;/AddressSpace&gt;
        &lt;Subnets&gt;
          &lt;Subnet name=&quot;MiddleTier&quot;&gt;
            &lt;AddressPrefix&gt;10.0.0.0/27&lt;/AddressPrefix&gt;
          &lt;/Subnet&gt;
        &lt;/Subnets&gt;
      &lt;/VirtualNetworkSite&gt;
    &lt;/VirtualNetworkSites&gt;
  &lt;/VirtualNetworkConfiguration&gt;
&lt;/NetworkConfiguration&gt;
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/best-practices/'>Best Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configuration/'>Configuration</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/roles/'>Roles</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/subnet/'>Subnet</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-network/'>Virtual Network</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/vnet/'>VNet</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/xml/'>XML</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/6018/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/6018/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/6018/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/6018/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/6018/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/6018/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/6018/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/6018/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/6018/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/6018/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/6018/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/6018/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/6018/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/6018/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=6018&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/02/15/deploying-a-cloud-services-to-a-virtual-network-vnet-on-azure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/02/deploying-to-a-virtual-network.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/deploying-to-a-virtual-network.png?w=150" medium="image">
			<media:title type="html">Deploying to a Virtual Network</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting to Know #Azure Virtual Networks</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/02/15/getting-to-know-azure-virtual-networks/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/02/15/getting-to-know-azure-virtual-networks/#comments</comments>
		<pubDate>Sun, 15 Feb 2015 15:51:48 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Access Control Lists]]></category>
		<category><![CDATA[ACL]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[CIDR]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[DDoS]]></category>
		<category><![CDATA[DHCP]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[Load Balancing]]></category>
		<category><![CDATA[Network Security Groups]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Segmentation]]></category>
		<category><![CDATA[Subnet]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Virtual Network]]></category>
		<category><![CDATA[VNet]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5921</guid>
		<description><![CDATA[A Virtual Network (VNet) is a network overlay that you can configure in Azure. Virtual Machines and Services that are part of the same Virtual Network can access each other. However, services outside the virtual network have no way to identify or connect to services hosted within virtual networks unless you decide to configure that specific type of connection, as in the case of VNet to VNet configurations.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5921&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/02/15/getting-to-know-azure-virtual-networks/" target="_blank" title="Getting to Know #Azure Virtual&nbsp;Networks"><img width="580" height="385" src="https://alexandrebrisebois.files.wordpress.com/2015/02/92e6c8b649650126b3dad3ccf657600c.jpg?w=580" class="attachment-large wp-post-image" alt="92e6c8b649650126b3dad3ccf657600c" /></a></p><h1>Why are Virtual Networks Important?</h1>
<p>As a developer, I used to forget about Virtual Networks. And to be fair, I shied away from pretty much everything that can be considered as infrastructure.</p>
<p>Microsoft Azure is a game changer! It requires Developers and IT Pros to collaborate on projects. Let&#8217;s take a moment to set things right. Developers and IT Pros are not competing against each other in this new world. They collaborate in order to produce value for the business and customers.</p>
<p>As we move to a Cloud First and Mobile First world, security is more important than it ever was. On Microsoft Azure, the first step towards securing your application resources is to create a Virtual Network.<span id="more-5921"></span></p>
<p>Microsoft Azure is constantly evolving and augmenting its security. Everything starts at the edge of the public Internet. This is where mechanisms like DDoS protection kick in. Then traffic is routed through multiple network layers and finally reaches public Endpoints that are configured on Cloud Services.</p>
<p>Cloud Services are containers. Like a firewall, they protect resources such as Roles and Virtual Machines from the outside world. They provide our resources with an internal network. At this point, it&#8217;s important to note that Cloud Services can contain up to 25 Roles. However, it is recommended to apply the Single Responsibility Rule (SRP) and to keep the Role count low. This helps reduce accidental complexity when it comes to deployments and maintenance.</p>
<p>Since Cloud Services are internal networks shielded from the&nbsp;outside world, they communicate&nbsp;over public Endpoints. The diagram below illustrates a 3-tier Cloud Service that is accessible&nbsp;from the outside world.</p>
<img class="aligncenter size-full wp-image-5930" src="https://alexandrebrisebois.files.wordpress.com/2015/02/tiered-cloud-service.png?w=580" alt="Tiered Cloud Service"   />
<p>Each tier is discoverable and accessible from the public Internet. In some scenarios, this can be favorable. However, it can be considered&nbsp;as an attack vector.</p>
<p>In order to secure our applications, best practices recommend the use of Virtual Networks and Subnets. As shown below, we can take advantage of<a href="http://azure.microsoft.com/blog/2014/11/04/network-security-groups/" target="_blank"> Network Security Groups </a>(NSG)&nbsp;and <a href="https://msdn.microsoft.com/en-us/library/azure/dn376541.aspx" target="_blank">Access Control Lists</a> (ACL) to control network traffic.</p>
<img class="aligncenter size-full wp-image-5935" src="https://alexandrebrisebois.files.wordpress.com/2015/02/tiered-cloud-servive-with-virtual-network.png?w=580&#038;h=489" alt="Tiered Cloud Servive with Virtual Network" width="580" height="489" />
<p>This diagram illustrates that a Front End tier of an application is accessible from the public Internet. It also shows that the Middle tier is only accessible from the Front End and that access to the Back End is limited to the Middle tier.</p>
<h2>Getting to Know Azure Virtual Networks (VNet)</h2>
<h3>What is a Virtual Network (VNet)</h3>
<blockquote><p>A Virtual Network (VNet) is a network overlay that you can configure in Azure. Virtual Machines and Services that are part of the same Virtual Network can access each other. However, <strong>services outside the virtual network have no way to identify or connect to services hosted within virtual networks unless you decide to configure that specific type of connection</strong>, as in the case of VNet to VNet configurations. This provides an added layer of isolation to your services. Azure Virtual Network also lets you extend your network into Azure and treat deployments as a natural extension to your on-premises network.</p></blockquote>
<h3>Take Notice</h3>
<p>Virtual Machines and Cloud Services acquire their network settings during deployment. This means you can’t move something into a Virtual Network&nbsp;if it is already deployed. <strong>In order to move a deployed resource into a Virtual Network, you need redeploy it</strong>.</p>
<h3>When Do You Need A Virtual Networks (VNet)?</h3>
<p>Whether you need a Virtual Network depends entirely on what you are trying to do. Azure currently supports two categories of Virtual Networks. The first is a Cloud-Only Virtual Network. And the second is a Cross-Premises Virtual Network (Hybrid Cloud Solutions). If you start with a Cloud-Only Virtual Network, you can convert it to a Cross-Premises Virtual Network. Going through a migration from no Virtual Network to a Cross-Premises Virtual Network can be painful and incur unwanted downtime.</p>
<p>The major advantage of starting with the Virtual Network is flexibility. You can create multi-site configurations, VNet to VNet configurations, ExpressRoute connections, and combinations of multiple configuration types.</p>
<h4>Considerations for Using a Virtual Network (VNet)</h4>
<ul>
<li><strong>Name Resolution (DNS</strong>) &#8211; If you want to connect to your Virtual Machines and Cloud Services by hostname or SRV records, rather than using the IP address, you need a&nbsp;<a href="https://msdn.microsoft.com/en-us/library/azure/jj156088.aspx" target="_blank">Name Resolution</a> (DNS).</li>
<li><strong>Enhanced Security and Isolation</strong> &#8211; Only virtual machines and services that are part of the same network can access each other.</li>
<li><strong>Extended Trust and Security Boundary</strong> &#8211; Extends the trust boundary from a single service to the virtual network boundary.</li>
<li><strong>Extend Your On-Premises Network to the Cloud</strong> &#8211; Leverage all on-premises investments around monitoring and identity for your services hosted in Azure.</li>
<li><strong>User persistent Private IP Addresses</strong> &#8211; Virtual machines within a Virtual Network will have a stable private IP address. Virtual Machines can be configured with a Static Internal IP. However, if you decide to use this feature it is recommended that you separate Virtual Machines that have static DIPs from PaaS instances by creating separate subnets.</li>
<li><strong>Internal Load Balancing</strong>&nbsp;&#8211; Enables scenarios like Highly Available (HA) line of business (LOB) apps&nbsp;and&nbsp;SQL Always On.</li>
</ul>
<h2>Using PowerShell to Create a Virtual Network</h2>
<p>To create a Microsoft Azure Virtual Network, we must start by creating a Network Configuration File. Referring to the <a href="https://msdn.microsoft.com/library/azure/jj157100" target="_blank">Virtual Network Configuration Schema</a> I created the following XML configuration File.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;NetworkConfiguration xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration&quot;&gt;
  &lt;VirtualNetworkConfiguration&gt;
    &lt;Dns /&gt;
    &lt;VirtualNetworkSites&gt;
      &lt;VirtualNetworkSite name=&quot;AzureVNet&quot; Location=&quot;East US 2&quot;&gt;
        &lt;AddressSpace&gt;
          &lt;AddressPrefix&gt;10.0.0.0/24&lt;/AddressPrefix&gt;
        &lt;/AddressSpace&gt;
        &lt;Subnets&gt;
          &lt;Subnet name=&quot;FrontEnd&quot;&gt;
            &lt;AddressPrefix&gt;10.0.0.0/27&lt;/AddressPrefix&gt;
          &lt;/Subnet&gt;
          &lt;Subnet name=&quot;MiddleTier&quot;&gt;
            &lt;AddressPrefix&gt;10.0.0.32/27&lt;/AddressPrefix&gt;
          &lt;/Subnet&gt;
          &lt;Subnet name=&quot;BackEnd&quot;&gt;
            &lt;AddressPrefix&gt;10.0.0.64/27&lt;/AddressPrefix&gt;
          &lt;/Subnet&gt;
        &lt;/Subnets&gt;
      &lt;/VirtualNetworkSite&gt;
    &lt;/VirtualNetworkSites&gt;
  &lt;/VirtualNetworkConfiguration&gt;
&lt;/NetworkConfiguration&gt;
</pre>
<p>Subnets are defined within the Virtual Network&#8217;s Address Space. Make sure to give yourself enough room to grow. Address Prefixes are used to define available IPs for each subnet. To create a new Subnet on a deployed Virtual Network, export the current Virtual Network Configuration from your Azure Subscription and add a new node to the Subnets XML node. Then import the configuration back to your Azure Subscription through PowerShell or the Azure Management Portal.</p>
<p>Azure Virtual Networks use the <a href="http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" target="_blank">CIDR notation</a> to define Usable Address Ranges.</p>
<blockquote><p>CIDR notation is a compact representation of an IP address and its associated routing prefix. The notation is constructed from the IP address and the prefix size, the latter being equivalent to the number of leading 1 bits in the routing prefix mask. The IP address is expressed according to the standards of IPv4 or IPv6. It is followed by a separator character, the slash (&#8216;/&#8217;) character, and the prefix size expressed as a decimal number.</p>
<p>The address may denote a single, distinct interface address or the beginning address of an entire network. The maximum size of the network is given by the number of addresses that are possible with the remaining, least-significant bits below the prefix. This is often called the host identifier.</p>
<p>For example, &#8216;192.168.100.0/24&#8242; represents the given IPv4 address and its associated routing prefix 192.168.100.0, or equivalently, its subnet mask 255.255.255.0, which has 24 leading 1-bits.</p></blockquote>
<p><strong>For those who are not comfortable with the <a href="http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" target="_blank">CIDR notation</a>, The Azure team has provided us with detailed dropdown menus to guide us through this configuration.</strong></p>
<p>I saved the above XML configuration as <strong>C:\demo\AzureVNet.netcfg</strong>. Then Using PowerShell, I setup the proper PowerShell console context and applied the Virtual Network configurations to my subscription.</p>
<pre class="brush: powershell; title: ; notranslate">
# Switch to Azure Service Management

Switch-AzureMode -Name AzureServiceManagement

# Refresh Credentials

Add-AzureAccount

# Select Subscription

$subscriptions = Get-AzureSubscription

# Select the first Subscription
# (I did not specify my target Subscription for this demo)

$firstSubscription = $subscriptions `
                        | Select-Object -First 1 `
                                        -Verbose

# Select the Azure Subscrition and set it as Default

Select-AzureSubscription -SubscriptionId $firstSubscription.SubscriptionId `
                         -Default `
                         -Verbose

# Create Virtual Network 

Set-AzureVNetConfig -ConfigurationPath 'C:\demo\AzureVNet.netcfg' `
                    -Verbose
</pre>
<p>Once the command completes, I navigated to the Azure Management Portal and was able to verify that everything had been created.</p>
<img class="aligncenter size-full wp-image-5981" src="https://alexandrebrisebois.files.wordpress.com/2015/02/created-virtual-network.png?w=580&#038;h=346" alt="Created Virtual Network" width="580" height="346" />
<h3>Take Notice</h3>
<p>Using the <strong>Set-AzureVNetConfig</strong> from PowerShell will replace all the Virtual Networks associated with your subscription and apply the new configurations present in the Network Configuration File.</p>
<h2>Best Practices</h2>
<ul>
<li>Use Subnets to&nbsp;create multi-tier typologies</li>
<li>Control flow over Network Segments using Network Security Groups</li>
<li>Use Access Control Lists (ACL) to filter conditions with allow / deny</li>
<li>Configure internal Load Balancing for Highly Available tiers</li>
<li>RDP to internal endpoints for added security</li>
<li>Design Virtual Networks with the following in mind
<ul>
<li>Maximum of&nbsp;2048&nbsp;machines (Virtual Machines and Web/Worker role instances).</li>
<li>500 000 concurrent TCP connections for a virtual machine or role instance.</li>
<li>50&nbsp;Access Control Lists (ACLs) per endpoint.</li>
<li>10&nbsp;local network sites per Virtual Network.</li>
<li>Each Virtual Network supports a single <a href="http://msdn.microsoft.com/en-us/library/azure/jj156210.aspx" target="_blank">virtual network gateway</a>.</li>
</ul>
</li>
</ul>
<h2>More Resources</h2>
<p>Be sure to read through the&nbsp;<a href="https://msdn.microsoft.com/en-us/library/azure/dn133803.aspx" target="_blank">Virtual Network FAQ</a>, you&#8217;ll find answers to most of your queries. Then go though these additional resources for more in depth information.</p>
<ul>
<li><a href="http://azure.microsoft.com/en-us/documentation/articles/azure-subscription-service-limits/" target="_blank">Azure Subscription and Service Limits, Quotas, and Constraints</a></li>
<li><a href="https://msdn.microsoft.com/library/azure/jj156007.aspx" target="_blank">Virtual Network Overview</a></li>
<li><a href="http://go.microsoft.com/fwlink/?LinkId=296826" target="_blank">Azure Networking Guidance</a></li>
<li><a href="http://channel9.msdn.com/Events/Microsoft-Azure/Level-Up-Azure-IaaS-for-IT-Pros/Designing-Networking-and-Hybrid-Connectivity-Infrastructure" target="_blank">Designing Networking and Hybrid Connectivity Infrastructure</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/dn133798.aspx" target="_blank">About Secure Cross-Premises Connectivity</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/jj156206.aspx" target="_blank">Virtual Network Configuration Tasks</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/jj157100.aspx" target="_blank">Azure Virtual Network Configuration Schema</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/dn848316.aspx" target="_blank">How does a Network Security Group Work</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/dn376541.aspx" target="_blank">About Network Access Control Lists (ACLs)</a></li>
<li><a href="https://msdn.microsoft.com/library/azure/dn133792.aspx" target="_blank">Configure a Point-to-Site VPN</a></li>
<li><a href="https://msdn.microsoft.com/library/azure/dn630228.aspx" target="_blank">Configure a Static Internal IP Address for a Virtual Machine</a></li>
<li><a href="https://msdn.microsoft.com/en-us/library/azure/dn631643.aspx" target="_blank">Configure a Cloud-Only Virtual Network in the Management Portal</a></li>
<li><a href="http://azure.microsoft.com/blog/2014/10/29/networking-enterprise/" target="_blank">General Availability of Network Security Groups</a></li>
<li><a href="http://azure.microsoft.com/blog/2014/11/04/network-security-groups/" target="_blank">Great Blog Post about Network Security Groups</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/access-control-lists/'>Access Control Lists</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/acl/'>ACL</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/best-practices/'>Best Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cidr/'>CIDR</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/ddos/'>DDoS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dhcp/'>DHCP</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dns/'>DNS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/load-balancing/'>Load Balancing</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/network-security-groups/'>Network Security Groups</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/security/'>Security</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/segmentation/'>Segmentation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/subnet/'>Subnet</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-network/'>Virtual Network</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/vnet/'>VNet</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/xml/'>XML</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5921/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5921/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5921/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5921/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5921/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5921/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5921/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5921/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5921/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5921/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5921/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5921/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5921/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5921/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5921&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/02/15/getting-to-know-azure-virtual-networks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/02/92e6c8b649650126b3dad3ccf657600c.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/92e6c8b649650126b3dad3ccf657600c.jpg?w=150" medium="image">
			<media:title type="html">92e6c8b649650126b3dad3ccf657600c</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/tiered-cloud-service.png" medium="image">
			<media:title type="html">Tiered Cloud Service</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/tiered-cloud-servive-with-virtual-network.png" medium="image">
			<media:title type="html">Tiered Cloud Servive with Virtual Network</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/created-virtual-network.png" medium="image">
			<media:title type="html">Created Virtual Network</media:title>
		</media:content>
	</item>
		<item>
		<title>Moving to #Azure &#8211; Find The Closest #Azure Data Center</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/02/11/moving-to-azure-find-the-closest-azure-data-center/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/02/11/moving-to-azure-find-the-closest-azure-data-center/#comments</comments>
		<pubDate>Wed, 11 Feb 2015 11:00:47 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Azure Storage]]></category>
		<category><![CDATA[Blobs Storage]]></category>
		<category><![CDATA[CDN]]></category>
		<category><![CDATA[Data Center]]></category>
		<category><![CDATA[Dev & Test]]></category>
		<category><![CDATA[Latency]]></category>
		<category><![CDATA[Ping]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5900</guid>
		<description><![CDATA[pick the Data Center that is nearest to your users<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5900&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/02/11/moving-to-azure-find-the-closest-azure-data-center/" target="_blank" title="Moving to #Azure &#8211; Find The Closest #Azure Data&nbsp;Center"><img width="580" height="254" src="https://alexandrebrisebois.files.wordpress.com/2015/02/blob-latency.png?w=580" class="attachment-large wp-post-image" alt="blob-latency" /></a></p><h1>Find The Closest #Azure Data Center</h1>
<p>I regularly get asked about how to choose a Microsoft Azure Data Center for optimal deployments. The answer is to <strong>pick the Data Center that is nearest to your users</strong>. For applications that have a broad user base, it&#8217;s favorable to <strong>deploy multiple instances</strong> of the application and to <strong>use Microsoft Azure Traffic Manager</strong> to direct users to the closest Data Center. This typically provides the best user experience.<span id="more-5900"></span></p>
<p>Finding that closest Data Center requires a couple of tests, because physical networks differ from location to location.</p>
<p>To get a ping from my location to all the available Microsoft Azure Data Centers, I use a community tool called <a href="http://azureping.info/" target="_blank">Azure Site Ping</a> (<a href="https://github.com/nzbart/AzureSitePing" target="_blank">GitHub</a>).<br />
<img class="aligncenter size-full wp-image-5910" src="https://alexandrebrisebois.files.wordpress.com/2015/02/data-center-latency.png?w=580" alt="data center latency"   />Then, to compare the <strong>Azure Blob Storage</strong> response time from multiple Microsoft Azure Data Centers, I use another community tool called <a href="http://azurespeedtest.azurewebsites.net/" target="_blank">Microsoft Azure Speed Test</a>. This tool produces a chart (see featured image of this post) that allows us to visualize and understand the variance in latency.</p>
<p>Armed with this information, I can identify a Data Center. In some scenarios, the Data Center that appears to be the nearest, may not be the closest to the application&#8217;s users. Just to be sure, run these tools from locations where your users will consume your application. This will help you identify the best Data Center for your scenario.</p>
<p>Remember, it&#8217;s acceptable to deploy to one Data Center for Dev &amp; Test scenarios and to deploy to another Data Center for Production. Latency obeys the laws of physics, and we need to take them under consideration when we make choices that can affect the overall user experience.</p>
<p>When you can&#8217;t get close enough to your users with <strong>Azure Blog Storage</strong>, consider using the <strong>Azure Content Delivery Network</strong> (CDN). This service is composed of many Edge Nodes that place your content closer to your users.</p>
<p>Ultimately, the bottom line is that when latency is low, users are happy.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/azure-storage/'>Azure Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blobs-storage/'>Blobs Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cdn/'>CDN</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/data-center/'>Data Center</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dev-test/'>Dev &amp; Test</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/latency/'>Latency</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/ping/'>Ping</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5900/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5900/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5900/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5900&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/02/11/moving-to-azure-find-the-closest-azure-data-center/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/02/blob-latency.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/blob-latency.png?w=150" medium="image">
			<media:title type="html">blob-latency</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/data-center-latency.png" medium="image">
			<media:title type="html">data center latency</media:title>
		</media:content>
	</item>
		<item>
		<title>Using #PowerShell to Upload Content to #Azure Storage</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/02/03/using-powershell-to-upload-content-to-azure-storage/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/02/03/using-powershell-to-upload-content-to-azure-storage/#comments</comments>
		<pubDate>Wed, 04 Feb 2015 00:00:00 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Azure Storage]]></category>
		<category><![CDATA[Blob]]></category>
		<category><![CDATA[Blobs Storage]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5877</guid>
		<description><![CDATA[I use Azure Blobs on a regular basis. They're generally really useful and help me through some tough situations. Working with Blobs is simple. You can interact with them using Visual Studio, third party tools, REST and even through PowerShell.

The following PowerShell command demonstrates how I upload content to Azure Storage.
<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5877&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/02/03/using-powershell-to-upload-content-to-azure-storage/" target="_blank" title="Using #PowerShell to Upload Content to #Azure&nbsp;Storage"><img width="580" height="285" src="https://alexandrebrisebois.files.wordpress.com/2015/02/star-forming_region_s106_captured_by_the_hubble_space_telescope.jpg?w=580" class="attachment-large wp-post-image" alt="Star-forming_region_S106_(captured_by_the_Hubble_Space_Telescope)" /></a></p><h1>Uploading Content to Azure Blobs</h1>
<p>I use Azure Blobs on a regular basis. They&#8217;re generally really useful and help me through some tough situations. Working with Blobs is simple. You can interact with them using Visual Studio, third-party tools, REST and even through PowerShell.</p>
<p>The following PowerShell command demonstrates how I upload content to Azure Storage.</p>
<pre class="brush: powershell; title: ; notranslate">
Set-BlobContent -StorageAccountName 'scaleupdowndemopkgs' `
                -StorageContainer 'packages' `
                -FilePath 'C:\Service\cloud_package.cspkg' `
                -BlobName 'extra_small_vm_cloud_package.cspkg'
</pre>
<p><span id="more-5877"></span></p>
<p>The following is the the PowerShell function invoked in the previous example. It finds your Azure Storage keys and creates a Blob Storage Container is it does not already exist. Then it uploads the contents of the provided file path to an Azure Blob.</p>
<pre class="brush: powershell; title: ; notranslate">
function Set-BlobContent
{
    Param
    (
        [Parameter(Mandatory=$true)]
        [string]
        $StorageAccountName,
 
        [Parameter(Mandatory=$true)]
        [string]
        $StorageContainer,
 
        [Parameter(Mandatory=$true)]
        [string]
        $FilePath,
 
        [Parameter(Mandatory=$true)]
        [string]
        $BlobName
    )
 
    # Setup the Storage Context used for Storage Operations
 
    $AccountKeys = Get-AzureStorageKey -StorageAccountName $StorageAccountName `
                                       -Verbose `
                                       -WarningAction Stop `
                                       -ErrorVariable $e `
 
    $StorageContext = New-AzureStorageContext -StorageAccountName $StorageAccountName `
                                              -StorageAccountKey $AccountKeys.Primary `
                                              -Verbose `
                                              -WarningAction Stop `
                                              -ErrorVariable $e `
 
    try
    {
        Write-Verbose('Try create Container')
        $newcontainer = New-AzureStorageContainer -Context $StorageContext `
                                              -Container $StorageContainer `
                                              -Verbose `
                                              -WarningAction Ignore `
                                              -ErrorVariable $e `
    }
    catch
    {
        Write-Verbose('Container already exists')
    }
 
    # Upload and rename the Cloud Service package to Blob Storage
 
    Set-AzureStorageBlobContent -File $FilePath `
                                -Container $StorageContainer `
                                -Context $StorageContext `
                                -Blob $BlobName `
                                -Force `
                                -Verbose `
                                -WarningAction Stop `
                                -ErrorVariable $e `
}
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/azure-storage/'>Azure Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blob/'>Blob</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blobs-storage/'>Blobs Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5877/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5877/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5877/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5877/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5877/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5877/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5877/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5877/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5877/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5877/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5877/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5877/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5877/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5877/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5877&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/02/03/using-powershell-to-upload-content-to-azure-storage/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/02/star-forming_region_s106_captured_by_the_hubble_space_telescope.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/star-forming_region_s106_captured_by_the_hubble_space_telescope.jpg?w=150" medium="image">
			<media:title type="html">Star-forming_region_S106_(captured_by_the_Hubble_Space_Telescope)</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Saving #Azure Resource Manager Templates to JSON files on disk</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/02/02/saving-azure-resource-manager-templates-to-json-files-on-disk/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/02/02/saving-azure-resource-manager-templates-to-json-files-on-disk/#comments</comments>
		<pubDate>Mon, 02 Feb 2015 16:00:48 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Download]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Resource Manager]]></category>
		<category><![CDATA[Resources]]></category>
		<category><![CDATA[Template]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5875</guid>
		<description><![CDATA[If you are creating a brand new environment on Azure, you should be using <a href="http://azure.microsoft.com/en-us/documentation/articles/powershell-azure-resource-manager/" target="_blank">Windows PowerShell and Resource Manager</a>.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5875&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/02/02/saving-azure-resource-manager-templates-to-json-files-on-disk/" target="_blank" title="Saving #Azure Resource Manager Templates to JSON files on&nbsp;disk"><img width="580" height="293" src="https://alexandrebrisebois.files.wordpress.com/2015/02/d1d15bddf7b3d0c63d2f0822d02918ed.jpg?w=580" class="attachment-large wp-post-image" alt="d1d15bddf7b3d0c63d2f0822d02918ed" /></a></p><h1>Saving Microsoft ARM Templates as JSON files on disk</h1>
<p>If you are creating a brand new environment on Azure, you should be using <a href="http://azure.microsoft.com/en-us/documentation/articles/powershell-azure-resource-manager/" target="_blank">Windows PowerShell and Resource Manager</a>. Instead of creating and managing individual resources, use a template (resource model) to create a resource group that has the resources need to support your service. You can create your own templates or pick a template from the gallery.</p>
<p>If you&#8217;re starting off with the Azure Resource Manager (ARM), I recommend taking a look at what others have published. Then modify them to create a resource model that represents your service.<span id="more-5875"></span></p>
<p>The following code will download the Azure Resource Manager (ARM) templates that are published and maintained by Microsoft.</p>
<pre class="brush: powershell; title: ; notranslate">
Switch-AzureMode -Name AzureResourceManager
 
New-Item -path 'C:\Azure\Templates\' -type directory -Force

$microsoftTemplates = Get-AzureResourceGroupGalleryTemplate -Publisher 'Microsoft'
 
foreach ($item in $microsoftTemplates)
{
    $identity = $item.'Identity'
 
    Save-AzureResourceGroupGalleryTemplate -Identity $identity `
             -Path C:\Azure\Templates\ `
             -Force `
             -Verbose
}
</pre>
<p><strong>NB: be sure that &#8216;C:\Azure\Templates\&#8217; exists before running this script.</strong></p>
<p>This list is growing fast. Microsoft is adding new features on a regular basis. And there&#8217;s no better way to learn, than to look at what&#8217;s already out there.</p>
<h2>Next Steps</h2>
<p>To learn more about using Windows PowerShell with Resource Manager:</p>
<ul>
<li><a title="" href="http://go.microsoft.com/fwlink/?linkid=394765&amp;clcid=0x409">Azure Resource Manager Cmdlets</a>: Learn to use the cmdlets in the AzureResourceManager module.</li>
<li><a title="" href="http://azure.microsoft.com/en-us/documentation/articles/azure-preview-portal-using-resource-groups">Using Resource groups to manage your Azure resources</a>: Learn how to create and manage resource groups in the Azure Management Portal.</li>
<li><a title="" href="http://www.windowsazure.com/en-us/documentation/articles/xplat-cli-azure-resource-manager/">Using the Azure Cross-Platform Command-Line Interface with the Resource Manager</a>: Learn how to create and manage resource groups with command-line tools that work on many operating system platforms.</li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/architecture/'>Architecture</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/arm/'>ARM</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/best-practices/'>Best Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/devops/'>DevOps</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/download/'>Download</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/json/'>JSON</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/resource-manager/'>Resource Manager</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/resources/'>Resources</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/template/'>Template</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5875/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5875/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5875/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5875/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5875/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5875/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5875/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5875/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5875/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5875/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5875/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5875/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5875/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5875/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5875&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/02/02/saving-azure-resource-manager-templates-to-json-files-on-disk/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/02/d1d15bddf7b3d0c63d2f0822d02918ed.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/02/d1d15bddf7b3d0c63d2f0822d02918ed.jpg?w=150" medium="image">
			<media:title type="html">d1d15bddf7b3d0c63d2f0822d02918ed</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Finding an Invisible NAS on a Network</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/01/14/finding-an-invisible-nas-on-a-network/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/01/14/finding-an-invisible-nas-on-a-network/#comments</comments>
		<pubDate>Wed, 14 Jan 2015 21:00:01 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Support]]></category>
		<category><![CDATA[DHCP]]></category>
		<category><![CDATA[HDD]]></category>
		<category><![CDATA[IP Address]]></category>
		<category><![CDATA[MAC Address]]></category>
		<category><![CDATA[NAS]]></category>
		<category><![CDATA[Network]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[RJ45]]></category>
		<category><![CDATA[Static IP]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5841</guid>
		<description><![CDATA[I finally located the invisible device and the lesson I'm pulling from this adventure, is that using DHCP Reservations easier to diagnose than forgotten Static IPs.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5841&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/01/14/finding-an-invisible-nas-on-a-network/" target="_blank" title="Finding an Invisible NAS on a&nbsp;Network"><img width="580" height="312" src="https://alexandrebrisebois.files.wordpress.com/2015/01/2015-01-13_14-25-09.png?w=580" class="attachment-large wp-post-image" alt="missing! Lost! Gone!" /></a></p><h1>Finding an Invisible NAS on a Network</h1>
<p>Over the weekend I decided&nbsp;to migrate data from an older&nbsp;NAS (Network Attached Storage) device to a newer device. So I plugged in the new NAS and set it up with two brand new HDDs. Provisioned a RAID 1 (Mirror) and finally I secured the device with a better password than &#8220;<strong>blank</strong>&#8220;.</p>
<p>Plugging in the older device, I expected that it would show up in Windows Explorer, but it did not. I spent the next couple hours trying to figure out why I could not find the device&#8217;s IP. I connected to my router, looked at the DHCP map and it wasn&#8217;t showing up.</p>
<p>Obviously, I hadn&#8217;t used the device for some time and had forgotten the devices name. So here I was, with no IP or Name for the device. The RJ45 plugged in and the flashing lights telling me that something was going on&#8230;<span id="more-5841"></span></p>
<p>In trying to find the device, I started to set up meaningful DHCP Reservations for all known devices my network. Surprisingly, I found myself adding more devices than I was expecting. This was an eye opener, but left me in the cold. The NAS was still invisible.</p>
<p>Having spent about an hour creating DHCP Reservations by finding the <a href="http://en.wikipedia.org/wiki/MAC_address" target="_blank">MAC Address</a> of each device, I went ahead and created a new reservation for the NAS device. Fortunately, most network devices like routers, have a hard copy of their MAC Address printed on a label. The new reservation assigned 192.168.1.153 as the IP Address for my NAS device.</p>
<p>I proceeded by rebooting both my router and the NAS device. Then I executed the following in a Command Prompt.</p>
<pre class="brush: plain; title: ; notranslate">
NET VIEW \\192.168.1.153
</pre>
<p>Seeing the following output put a huge smile on my face, because I finally had a known IP for my NAS device.</p>
<pre class="brush: plain; title: ; notranslate">
Shared resources at 192.168.1.153

DNS-325

Share name  Type   Used as  Comment

--------------------------------------------
lp          Print           USB Printer
Volume_1    Disk
The command completed successfully.
</pre>
<p>I was then able to map the network drive by using this new address <strong>\\192.168.1.153\Volume_1</strong>. Then using the same IP Address, I browsed to the device&#8217;s admin website. Out of curiosity I tried to find the cause and this is when I realized that I had previously configured the device with a <strong>Static IP</strong>. I had forgotten the device&#8217;s name and IP. </p>
<p>The lesson I&#8217;m pulling from this adventure, is that using DHCP Reservations easier to diagnose than forgotten Static IPs.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/support/'>Support</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/dhcp/'>DHCP</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/hdd/'>HDD</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/ip-address/'>IP Address</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/mac-address/'>MAC Address</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/nas/'>NAS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/network/'>Network</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/networking/'>Networking</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/rj45/'>RJ45</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/static-ip/'>Static IP</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5841/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5841/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5841/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5841/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5841/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5841/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5841/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5841/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5841/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5841/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5841/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5841/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5841/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5841/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5841&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/01/14/finding-an-invisible-nas-on-a-network/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/01/2015-01-13_14-25-09.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/01/2015-01-13_14-25-09.png?w=150" medium="image">
			<media:title type="html">missing! Lost! Gone!</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Securing Production #Azure SQL Databases</title>
		<link>https://alexandrebrisebois.wordpress.com/2015/01/08/securing-production-azure-sql-databases/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2015/01/08/securing-production-azure-sql-databases/#comments</comments>
		<pubDate>Thu, 08 Jan 2015 17:00:34 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Firewall]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Rules]]></category>
		<category><![CDATA[Schema]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[SQL Database]]></category>
		<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[Users]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5793</guid>
		<description><![CDATA[Although we try to be vigilant, we are human and can forget to remove unnecessary firewall rules. These rules, become attack vectors that can be leverage against our application and we should proactively do everything we can to reduce potential risks. This vulnerability can affect business continuity in two ways. The first is a malicious attack meant to steal or destroy data. The second way business continuity can be affected is by human error. Imagine for a moment that a developer updates a database and targets the production database by mistake, the results can be disastrous. Rolling back isn't always possible and downtime can be costly. <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5793&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2015/01/08/securing-production-azure-sql-databases/" target="_blank" title="Securing Production #Azure SQL&nbsp;Databases"><img width="580" height="277" src="https://alexandrebrisebois.files.wordpress.com/2015/01/servers.png?w=580" class="attachment-large wp-post-image" alt="servers" /></a></p><h2>The Challenge</h2>
<p>As developers, we are up against odds that push us to make trade-offs in order to go into production on time. More often than not, it’s a race where security becomes an afterthought.</p>
<h1>Securing Azure SQL Databases</h1>
<p>Security mechanisms come in many flavors. It is a requirement that needs to be defined and implemented on day 1. These rituals (policies and practices), must become natural in your application life cycle management. <strong>Consider these as a starting point from which you can develop your own security practices</strong>.</p>
<ul>
<li>Do not use the default user for development, testing or for deployments
<ul>
<li>Create a user specifically for deployments (can perform schema alterations)</li>
<li>Create a user on a per application basis (cannot alter schema and has limited write access)</li>
<li>Create a user for support investigations (this should be read-only)</li>
<li>Create individual accounts for members of DevOps who will need to act upon the database. (these accounts should have limited write access)</li>
</ul>
</li>
<li>Reference data should be read-only (immutable versions) and should only be updated through deployments. This type of data can be stored in NoSQL data services to augment the overall scalability of your application.</li>
<li><a href="http://azure.microsoft.com/en-us/documentation/articles/sql-database-auditing-get-started/" target="_blank">Enable Auditing for Azure SQL Database</a>, this feature will give you deep insight in how the database is manipulated and&nbsp;about how it is&nbsp;used.</li>
<li><a href="https://alexandrebrisebois.wordpress.com/2013/07/20/take-control-windows-azure-sql-database-application-life-cycle-management-made-easy/" target="_blank">Use SQL Database Projects to design, build, version and deploy</a></li>
<li>Use schemas to segregate tenants, reference data, activity data and resouce (shared) data.</li>
<li><a href="http://weblogs.sqlteam.com/dang/archive/2008/02/09/Security-with-Ownership-Chains.aspx" target="_blank">Use schemas to keep track of ownership chaining</a></li>
<li>Encrypt&nbsp;connection string&nbsp;passwords at rest</li>
<li>Use strong passwords</li>
<li>Set <strong>Trusted_Connection=False</strong> in the&nbsp;connection string.&nbsp;This forces server certificate validation</li>
<li>Set <strong>Encrypt=True</strong> in the connection string to force the client to use SSL</li>
<li>Ensure that you are covered against <a href="http://technet.microsoft.com/en-us/library/ms161953(v=sql.105).aspx" target="_blank">SQL Injection</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/jj553530.aspx" target="_blank">SQL Database Firewall rules</a> should block everything except the consuming applications
<ul>
<li>SQL Database Firewall rules should be set on both the&nbsp;<a href="http://msdn.microsoft.com/en-us/library/azure/jj553530.aspx" target="_blank">Server and Database</a></li>
</ul>
</li>
</ul>
<p><span id="more-5793"></span></p>
<h2>Automating Azure SQL Server Firewall Rule Maintenance</h2>
<p>All too often our Azure SQL Server firewall rules are riddled with unused and forgotten entries.</p>
<p><img class="aligncenter size-large wp-image-5816" src="https://alexandrebrisebois.files.wordpress.com/2015/01/before-runbook-execution.png?w=580&#038;h=353" alt="before-runbook-execution" width="580" height="353" /><br />
Although we try to be vigilant, we are human and can forget to remove unnecessary firewall rules. These rules, become attack vectors that can be leverage against our application and we should proactively do everything we can to reduce potential risks. This vulnerability can affect business continuity in two ways. The first is a malicious attack meant to steal or destroy data. The second way business continuity can be affected is by human error. Imagine for a moment that a developer updates a database and targets the production database by mistake, the results can be disastrous. Rolling back isn&#8217;t always possible and downtime can be costly.&nbsp;On the other hand, if the Azure SQL Server firewall rules are maintained, pruned and specifically targeted at the consuming applications, developers would&nbsp;be blocked from targeting the wrong database during their development cycle. In order to update the database, developers would need to manually add a firewall rule to the Azure SQL Server and target the database.</p>
<p>Protecting SQL Database instance against human error got me thinking and I decided to write a runbook that could be schedule using Azure Automation.</p>
<pre class="brush: powershell; title: ; notranslate">
&lt;#
.Synopsis
   The purpose of this script is to maintain a clean list of firewall rules
   for Azure SQL Database Server. It will add a rule for each Role it finds
   within the targeted Cloud Service. It will update rules that are out of
   sync with the deployed cloud service. Then it will delete all unrelated rules.
.EXAMPLE
   Set-CloudServiceSqlDatabaseFirewallRules -AzureCredentialsName 'runbooks' `
                                            -SqlServerName $SqlServerName `
                                            -CloudServiceName $CloudServiceName `
                                            -DeploymentSlot Production `
                                            -Verbose
#&gt;
workflow Set-CloudServiceSqlDatabaseFirewallRules
{
    Param
    (
        [parameter(Mandatory=$true, `
                 HelpMessage = 'The name given to the Windows PowerShell Credentials located# in the Assets of this Azure Automation instance')]
        [String]
        $AzureCredentialsName,

        # Azure SQL Server name
        [parameter(Mandatory=$true, `
                 HelpMessage = 'The name of the Azure SQL Server')]
        [string]
        $SqlServerName,

        # Azure Cloud Service Name
        [parameter(Mandatory=$true, `
                 HelpMessage = 'The name of the Azure Cloud Service')]
        [string]
        $CloudServiceName,

        # Azure Cloud Service Deployment Slot
        [parameter(Mandatory=$true, `
                 HelpMessage = 'The Azure Cloud Service deployment Slot')]
        [ValidateSet('Production', 'Staging')]
        [string]
        $DeploymentSlot
    )

    $Credentials = Get-AutomationPSCredential `
                       -Name $AzureCredentialsName

    Add-AzureAccount `
       -Credential $Credentials

    $rules = Get-AzureSqlDatabaseServerFirewallRule -ServerName $SqlServerName
    'Rules Obtained from Azure SQL Server'
    $rules

    InlineScript
    {
      $instances = Get-AzureRole -ServiceName $Using:CloudServiceName -Slot $Using:DeploymentSlot -InstanceDetails `
                 | Select-Object ServiceName,  @{Name=&quot;Vip&quot;;Expression={$_.InstanceEndpoints[0].Vip}}

      $instances | `
      ForEach-Object {

        $name = $_.ServiceName

        $vip =$_.Vip

        $rule = $null

        $rules = Get-AzureSqlDatabaseServerFirewallRule -ServerName $Using:SqlServerName

        if($rules)
        {
           $rule = $rules | Where-Object {$_.RuleName -eq $name}
        }

        if($vip)
        {
          if($rule)
          {
            if($rule.StartIpAddress -ne $vip -and $rule.EndIpAddress -ne $vip)
            {
              Set-AzureSqlDatabaseServerFirewallRule -ServerName $Using:SqlServerName `
                                                     -RuleName $name `
                                                     -StartIpAddress $vip `
                                                     -EndIpAddress $vip `
                                                     -Verbose
            }
          }
          else
          {
            New-AzureSqlDatabaseServerFirewallRule -ServerName $Using:SqlServerName `
                                                   -RuleName $name `
                                                   -StartIpAddress $vip `
                                                   -EndIpAddress $vip `
                                                   -Verbose
          }
        }
      }

      $rules = Get-AzureSqlDatabaseServerFirewallRule -ServerName $Using:SqlServerName

      $rules | `
      ForEach-Object {
        $name = $_.RuleName

        $instance = $instances | Where-Object {$_.ServiceName -eq $name}

        if(!$instance)
        {
          Remove-AzureSqlDatabaseServerFirewallRule -ServerName $Using:SqlServerName `
                                                    -RuleName $name `
                                                    -Verbose
        }
      }
    }

    'Updated on Azure SQL Server'
    $rules = Get-AzureSqlDatabaseServerFirewallRule -ServerName $SqlServerName
    $rules
}
</pre>
<p>Executing this runbook on a regular schedule requires us to set up credentials and a schedule in Azure Automation Assets. My earlier post about <a title="scaling Azure Cloud Services up and down like clockwork" href="https://alexandrebrisebois.wordpress.com/2014/12/29/scaling-azure-cloud-services-up-and-down-like-clockwork/" target="_blank">scaling Azure Cloud Services up and down like clockwork</a> can help you get up and running.</p>
<p>Everytime Set-CloudServiceSqlDatabaseFirewallRules is executed, it will give you an output similar to the following. Let&#8217;s walk through the output and understand&nbsp;what we can extract from it. The first part is a list of the Azure SQL Server firewall rules prior to maintenance. Then it will list all removed and added firewalls rules. Finally it will list the updated set of Azure SQL Server firewall rules.</p>
<pre class="brush: plain; title: ; notranslate">
Rules Obtained from Azure SQL Server

RuleName       : ClientIPAddress_Alex_home
StartIpAddress : 69.130.90.185
EndIpAddress   : 69.130.90.185
ServerName     : bnv4xb0akd
PSComputerName : localhost

RuleName       : ClientIPAddress_Alex_work
StartIpAddress : 69.130.90.19
EndIpAddress   : 69.130.90.19
ServerName     : bnv4xb0akd
PSComputerName : localhost

RuleName       : console
StartIpAddress : 23.99.200.245
EndIpAddress   : 23.99.200.245
ServerName     : bnv4xb0akd
PSComputerName : localhost

1/8/2015 9:25:05 AM, Verbose: 606a4214-a079-47a8-9105-f65dc92f9e8f:[localhost]:Removing firewall rule &quot;ClientIPAddress_Alex_home&quot; for Microsoft Azure
Sql Database server &quot;bnv4xb0akd&quot;.

1/8/2015 9:25:06 AM, Verbose: 606a4214-a079-47a8-9105-f65dc92f9e8f:[localhost]:Removing firewall rule &quot;ClientIPAddress_Alex_work&quot; for Microsoft Azure
Sql Database server &quot;bnv4xb0akd&quot;.

Updated on Azure SQL Server

RuleName       : console
StartIpAddress : 23.99.200.245
EndIpAddress   : 23.99.200.245
ServerName     : bnv4xb0akd
PSComputerName : localhost
</pre>
<p>Once the runbook execution is complete, the Microsoft Azure management portal should look much cleaner. The newly created firewall rules will have the same name as the Cloud Service that they represent.<br />
<a href="https://alexandrebrisebois.files.wordpress.com/2015/01/after-runbook-execution.png"><img class="alignnone size-large wp-image-5821" src="https://alexandrebrisebois.files.wordpress.com/2015/01/after-runbook-execution.png?w=580&#038;h=301" alt="after-runbook-execution" width="580" height="301" /></a></p>
<h3>Next Steps</h3>
<p>This runbook is an example that you can use to build out your maintenance and security strategy around Azure SQL Dababase firewall rules.</p>
<p>The above runbook has short comings that need to be addressed. It does not support a scenarios where a database is shared by more than one Cloud Service. It also does not configure the database level firewall. As illustrated below, Azure SQL Databases has two levels of Firewalls and you should take advantage of this.<br />
<img class="aligncenter size-full wp-image-5827" src="https://alexandrebrisebois.files.wordpress.com/2015/01/azure-sql-database-firewalls.jpg?w=580" alt="Azure SQL Database Firewalls"   /><br />
Azure SQL Server firewall rules give access to all of its databases. If you need to restrict access to a single database within an Azure SQL Server, you will need to execute SQL commands against the Azure SQL Database. Refer to this documentation about <a title="Database-Level Firewall Rules" href="http://msdn.microsoft.com/en-us/library/azure/jj553530.aspx" target="_blank">database-level firewall rules</a>.</p>
<h2>Azure SQL Database Resources</h2>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/jj553530.aspx" target="_blank">How to: Configure Firewall Settings (Azure SQL Database)</a></li>
<li><a href="http://channel9.msdn.com/Shows/Azure-Friday/Best-Practices-for-Securing-SQL-Azure" target="_blank">Best Practices for Securing Azure SQL Database</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/ee621782.aspx">Azure SQL Database Firewall</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/ee336282.aspx">Guidelines for Connecting to Azure SQL Database</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/ee336235.aspx">Managing Databases and Logins in Azure SQL Database</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/ff394102.aspx">Azure SQL Database Guidelines and Limitations</a></li>
</ul>
<h3>TSQL Resources</h3>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dn505712.aspx">Create Firewall Rule</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dn505706.aspx">Delete Firewall Rule</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dn505698.aspx">Get Firewall Rule</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dn505715.aspx">List Firewall Rules</a></li>
</ul>
<h3>PowerShell Resources</h3>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dn546724.aspx">New-AzureSqlDatabaseServerFirewallRule</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dn546727.aspx">Remove-AzureSqlDatabaseServerFirewallRule</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dn546739.aspx">Set-AzureSqlDatabaseServerFirewallRule</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dn546731.aspx">Get-AzureSqlDatabaseServerFirewallRule</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/best-practices/'>Best Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/data/'>Data</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/firewall/'>Firewall</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/rules/'>Rules</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/schema/'>Schema</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/security/'>Security</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/sql-database/'>SQL Database</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/t-sql/'>T-SQL</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/users/'>Users</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5793/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5793/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5793/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5793/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5793/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5793/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5793/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5793/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5793/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5793/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5793/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5793/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5793/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5793/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5793&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2015/01/08/securing-production-azure-sql-databases/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2015/01/servers.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/01/servers.png?w=150" medium="image">
			<media:title type="html">servers</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/01/before-runbook-execution.png?w=580" medium="image">
			<media:title type="html">before-runbook-execution</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/01/after-runbook-execution.png?w=580" medium="image">
			<media:title type="html">after-runbook-execution</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2015/01/azure-sql-database-firewalls.jpg" medium="image">
			<media:title type="html">Azure SQL Database Firewalls</media:title>
		</media:content>
	</item>
		<item>
		<title>Scaling #Azure Cloud Services Up and Down Like Clockwork</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/12/29/scaling-azure-cloud-services-up-and-down-like-clockwork/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/12/29/scaling-azure-cloud-services-up-and-down-like-clockwork/#comments</comments>
		<pubDate>Mon, 29 Dec 2014 20:56:56 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Azure Storage]]></category>
		<category><![CDATA[Blobs Storage]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Configurations]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Roles]]></category>
		<category><![CDATA[Runbook]]></category>
		<category><![CDATA[Scale Down]]></category>
		<category><![CDATA[Scale In]]></category>
		<category><![CDATA[Scale Out]]></category>
		<category><![CDATA[Scale Up]]></category>
		<category><![CDATA[Schedule]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Worker Role]]></category>
		<category><![CDATA[Workflow]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5705</guid>
		<description><![CDATA[Using Microsoft Azure Automation to reduce operational costs by scaling Cloud Service up and down based on a schedule<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5705&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/12/29/scaling-azure-cloud-services-up-and-down-like-clockwork/" target="_blank" title="Scaling #Azure Cloud Services Up and Down Like&nbsp;Clockwork"><img width="580" height="387" src="https://alexandrebrisebois.files.wordpress.com/2014/12/8478044641_993f0a2373_z.jpg?w=580" class="attachment-large wp-post-image" alt="clock-work" /></a></p><h1>Scaling Azure Cloud Services</h1>
<p>When we build applications on the cloud, we usually favor scaling-out over scaling-up. Consequently, scaling in and out is supported out of the box on Microsoft Azure. On rare occasions, there is a business need to scale-up during peak hours and to scale-down for the quiet hours. This blog post will show you how to achieve this with the help of Microsoft Azure Automation and with PowerShell.</p>
<p>Keep in mind, that scaling up and down requires us to be creative.<span id="more-5705"></span></p>
<h2>Getting Ready</h2>
<p>Azure Cloud Services define Virtual Machine size in the <strong>ServiceDefinition.csdef</strong> file. Unfortunately this file is part of the Cloud Service package. Therefore, one needs to redeploy to scale to a different Virtual Machine size.</p>
<p>This limitation requires us to create an individual package for each Virtual Machine size that we will use to scale our Cloud Service up and down.</p>
<p>For this blog post, we will use the Cloud Service I created in my previous <a title="Lift and Shift of a Console Appication to Microsoft #Azure" href="https://alexandrebrisebois.wordpress.com/2014/12/14/lift-and-shift-of-a-console-appication-to-microsoft-azure/" target="_blank">post about deploying a Console Application to Microsoft Azure</a> to create my packages. The first package will be sized to an ExtraSmall (1 CPU, 768 MB RAM, 19 GB DISK) Virtual Machine. This will be the default deployment package. We will schedule this package to be deployed to the production slot between the hours of 8 PM and 6 AM. The second package will be sized to an ExtraLarge (8 CPU, 14 GB RAM, 2039 GB DISK) Virtual Machine. It will be deployed to the production slot of my Cloud Service between the hours of 6 AM and 8 PM.</p>
<p>To create the first package, we must edit the <strong>ServiceDefinition.csdef</strong> file and set the <strong>vmsize</strong> of the <strong>ConsoleWorkerRole</strong> to <strong>ExtraSmall</strong>. The following is the updated <strong>ServiceDefinition.csdef</strong> that we will use to created the scaled-down package.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!--?&lt;span class=&quot;hiddenSpellError&quot; pre=&quot;&quot; data-mce-bogus=&quot;1&quot;--&gt;xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
                   xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
                   name=&quot;console-lift-and-shift&quot;
                   xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition&quot;&gt;
  &lt;WorkerRole name=&quot;ConsoleWorkerRole&quot; vmsize=&quot;ExtraSmall&quot;&gt;
    &lt;Startup&gt;
      &lt;Task commandLine=&quot;setup_worker.cmd &amp;gt; log.txt&quot; executionContext=&quot;elevated&quot;&gt;
        &lt;Environment&gt;
          &lt;Variable name=&quot;EMULATED&quot;&gt;
            &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
          &lt;/Variable&gt;
          &lt;Variable name=&quot;RUNTIMEID&quot; value=&quot;&quot; /&gt;
          &lt;Variable name=&quot;RUNTIMEURL&quot; value=&quot;&quot; /&gt;
        &lt;/Environment&gt;
      &lt;/Task&gt;
      &lt;Task commandLine=&quot;.\startup.cmd &amp;gt; startup_log.txt&quot; executionContext=&quot;elevated&quot; /&gt;
    &lt;/Startup&gt;
    &lt;Endpoints&gt;
      &lt;InputEndpoint name=&quot;HttpIn&quot; protocol=&quot;tcp&quot; port=&quot;80&quot; /&gt;
    &lt;/Endpoints&gt;
    &lt;Runtime&gt;
      &lt;Environment&gt;
        &lt;Variable name=&quot;PORT&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[@name='HttpIn']/@port&quot; /&gt;
        &lt;/Variable&gt;
        &lt;Variable name=&quot;EMULATED&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
        &lt;/Variable&gt;
      &lt;/Environment&gt;
      &lt;EntryPoint&gt;
        &lt;ProgramEntryPoint commandLine=&quot;worker.cmd&quot; setReadyOnProcessStart=&quot;true&quot; /&gt;
      &lt;/EntryPoint&gt;
    &lt;/Runtime&gt;
  &lt;!--&lt;span class=&quot;hiddenSpellError&quot; pre=&quot;&quot; data-mce-bogus=&quot;1&quot;--&gt;WorkerRole&gt;
&lt;/ServiceDefinition&gt;
</pre>
<p>In order to create the scaled-down package for the Cloud Service, we must open <strong>Windows PowerShell ISE</strong> and navigat to the folder that contains the Cloud Service.</p>
<p>The Cloud Service for this blog post is at the following location:</p>
<pre class="brush: plain; title: ; notranslate">
C:\users\&lt;user id&gt;\Documents\demo-lift-and-shift\console-lift-and-shift
</pre>
<p>In the PowerShell console, we execute the following command to create a deployment package for the Cloud Service.</p>
<pre class="brush: plain; title: ; notranslate">
# Package the Cloud Service
Save-AzureServiceProjectPackage
</pre>
<p>This produces a package named <strong>cloud_package.cspkg</strong>. It is located in the folder that contains the Cloud Service.</p>
<p>Next, we must upload the <strong>cloud_package.cspkg</strong> file and the <strong>ServiceConfiguration.Cloud.cscfg</strong> file to Azure Blob Storage. This can be done from tools like Visual Studio, Azure Management Studio or PowerShell.</p>
<p>For this example, we will use PowerShell to <strong>rename</strong> and <strong>upload</strong> the Cloud Service artifacts (Package &amp; Configurations) to Azure Blob Storage.</p>
<p>In order for this to work, we need to import the publish profile from our Microsoft Azure Subscription. PowerShell will then use it to connect to Microsoft Azure.</p>
<p>In the PowerShell console, execute the following commands.</p>
<pre class="brush: powershell; title: ; notranslate">
# Opens a website that allows us to download the Publish Profile
# associated with our Microsoft Azure Subscription
Get-AzurePublishSettingsFile

# Save the publish settings files to your downloads folder
# Then import it using the following command.
Import-AzurePublishSettingsFile -PublishSettingsFile 'C:\Users\\Downloads\-credentials.publishsettings'
</pre>
<p>Then make sure to set our Azure subscription as the default subscription for the local PowerShell environment.</p>
<pre class="brush: powershell; title: ; notranslate">
Select-AzureSubscription -Default -SubscriptionName 'my subscription name'
</pre>
<p>Before we upload anything to Azure Storage, we must first make sure that we have a provisioned Storage Account.<br />
Using the following commands I will create a new Storage Account that will be used to store the Cloud Service artifacts.</p>
<pre class="brush: powershell; title: ; notranslate">
New-AzureStorageAccount -StorageAccountName 'scaleupdowndemopkgs' `
                        -Label 'scale up down demo deployment packages' `
                        -Location 'East US' `
                        -Type 'Standard_GRS' `
                        -Verbose -WarningAction SilentlyContinue `
                        -ErrorVariable $e `
</pre>
<p>Now using the following PowerShell function, we will upload the artifacts to our new Azure Storage Account.</p>
<pre class="brush: powershell; title: ; notranslate">
function Set-BlobContent
{
    Param
    (
        [Parameter(Mandatory=$true)]
        [string]
        $StorageAccountName,

        [Parameter(Mandatory=$true)]
        [string]
        $StorageContainer,

        [Parameter(Mandatory=$true)]
        [string]
        $FilePath,

        [Parameter(Mandatory=$true)]
        [string]
        $BlobName
    )

    # Setup the Storage Context that is used for Storage Operations

    $AccountKeys = Get-AzureStorageKey -StorageAccountName $StorageAccountName `
                                       -Verbose `
                                       -WarningAction Stop `
                                       -ErrorVariable $e `

    $StorageContext = New-AzureStorageContext -StorageAccountName $StorageAccountName `
                                              -StorageAccountKey $AccountKeys.Primary `
                                              -Verbose `
                                              -WarningAction Stop `
                                              -ErrorVariable $e `

    try
    {
        Write-Verbose('Try create Container')
        $newcontainer = New-AzureStorageContainer -Context $StorageContext `
                                              -Container $StorageContainer `
                                              -Verbose `
                                              -WarningAction Ignore `
                                              -ErrorVariable $e `
    }
    catch
    {
        Write-Verbose('Container already exists')
    }

    # Upload and rename the Cloud Service package to Blob Storage

    Set-AzureStorageBlobContent -File $FilePath `
                                -Container $StorageContainer `
                                -Context $StorageContext `
                                -Blob $BlobName `
                                -Force `
                                -Verbose `
                                -WarningAction Stop `
                                -ErrorVariable $e `
}
</pre>
<p>Uploading the Cloud Service package provides us with the chance to give the package file a meaningful name. For the purpose of this example, I renamed the package file to <strong>extra_small_vm_cloud_package.cspkg</strong>.</p>
<pre class="brush: powershell; title: ; notranslate">
Set-BlobContent -StorageAccountName 'scaleupdowndemopkgs' `
                -StorageContainer 'packages' `
                -FilePath 'C:\Users\\Documents\demo-lift-and-shift\console-lift-and-shift\cloud_package.cspkg' `
                -BlobName 'extra_small_vm_cloud_package.cspkg'
</pre>
<p>Then we must update the <strong>ServiceConfiguration.Cloud.cscfg</strong> file and set the instance count to <strong>1</strong>. This will allow the Cloud Service to scale-in the as it scales-down.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!--?&lt;span class=&quot;hiddenSpellError&quot; pre=&quot;&quot; data-mce-bogus=&quot;1&quot;--&gt;xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; serviceName=&quot;lift-and-shift-demo&quot; osFamily=&quot;4&quot; osVersion=&quot;*&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration&quot;&gt;
  &lt;Role name=&quot;ConsoleWorkerRole&quot;&gt;
    &lt;ConfigurationSettings /&gt;
    &lt;Instances count=&quot;1&quot; /&gt;
    &lt;Certificates /&gt;
  &lt;/Role&gt;
&lt;/ServiceConfiguration&gt;
</pre>
<p>Using the same PowerShell function we will upload the updated <strong>ServiceConfiguration.Cloud.cscfg</strong> and give it a meaningful name. For the purpose of this example, I renamed the package file to <strong>ServiceConfiguration.Scaled-In-Cloud.cscfg</strong>.</p>
<pre class="brush: powershell; title: ; notranslate">
Set-BlobContent -StorageAccountName 'scaleupdowndemopkgs' `
                -StorageContainer 'packages' `
                -FilePath 'C:\Users\\Documents\demo-lift-and-shift\console-lift-and-shift\ServiceConfiguration.Cloud.cscfg' `
                -BlobName 'ServiceConfiguration.Scaled-In-Cloud.cscfg'
</pre>
<p>To create the second package, we must edit the <strong>ServiceDefinition.csdef</strong> file and set the <strong>vmsize</strong> of the <strong>ConsoleWorkerRole</strong> to <strong>ExtraLarge</strong>. The following is the updated <strong>ServiceDefinition.csdef</strong> that will be used to created the scaled-up package.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
                   xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
                   name=&quot;console-lift-and-shift&quot;
                   xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition&quot;&gt;
  &lt;WorkerRole name=&quot;ConsoleWorkerRole&quot; vmsize=&quot;ExtraLarge&quot;&gt;
    &lt;Startup&gt;
      &lt;Task commandLine=&quot;setup_worker.cmd &amp;gt; log.txt&quot; executionContext=&quot;elevated&quot;&gt;
        &lt;Environment&gt;
          &lt;Variable name=&quot;EMULATED&quot;&gt;
            &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
          &lt;/Variable&gt;
          &lt;Variable name=&quot;RUNTIMEID&quot; value=&quot;&quot; /&gt;
          &lt;Variable name=&quot;RUNTIMEURL&quot; value=&quot;&quot; /&gt;
        &lt;/Environment&gt;
      &lt;/Task&gt;
      &lt;Task commandLine=&quot;.\startup.cmd &amp;gt; startup_log.txt&quot; executionContext=&quot;elevated&quot; /&gt;
    &lt;/Startup&gt;
    &lt;Endpoints&gt;
      &lt;InputEndpoint name=&quot;HttpIn&quot; protocol=&quot;tcp&quot; port=&quot;80&quot; /&gt;
    &lt;/Endpoints&gt;
    &lt;Runtime&gt;
      &lt;Environment&gt;
        &lt;Variable name=&quot;PORT&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[@name='HttpIn']/@port&quot; /&gt;
        &lt;/Variable&gt;
        &lt;Variable name=&quot;EMULATED&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
        &lt;/Variable&gt;
      &lt;/Environment&gt;
      &lt;EntryPoint&gt;
        &lt;ProgramEntryPoint commandLine=&quot;worker.cmd&quot; setReadyOnProcessStart=&quot;true&quot; /&gt;
      &lt;/EntryPoint&gt;
    &lt;/Runtime&gt;
  &lt;/WorkerRole&gt;
&lt;/ServiceDefinition&gt;
</pre>
<p>In the PowerShell console, we must execute the following command to create the deployment package for the Cloud Service.</p>
<pre class="brush: plain; title: ; notranslate">
# Package the Cloud Service
Save-AzureServiceProjectPackage
</pre>
<p>This will produce a package named <strong>cloud_package.cspkg</strong>. It will be created in the folder that contains the Cloud Service.</p>
<p>Before we upload the new package to Azure Storage, update the <strong>ServiceConfiguration.Cloud.cscfg</strong> file and set the instance count to <strong>5</strong>. This will allow the Cloud Service to scale-out as it scales-up.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; serviceName=&quot;lift-and-shift-demo&quot; osFamily=&quot;4&quot; osVersion=&quot;*&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration&quot;&gt;
  &lt;Role name=&quot;ConsoleWorkerRole&quot;&gt;
    &lt;ConfigurationSettings /&gt;
    &lt;Instances count=&quot;5&quot; /&gt;
    &lt;Certificates /&gt;
  &lt;/Role&gt;
&lt;/ServiceConfiguration&gt;
</pre>
<p>Uploading the Cloud Service package provides us with the chance to give the package file a meaningful name. For the purpose of this example, I renamed the package file to <strong>extra_large_vm_cloud_package.cspkg</strong>. I also renamed the updated <strong>ServiceConfiguration.Cloud.cscfg</strong> to <strong>ServiceConfiguration.Scaled-Out-Cloud.cscfg</strong>.</p>
<pre class="brush: powershell; title: ; notranslate">
Set-BlobContent -StorageAccountName 'scaleupdowndemopkgs' `
                -StorageContainer 'packages' `
                -FilePath 'C:\Users\\Documents\demo-lift-and-shift\console-lift-and-shift\cloud_package.cspkg' `
                -BlobName 'extra_large_vm_cloud_package.cspkg'

Set-BlobContent -StorageAccountName 'scaleupdowndemopkgs' `
                -StorageContainer 'packages' `
                -FilePath 'C:\Users\\Documents\demo-lift-and-shift\console-lift-and-shift\ServiceConfiguration.Cloud.cscfg' `
                -BlobName 'ServiceConfiguration.Scaled-Out-Cloud.cscfg'
</pre>
<h2>Automate and Schedule!</h2>
<blockquote><p><a href="http://azure.microsoft.com/en-us/documentation/services/automation/" target="_blank">Microsoft Azure Automation</a> is all about automating frequent, time-consuming, and error-prone cloud management tasks. Azure Automation helps you spend more of your time focused on work that adds business value. By reducing errors and boosting efficiency, it can also help <strong>lower your operational costs</strong>.</p></blockquote>
<p>Setting this up for the first time can be tricky, but don&#8217;t worry, there are some great resources that will help us overcome this challenge.</p>
<p>By default, Microsoft Azure Automation does not have access to your Azure resources. It must be configured appropriately and to do so, we should followed the steps described in <a href="http://azure.microsoft.com/blog/2014/08/27/azure-automation-authenticating-to-azure-using-azure-active-directory/" target="_blank">Azure Automation: Authenticating to Azure using Azure Active Directory</a>.</p>
<blockquote><p>Note: Those who have a <strong>microsoft.onmicrosoft.com</strong> subscription may hit a wall using this method. If you know of a workaround please share it through the comment section on this post.</p></blockquote>
<p>OK. Now we&#8217;re ready to build a Windows PowerShell workflow (runbook). Having no prior experience with runbooks, I peaked at pre-built samples from the Runbook Gallery. This Gallery allows you to browse and import runbooks to your Automation account from the Azure Management Portal. This gave me a great deal of insight as to what I was up against and got me asking a bunch of questions. Here are a few of the resources that answered most of my questions.</p>
<ul>
<li><a href="http://azure.microsoft.com/en-us/documentation/articles/automation-create-runbook-from-samples/" target="_blank">Get started with Azure Automation</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dn643629.aspx" target="_blank">Microsoft Azure Automation on MSDN</a></li>
<li><a href="http://technet.microsoft.com/en-us/library/dn469262.aspx" target="_blank">Authoring Automation Runbooks</a></li>
<li><a href="http://technet.microsoft.com/en-us/library/dn469257.aspx" target="_blank">Runbook Concepts</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dn850372.aspx" target="_blank">Runbook Execution in Azure Automation</a></li>
<li><a href="http://azure.microsoft.com/blog/2014/08/12/azure-automation-runbook-input-output-and-nested-runbooks/" target="_blank">Azure Automation: Controlling Runbook Streams for Testing and Troubleshooting</a></li>
<li><a href="http://azure.microsoft.com/blog/2014/08/12/azure-automation-runbook-input-output-and-nested-runbooks/" target="_blank">Azure Automation: Runbook Input, Output, and Nested Runbooks</a></li>
<li><a href="http://azure.microsoft.com/blog/2014/07/03/azure-automation-in-depth-runbook-authoring/" target="_blank">Azure Automation in Depth: Runbook Authoring</a></li>
<li><a href="https://social.msdn.microsoft.com/Forums/azure/en-US/home?forum=azureautomation" target="_blank">Microsoft Azure Automation Forums</a></li>
</ul>
<p>Armed with these resources I wrote the following runbook. It deploys a Cloud Service package and desired configurations from Azure Storage to the production slot of a Cloud Service. If the Cloud Service does not exist, it creates it. Then it tries to update the Cloud Service. If that fails, it created a brand new deployment.</p>
<pre class="brush: powershell; title: ; notranslate">
workflow Invoke-DeployPackage
{
   param
   (
      [parameter(Mandatory=$true, `
                 HelpMessage = 'The name given to the Windows PowerShell Credentials located in the Assets of this Azure Automation instance')]
      [String]
      $AzureCredentialsName,

      [parameter(Mandatory=$true, `
                 HelpMessage = 'The name of the Microsoft Azure Subscription that contains the resources your wish to deploy')]
      [String]
      $AzureSubscriptionName,

      [parameter(Mandatory=$true, `
                 HelpMessage = 'The name of the service you wish to deploy')]
      [String]
      $ServiceName,

      [parameter(Mandatory=$true, `
                 HelpMessage = 'The location of the service your with to deploy I.E. &quot;East US&quot;')]
      [String]
      $ServiceLocation,

      [parameter(Mandatory=$true, `
                 HelpMessage = 'The name of the Microsoft Azure storage account that contains the Cloud Service Packages')]
      [String]
      $StorageAccountName,

      [parameter(Mandatory=$true, `
                 HelpMessage = 'The name of the Blob container that contains the Cloud Service Packages')]
      [String]
      $StorageContainerName,

      [parameter(Mandatory=$true, HelpMessage = 'The name of the Cloud Service Package file')]
      [String]
      $PackageBlobName,

      [parameter(Mandatory=$true, HelpMessage = 'The name of the Cloud Service Configurations file')]
      [String]
      $ConfigurationBlobName
    )

    $VerbosePreference = 'Continue'

    # Mark the start time of the script execution
    $StartTime = Get-Date

    $DeploymentLable = $ServiceName + ' (' + $StartTime +')'

    Write-Verbose ('Connecting to Microsoft Azure')

    $Credentials = Get-AutomationPSCredential `
                       -Name $AzureCredentialsName

    Add-AzureAccount `
       -Credential $Credentials

    InlineScript{

        Write-Verbose ('Selecting Azure Subscription')

        Select-AzureSubscription -SubscriptionName $Using:AzureSubscriptionName

        $StorageAccount = (Get-AzureStorageAccount -StorageAccountName $Using:StorageAccountName).Label

        Write-Verbose ('Setting the Azure Subscription and Storage Accounts')

        Set-AzureSubscription `
            -SubscriptionName $Using:AzureSubscriptionName `
            -CurrentStorageAccount $StorageAccount

        Write-Verbose ('[Start] Validating Azure cloud service environment {0}' -f $Using:ServiceName)

        try
        {
            $CloudService = Get-AzureService `
                                -ServiceName $Using:ServiceName

            Write-Verbose ('cloud service {0} in location {1} exist!' -f $Using:ServiceName, $Using:ServiceLocation)
        }
        catch
        {
            #Create
            Write-Verbose ('[Start] creating cloud service {0} in location {1}' -f $Using:ServiceName, $Using:ServiceLocation)

            New-AzureService `
                -ServiceName $Using:ServiceName `
                -Location $Using:ServiceLocation

            Write-Verbose ('[Finish] creating cloud service {0} in location {1}' -f $Using:ServiceName, $Using:ServiceLocation)
        }

        Write-Verbose ('[Finish] Validating Azure cloud service environment {0}' -f $Using:ServiceName)

        $TempFileLocation = &quot;C:\$Using:ConfigurationBlobName&quot;

        Write-Verbose ('Downloading Service Configurations from Azure Storage')

        Get-AzureStorageBlobContent `
            -Container $Using:StorageContainerName `
            -Blob  $Using:ConfigurationBlobName `
            -Destination $TempFileLocation `
            -Force

        Write-Verbose('Downloaded Configuration File: '+ $TempFileLocation)

        Write-Verbose('Getting Package Url from Azure Storage: '+ $Using:PackageBlobName)

        $blob = $(Get-AzureStorageBlob -Blob $Using:PackageBlobName -Container $Using:StorageContainerName)

        $PackageUri = $blob.ICloudBlob.Uri.AbsoluteUri

        Write-Verbose('Package Url: '+ $PackageUri)

        try
        {
            Write-Verbose('Attempting to Update an Existing Deployment')
            Set-AzureDeployment `
                -Package $PackageUri `
                -Configuration $TempFileLocation `
                -Slot Production `
                -Mode Simultaneous `
                -Label $Using:DeploymentLable `
                -ServiceName  $Using:ServiceName `
                -Upgrade `
                -Force `
                -Verbose

        }catch
        {
            Write-Output $error

            Write-Verbose('Attempting to Deploy the service')

            New-AzureDeployment `
                -Package $PackageUri `
                -Configuration $TempFileLocation `
                -Slot Production `
                -Label $Using:DeploymentLable `
                -ServiceName  $Using:ServiceName `
                -Verbose
        }
    }
}
</pre>
<p>Using your browser let&#8217;s navigated to <a href="http://manage.windowsazure.com" target="_blank">http://manage.windowsazure.com</a> and log into our Azure Account. From this management portal I will show you how to schedule your runbook to execute once at 8 PM to scale-down and once at 6 AM to scale-up.</p>
<p>From the bottom of the management portal click on the <strong>+</strong> button and make the selections seen below. Then create a new runbook whose name is the same as the workflow listed above (for this to work, both names must match). For the purpose of this blog post, I also opted to create a new Automation Account. This account will be used to host the runbook, schedules and assets.</p>
<a href="https://alexandrebrisebois.files.wordpress.com/2014/12/create-runbook.png"><img class="aligncenter size-large wp-image-5748" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-runbook.png?w=580&#038;h=250" alt="create-runbook" width="580" height="250" /></a>
<p>Once the Automation Account and Runbook have been created, navigate to the new Automation Account and click on the Assets tab.</p>
<img class="aligncenter size-large wp-image-5768" src="https://alexandrebrisebois.files.wordpress.com/2014/12/adding-an-asset.png?w=580&#038;h=309" alt="adding-an-asset" width="580" height="309" />
<p>Click on <strong>ADD SETTING</strong> and then on <strong>ADD CREDENTIAL</strong><br />
<img class="aligncenter size-large wp-image-5769" src="https://alexandrebrisebois.files.wordpress.com/2014/12/add-runbook-credentials-0.png?w=580&#038;h=223" alt="add-runbook-credentials-0" width="580" height="223" /></p>
<p>Select <strong>Windows PowerShell Credential</strong> from the <strong>CREDENTIAL TYPE</strong> dropdown. Then give this asset a name. It will be used by the runbook, to retrieve the required credentials that provide access the Azure Storage Account that contains the packages and configurations of the Cloud Service.</p>
<img class="aligncenter size-large wp-image-5750" src="https://alexandrebrisebois.files.wordpress.com/2014/12/add-runbook-credentials.png?w=580&#038;h=518" alt="add-runbook-credentials" width="580" height="518" />
<p>Enter the user name and password for the Azure Active Directory user that was created earlier in this post. This user must be co-administrator to your Azure Subscription.</p>
<img class="aligncenter size-large wp-image-5751" src="https://alexandrebrisebois.files.wordpress.com/2014/12/add-runbook-credentials-2.png?w=580&#038;h=370" alt="add-runbook-credentials-2" width="580" height="370" />
<p>Once the asset is created, it will appear in the assets list. This list is composed of Connections, Credentials, Variables and Schedules that can be used or linked to runbooks.</p>
<p><img class="aligncenter size-large wp-image-5753" src="https://alexandrebrisebois.files.wordpress.com/2014/12/add-runbook-credentials-3.png?w=580&#038;h=186" alt="add-runbook-credentials-3" width="580" height="186" /><br />
Navigate to the <strong>RUNBOOKS</strong> tab and select the <strong>Invoke-DeployPackage</strong> runbook.</p>
<img class="aligncenter size-large wp-image-5771" src="https://alexandrebrisebois.files.wordpress.com/2014/12/navigate-to-runbooks.png?w=580&#038;h=267" alt="navigate-to-runbooks" width="580" height="267" />
<p>Navigate to the <strong>AUTHOR</strong> tab. The <strong>DRAFT</strong> tab should be active by default. By now the runbook is composed of an empty workflow. Replace it with the full runbook script listed above. Click <strong>SAVE</strong> and then <strong>TEST</strong>. Provide all the necessary information and see whether the runbook is able to deploy the Cloud Service. Once everything look OK, click <strong>PUBLISH</strong>.</p>
<a href="https://alexandrebrisebois.files.wordpress.com/2014/12/runbook-draft.png"><img class="aligncenter size-large wp-image-5755" src="https://alexandrebrisebois.files.wordpress.com/2014/12/runbook-draft.png?w=580&#038;h=548" alt="runbook-draft" width="580" height="548" /></a>
<p>Navigate to the <strong>SCHEDULE</strong> tab and click on <strong>LINK TO A NEW SCHEDULE</strong>.</p>
<p><img class="aligncenter size-large wp-image-5756" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule.png?w=580&#038;h=236" alt="create-schedule" width="580" height="236" /><br />
There are two schedules that need to be created. The first one is to scale-down the Cloud Service. Give the schedule a meaningful name and description.</p>
<p><a href="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-1.png"><img class="aligncenter size-large wp-image-5757" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-1.png?w=580&#038;h=458" alt="create-schedule-1" width="580" height="458" /></a><br />
Then configure the schedule. As originally stated, we want to scale-down everyday at 8 PM.</p>
<p><a href="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-2.png"><img class="aligncenter size-large wp-image-5758" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-2.png?w=580&#038;h=458" alt="create-schedule-2" width="580" height="458" /></a><br />
Provide the configuration values for the scheduled execution of the <strong>Invoke-DeployPackage</strong> runbook.</p>
<a href="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-3.png"><img class="aligncenter size-large wp-image-5759" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-3.png?w=580&#038;h=457" alt="create-schedule-3" width="580" height="457" /></a>
<p>Once the schedule is created, it will be listed under the <strong>SCHEDULE</strong> tab.</p>
<p><a href="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-4.png"><img class="aligncenter size-large wp-image-5761" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-4.png?w=580&#038;h=198" alt="create-schedule-4" width="580" height="198" /></a>It is possible to go back and view the schedule&#8217;s details. Click on <strong>VIEW DETAILS</strong> located at the bottom of the list.</p>
<p><img class="aligncenter wp-image-5773 size-full" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-4-11.png?w=580" alt=""   /><br />
Now it&#8217;s time to create the scale-up schedule. Click on <strong>LINK</strong> located at the bottom of the schedule list and select <strong>Link to a new Schedule</strong>.</p>
<p><a href="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-5.png"><img class="aligncenter size-large wp-image-5762" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-5.png?w=580&#038;h=199" alt="create-schedule-5"   /></a><br />
To create the scale-up schedule, the wizard will walk through the same screens as it did for the scale-down schedule. Be sure to provide a meaningful name and description. These values can be quite useful when the list of schedules gets to be lengthy.</p>
<p><a href="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-6.png"><img class="aligncenter size-large wp-image-5763" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-6.png?w=580&#038;h=457" alt="create-schedule-6" width="580" height="457" /></a><br />
As previously stated, we want to scale-up the Cloud Service everyday at 6:00 AM.</p>
<p><a href="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-7.png"><img class="aligncenter size-large wp-image-5764" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-7.png?w=580&#038;h=458" alt="create-schedule-7" width="580" height="458" /></a><br />
Provide the configuration values for the scheduled execution of the <strong>Invoke-DeployPackage</strong> runbook. This time, specify the extra large package and configuration file names.</p>
<p><a href="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-8.png"><img class="aligncenter size-large wp-image-5765" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-8.png?w=580&#038;h=457" alt="create-schedule-8" width="580" height="457" /></a><br />
The schedule will appear in the schedule list. Note that this is a great place to get information about the schedule&#8217;s next execution time.</p>
<a href="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-9.png"><img class="aligncenter size-large wp-image-5766" src="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-9.png?w=580&#038;h=146" alt="create-schedule-9" width="580" height="146" /></a>
<p>Once you navigate back to the <strong>DASHBOARD</strong> tab, you will notice that 2 schedules are active.</p>
<img class="aligncenter size-large wp-image-5752" src="https://alexandrebrisebois.files.wordpress.com/2014/12/azure-automation.png?w=580&#038;h=517" alt="Azure-Automation" width="580" height="517" />
<p>Within 24 hours, the <strong>DASHBOARD</strong> will light up with useful information about the execution of the runbooks. In this screen capture, we can observe that I had two successful executions and that I consumed 2 minutes of the available 500 minutes. This runbook is currently scaled at the free tier and can easily be scaled up if I need more execution time.<br />
<a href="https://alexandrebrisebois.files.wordpress.com/2014/12/runbook-dashboard.png"><img class="aligncenter size-large wp-image-5776" src="https://alexandrebrisebois.files.wordpress.com/2014/12/runbook-dashboard.png?w=580&#038;h=514" alt="runbook-dashboard" width="580" height="514" /></a></p>
<h2>Wrapping it up</h2>
<p>This was a long one, but I hope it can help you through this process. Getting this setup for the first time required that I read up on runbooks and PowerShell. It also required me to do a lot of testing, and I found that using the portal slowed me down. So I decided to develop and test my runbook from <strong>Windows PowerShell ISE</strong>. This allowed me to go through development cycles at a much faster rate.</p>
<p>Configuring the Credentials necessary for Microsoft Azure Automation also took me some time to figure out because I was using the wrong Azure Active Directory.</p>
<p>In summary, where are the steps required to setup this scenario.</p>
<ol>
<li>Create the Cloud Service packages
<ol>
<li>The first with the scaled-up VM size</li>
<li>The second with the scaled-down VM size</li>
</ol>
</li>
<li>Prepare 2 Cloud Service configuration files
<ol>
<li>The first with the scaled-in instance count</li>
<li>The second with the scaled-out instance count</li>
</ol>
</li>
<li>Upload the Cloud Service packages and configuration files to Azure Storage</li>
<li>Create an Automation account</li>
<li>Setup <a href="http://azure.microsoft.com/blog/2014/08/27/azure-automation-authenticating-to-azure-using-azure-active-directory/" target="_blank"><span style="color:#4d8b97;">Azure Automation: Authenticating to Azure using Azure Active Directory</span></a></li>
<li>Author the runbook (draft, test and publish)</li>
<li>Schedule therunbook
<ol>
<li>Once to scale-up everyday at 6 AM</li>
<li>Once to scale-down everyday at 8 PM</li>
</ol>
</li>
</ol>
<h3>How does this scenario translate to lower operational costs?</h3>
<p>The following comparison uses the pay-as-you-go pricing from <strong>December 2014</strong></p>
<table width="370">
<tbody>
<tr>
<td><strong>SCENARIO </strong></td>
<td style="text-align:center;" colspan="4" width="284"><strong>scaling down during quiet hours</strong></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>VM</td>
<td>HOURS</td>
<td>INSTANCES</td>
<td>COST/HOUR</td>
<td>TOTAL</td>
</tr>
<tr>
<td>ExtraSmall</td>
<td>10</td>
<td>1</td>
<td>$           0.022</td>
<td>$     0.22</td>
</tr>
<tr>
<td>ExtraLarge</td>
<td>14</td>
<td>5</td>
<td>$           0.675</td>
<td>$   47.25</td>
</tr>
<tr>
<td><strong>Daily Cost</strong></td>
<td></td>
<td></td>
<td></td>
<td><strong> $   47.47 </strong></td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td><strong>SCENARIO</strong></td>
<td style="text-align:center;" colspan="4" width="284"><strong>staying at maximum capacity</strong></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>VM</td>
<td>HOURS</td>
<td>INSTANCES</td>
<td>COST/HOUR</td>
<td>TOTAL</td>
</tr>
<tr>
<td>ExtraSmall</td>
<td>0</td>
<td>0</td>
<td>$           0.022</td>
<td>$         &#8211;</td>
</tr>
<tr>
<td>ExtraLarge</td>
<td>24</td>
<td>5</td>
<td>$           0.675</td>
<td>$   81.00</td>
</tr>
<tr>
<td><strong>Daily Cost</strong></td>
<td></td>
<td></td>
<td></td>
<td><strong> $   81.00 </strong></td>
</tr>
</tbody>
</table>
<p>Let&#8217;s take a look at the operational cost difference between both scenarios</p>
<table>
<tbody>
<tr>
<td><strong>DIFFERENCE</strong></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><strong>SCENARIO</strong></td>
<td><strong>1 DAY</strong></td>
<td><strong>1 MONTH</strong></td>
<td><strong>1 YEAR</strong></td>
</tr>
<tr>
<td>scaling down</td>
<td>$   47.47</td>
<td>$ 1,424.10</td>
<td>$ 17,326.55</td>
</tr>
<tr>
<td>full capacity</td>
<td>$   81.00</td>
<td>$ 2,430.00</td>
<td>$ 29,565.00</td>
</tr>
<tr>
<td><strong>savings</strong></td>
<td><strong> $   33.53 </strong></td>
<td><strong> $ 1,005.90 </strong></td>
<td><strong> $ 12,238.45 </strong></td>
</tr>
</tbody>
</table>
<p>I think the numbers speak for themselves. At this time, it&#8217;s important to note that scaling dynamically using features like Auto Scaling and scaling based on a schedule can dramatically affect your overall operational costs. Furthermore, Azure gives us the ability to scale up and down as well as in and out. Finding the right combination can enable us to provide the appropriate amount of resources to satisfy the application&#8217;s needs.</p>
<p>Be careful, over provisioning means overspending. On the other hand, under provisioning can result in decreased revenue and dissatisfied customers. It can even push customers to your competitors. Use telemetry data to identify the amount of resources required to strike a balance point between operational costs, availability and responsiveness of your application.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-storage/'>Azure Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blobs-storage/'>Blobs Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configurations/'>Configurations</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/package/'>Package</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/roles/'>Roles</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/runbook/'>Runbook</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/scale-down/'>Scale Down</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/scale-in/'>Scale In</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/scale-out/'>Scale Out</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/scale-up/'>Scale Up</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/schedule/'>Schedule</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/worker-role/'>Worker Role</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/workflow/'>Workflow</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/xml/'>XML</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5705/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5705/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5705&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/12/29/scaling-azure-cloud-services-up-and-down-like-clockwork/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/12/8478044641_993f0a2373_z.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/8478044641_993f0a2373_z.jpg?w=150" medium="image">
			<media:title type="html">clock-work</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-runbook.png?w=580" medium="image">
			<media:title type="html">create-runbook</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/adding-an-asset.png?w=580" medium="image">
			<media:title type="html">adding-an-asset</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/add-runbook-credentials-0.png?w=580" medium="image">
			<media:title type="html">add-runbook-credentials-0</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/add-runbook-credentials.png?w=580" medium="image">
			<media:title type="html">add-runbook-credentials</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/add-runbook-credentials-2.png?w=580" medium="image">
			<media:title type="html">add-runbook-credentials-2</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/add-runbook-credentials-3.png?w=580" medium="image">
			<media:title type="html">add-runbook-credentials-3</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/navigate-to-runbooks.png?w=580" medium="image">
			<media:title type="html">navigate-to-runbooks</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/runbook-draft.png?w=580" medium="image">
			<media:title type="html">runbook-draft</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule.png?w=580" medium="image">
			<media:title type="html">create-schedule</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-1.png?w=580" medium="image">
			<media:title type="html">create-schedule-1</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-2.png?w=580" medium="image">
			<media:title type="html">create-schedule-2</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-3.png?w=580" medium="image">
			<media:title type="html">create-schedule-3</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-4.png?w=580" medium="image">
			<media:title type="html">create-schedule-4</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-4-11.png" medium="image" />

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-5.png?w=551" medium="image">
			<media:title type="html">create-schedule-5</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-6.png?w=580" medium="image">
			<media:title type="html">create-schedule-6</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-7.png?w=580" medium="image">
			<media:title type="html">create-schedule-7</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-8.png?w=580" medium="image">
			<media:title type="html">create-schedule-8</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/create-schedule-9.png?w=580" medium="image">
			<media:title type="html">create-schedule-9</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/azure-automation.png?w=580" medium="image">
			<media:title type="html">Azure-Automation</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/runbook-dashboard.png?w=580" medium="image">
			<media:title type="html">runbook-dashboard</media:title>
		</media:content>
	</item>
		<item>
		<title>Lift and Shift of a Console Appication to Microsoft #Azure</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/12/14/lift-and-shift-of-a-console-appication-to-microsoft-azure/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/12/14/lift-and-shift-of-a-console-appication-to-microsoft-azure/#comments</comments>
		<pubDate>Mon, 15 Dec 2014 02:00:54 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[ANSI]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Configurations]]></category>
		<category><![CDATA[Guest OS]]></category>
		<category><![CDATA[Lift & Shift]]></category>
		<category><![CDATA[PaaS]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Queue Storage]]></category>
		<category><![CDATA[Roles]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Worker Role]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5606</guid>
		<description><![CDATA[Azure Worker Roles support a surprising variety of scenarios! This post is all about lifting and shifting an application from on premise to a Microsoft Azure Worker Role.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5606&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/12/14/lift-and-shift-of-a-console-appication-to-microsoft-azure/" target="_blank" title="Lift and Shift of a Console Appication to Microsoft&nbsp;#Azure"><img width="580" height="385" src="https://alexandrebrisebois.files.wordpress.com/2014/12/lift-and-shift-5.jpg?w=580" class="attachment-large wp-post-image" alt="lift-and-shift-5" /></a></p><h1>Moving to Microsoft Azure</h1>
<p>Every time I dig a little deeper into Azure, I’m amazed at how much there is to know. Having done a few projects with Cloud Services in the past, I thought it would be interesting to see if it was possible to lift and shift a Console Application into an Azure Worker Role.</p>
<blockquote><p><strong>Lift and Shift</strong>: The action of moving a workload to a new environment, without altering the application’s code.</p></blockquote>
<p><span id="more-5606"></span></p>
<h3>Prerequisites</h3>
<blockquote>
<h4>☁ Tools</h4>
<p>Using the <a href="http://www.microsoft.com/web/downloads/platform.aspx" target="_blank">Microsoft Web Platform Installer</a> install the latest <strong>Microsoft Azure PowerShell with Microsoft Azure SDK</strong>.</p>
<h4>☁ Microsoft Azure Account</h4>
<p>In order to deploy your workload to Microsoft Azure, be sure to have an account. You can create a <a href="http://azure.microsoft.com/en-us/pricing/free-trial/" target="_blank">Free Trial Account</a> on the <a href="http://www.azure.com" target="_blank">azure.com</a> website.</p></blockquote>
<h2>Creating a Worker Role without Visual Studio</h2>
<blockquote><p>A <a href="http://msdn.microsoft.com/en-us/library/azure/jj155995.aspx" target="_blank">Worker Role</a> is a role that is useful for generalized development, and may perform background processing for a <a href="http://msdn.microsoft.com/en-us/library/azure/jj155995.aspx" target="_blank">Web Role</a>. When you have a need for a background process that performs long running or intermittent tasks, you should use this role.</p></blockquote>
<p>Let&#8217;s fire-up <strong>Windows PowerShell ISE</strong> and navigate to the folder where you want to create your Cloud Service. For this blog post, I created a new folder, <strong>demo-lift-and-shift</strong>, in my Documents.</p>
<pre class="brush: plain; title: ; notranslate">
C:\users\&lt;user id&gt;\Documents\demo-lift-and-shift
</pre>
<p>In the PowerShell console, execute the following commands.</p>
<pre class="brush: powershell; title: ; notranslate">
# Create the Cloud Service
New-AzureServiceProject -ServiceName 'console-lift-and-shift' -Verbose

# Create the Worker Role
Add-AzureWorkerRole -Name 'ConsoleWorkerRole' -Instances 1 -Verbose
</pre>
<p>These two commands will produce the following files and documents. This represents the Cloud Service project. It contains the configurations and the Cloud Service definition.</p>
<img class="aligncenter wp-image-5627 size-full" src="https://alexandrebrisebois.files.wordpress.com/2014/12/project.png?w=580" alt="project"   />
<p>The <strong>ServiceDefinition.csdef</strong> was created by PowerShell when we executed the <strong>New-AzureServiceProject</strong> command. Then it was updated when we executed the <strong>Add-AzureWorkerRole</strong>. The following is the unchanged version of the service definition. Since it is missing a few pieces, I will show you what to change in order to be able to deploy your brand-new service to Microsoft Azure.</p>
<blockquote><p>The <strong>ServiceDefinition.csdef</strong> file contains the metadata that is required by the Azure environment for the requirements of your cloud service, including what roles it contains. This file also contains configuration settings that apply to all instances. These configuration settings can be read at runtime using the Azure Service Hosting Runtime API. This file cannot be updated while your service is running in Azure.</p></blockquote>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;ServiceDefinition xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
                   xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
                   name=&quot;console-lift-and-shift&quot;
                   xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition&quot;&gt;
  &lt;WorkerRole name=&quot;ConsoleWorkerRole&quot;&gt;
    &lt;Startup&gt;
      &lt;Task commandLine=&quot;setup_worker.cmd &amp;gt; log.txt&quot; executionContext=&quot;elevated&quot;&gt;
        &lt;Environment&gt;
          &lt;Variable name=&quot;EMULATED&quot;&gt;
            &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
          &lt;/Variable&gt;
          &lt;Variable name=&quot;RUNTIMEID&quot; value=&quot;&quot; /&gt;
          &lt;Variable name=&quot;RUNTIMEURL&quot; value=&quot;&quot; /&gt;
        &lt;/Environment&gt;
      &lt;/Task&gt;
      &lt;Task commandLine=&quot;.\startup.cmd &amp;gt; startup_log.txt&quot; executionContext=&quot;elevated&quot; /&gt;
    &lt;/Startup&gt;
    &lt;Endpoints&gt;
      &lt;InputEndpoint name=&quot;HttpIn&quot; protocol=&quot;tcp&quot; port=&quot;80&quot; /&gt;
    &lt;/Endpoints&gt;
    &lt;Runtime&gt;
      &lt;Environment&gt;
        &lt;Variable name=&quot;PORT&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[@name='HttpIn']/@port&quot; /&gt;
        &lt;/Variable&gt;
        &lt;Variable name=&quot;EMULATED&quot;&gt;
          &lt;RoleInstanceValue xpath=&quot;/RoleEnvironment/Deployment/@emulated&quot; /&gt;
        &lt;/Variable&gt;
      &lt;/Environment&gt;
      &lt;EntryPoint&gt;
        &lt;ProgramEntryPoint commandLine=&quot;worker.cmd&quot; setReadyOnProcessStart=&quot;true&quot; /&gt;
      &lt;/EntryPoint&gt;
    &lt;/Runtime&gt;
  &lt;/WorkerRole&gt;
&lt;/ServiceDefinition&gt;
</pre>
<h3>Specify a Role (Virtual Machine) size</h3>
<p>The size of the role determines the number of CPU cores, the memory capacity, and the local file system size that is allocated to a running instance. The following</p>
<ul>
<li>ExtraSmall (1 CPU, 768 MB RAM, 19 GB DISK)</li>
<li>Small (1 CPU, 1.75 GB RAM, 224 GB DISK)</li>
<li>Medium (2 CPU. 2.5 GB RAM, 489 GB DISK)</li>
<li>Large (4 CPU 7 GB RAM, 999 GB DISK)</li>
<li>ExtraLarge (8 CPU, 14 GB RAM, 2039 GB DISK)</li>
</ul>
<p>Considerations to&nbsp;help you decide on&nbsp;the correct&nbsp;size for your workload</p>
<blockquote>
<ol>
<li>Instances can now be configured to use a D-series VM. These are designed to run applications that demand higher compute power and temporary disk performance. D-series VMs provide faster processors, a higher memory-to-core ratio, and a solid-state drive (SSD) for the temporary disk. For details, see the announcement on the Azure blog, New D-Series Virtual Machine Sizes.</li>
<li>Web roles and worker roles require more temporary disk space than Azure Virtual Machines because of system requirements. The system files reserve 4 GB of space for the Windows page file, and 2 GB of space for the Windows dump file.</li>
<li>The OS disk contains the Windows guest OS and includes the Program Files folder (including installations done via startup tasks unless you specify another disk), registry changes, the System32 folder, and the .NET framework.</li>
<li>The local resource disk contains Azure logs and configuration files, Azure Diagnostics (which includes your IIS logs), and any local storage resources you define.</li>
<li>The apps (application) disk is where your .cspkg is extracted and includes your website, binaries, role host process, startup tasks, web.config, and so on.</li>
</ol>
</blockquote>
<p>More details about <a href="http://msdn.microsoft.com/library/azure/dn197896.aspx" target="_blank">Virtual Machine and Cloud Service Sizes for Azure</a> can be found in the official Azure documentation.</p>
<p>For this example we will use a <strong>Medium</strong> sized role (Virtual Machine) for our Cloud Service.</p>
<p><strong>Replace</strong></p>
<pre class="brush: xml; title: ; notranslate">
&lt;WorkerRole name=&quot;ConsoleWorkerRole&quot;&gt;
</pre>
<p><strong>By</strong></p>
<pre class="brush: xml; title: ; notranslate">
&lt;WorkerRole name=&quot;ConsoleWorkerRole&quot; vmsize=&quot;Medium&quot;&gt;
</pre>
<h3>Specify a Guest OS Version</h3>
<p>Guest OS families and versions have a release date, a disabled date, and an expiration date. As of the release date, a Guest OS version can be manually selected in the management portal. A Guest OS is removed from the management portal on or after its &#8220;disabled&#8221; date. It is then &#8220;in transition&#8221; but is supported with limited ability to update a deployment. The expiration date is when a version or family is scheduled to be removed from the Azure system completely. Cloud services still running on a version when it expires will be stopped, deleted or force upgraded to a newer version, as detailed in the <a href="http://msdn.microsoft.com/en-us/library/azure/dn750847.aspx">Azure Guest OS Supportability and Retirement Policy</a>. Microsoft supports at least two recent versions of each supported Guest OS family.</p>
<p>Available Families as of December 2014</p>
<ul>
<li><strong>FAMILY 4</strong><br />
Windows Server 2012 R2<br />
Supports .NET 4.0, 4.5, 4.5.1, 4.5.2</li>
<li><strong>FAMILY 3</strong><br />
Windows Server 2012<br />
Supports .NET 4.0, 4.5</li>
<li><strong>FAMILY 2</strong><br />
Windows Server 2008 R2 SP1<br />
Supports .NET 3.5, 4.0</li>
</ul>
<p>More details about <a href="http://msdn.microsoft.com/en-us/library/azure/ee924680.aspx" target="_blank">Azure Guest OS Releases</a> can be found in the official Azure documentation.</p>
<img class="aligncenter wp-image-5627 size-full" src="https://alexandrebrisebois.files.wordpress.com/2014/12/project.png?w=580" alt="project"   />
<p>The&nbsp;<strong>ServiceConfiguration.{Environment}.cscfg</strong> was created by PowerShell when we executed the <strong>Add-AzureWorkerRole</strong> PowerShell&nbsp;command.</p>
<blockquote><p>The configuration of the settings for your cloud service is determined by the values in the ServiceConfiguration.cscfg file. You specify the number of instances that you want to deploy for each role in this file. The values for the configuration settings that you defined in the service definition file are added to the service configuration file. The thumbprints for any management certificates that are associated with the cloud service are also added to the file. The <a href="http://msdn.microsoft.com/en-us/library/azure/ee758710.aspx" target="_blank">Azure Service Configuration Schema (.cscfg File)</a> provides the allowable format for a service configuration file.</p></blockquote>
<p>The following is the unchanged version of the <strong>ServiceConfiguration.Cloud.cscfg</strong> file. Since it is missing a few pieces, I will show you what to change in order to be able to deploy your brand-new service to Microsoft Azure.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;
&lt;ServiceConfiguration xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
                      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
                      serviceName=&quot;console-lift-and-shift&quot;
                      osFamily=&quot;2&quot;
                      osVersion=&quot;*&quot;
                      xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration&quot;&gt;
  &lt;Role name=&quot;ConsoleWorkerRole&quot;&gt;
    &lt;ConfigurationSettings /&gt;
    &lt;Instances count=&quot;1&quot; /&gt;
    &lt;Certificates /&gt;
  &lt;/Role&gt;
&lt;/ServiceConfiguration&gt;
</pre>
<p>For this example we will use <strong>Family 4</strong> because our Console Application is built using .Net 4.5.</p>
<p><strong>Replace</strong></p>
<pre class="brush: xml; title: ; notranslate">
&lt;ServiceConfiguration xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
                      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
                      serviceName=&quot;console-lift-and-shift&quot;
                      osFamily=&quot;2&quot;
                      osVersion=&quot;*&quot;
                      xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration&quot;&gt;
</pre>
<p><strong>By</strong></p>
<pre class="brush: xml; title: ; notranslate">
&lt;ServiceConfiguration xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
                      xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
                      serviceName=&quot;console-lift-and-shift&quot;
                      osFamily=&quot;4&quot;
                      osVersion=&quot;*&quot;
                      xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration&quot;&gt;
</pre>
<p>We left <strong>osVersion=&#8221;*&#8221;</strong> to allow the Azure Fabric to continuously patch the Guest OS.</p>
<h2>Packaging The Console Application as a Cloud Service</h2>
<p>The <strong>ConsoleWorkerRole</strong> folder contains the files and documents that compose our new <strong>Azure Worker Role</strong></p>
<img class="aligncenter wp-image-5630 size-full" src="https://alexandrebrisebois.files.wordpress.com/2014/12/worker-role.png?w=580" alt="worker-role"   />
<p>Place the files that compose the Console Application in this folder. The example used for this Blog is an application that writes messages to an Azure Storage Queue.</p>
<img class="aligncenter size-full wp-image-5664" src="https://alexandrebrisebois.files.wordpress.com/2014/12/console-role.png?w=580" alt="console-role"   />
<p>Be sure to include the application&#8217;s dependencies such that nothing stops the application from running once it is deployed to an Azure Worker Role. If, for some reason, the application does not seem to run as expected, refer to my earlier <a href="https://alexandrebrisebois.wordpress.com/2014/08/07/busy-starting-role-sites-were-deployed-azure-role-diagnostics/" target="_blank">blog post that shared techniques to investigate and debug Azure Roles</a>.</p>
<p>Before we package the Azure Cloud Service, we must update the <strong>worker.cmd</strong> file. This file contains the application loop that is executed by the&nbsp;Azure Worker role.&nbsp;The following is the initial version of the file.</p>
<pre class="brush: plain; title: ; notranslate">
:workerLoop

:: Do work
ping 123.45.67.89 -n 1 -w 1000000 &gt; nul

goto workerLoop
</pre>
<p>In order to start the application, replace the <strong>ping</strong> command by a direct call to&nbsp;the application&#8217;s executable. Every time the application terminates, it will be restarted. This is the first of many mechanisms in place to ensure that&nbsp;the application is resilient and available.</p>
<pre class="brush: plain; title: ; notranslate">
:workerLoop

:: This EXE will be re-invoked every time it completes it's execution
DemoAppWritingToAQueue.exe

goto workerLoop
</pre>
<p>Be sure to select the <strong>ANSI Encoding</strong> then you save your changes. Failing to do so may prevent the CMD script from executing.</p>
<img class="aligncenter size-full wp-image-5670" src="https://alexandrebrisebois.files.wordpress.com/2014/12/encoding-e1418584138831.png?w=580" alt="encoding"   />
<p>Now that we have the Console Application wired up to the Worker Role, it&#8217;s time to package the Cloud Service. In <strong>Windows PowerShell ISE</strong> and navigate back to the folder that contains the Cloud Service.</p>
<p>The Cloud Service for this blog post is at the following location:</p>
<pre class="brush: plain; title: ; notranslate">
C:\users\&lt;user id&gt;\Documents\demo-lift-and-shift\console-lift-and-shift
</pre>
<p>In the PowerShell console, execute the following commands.</p>
<pre class="brush: powershell; title: ; notranslate">
# Package the Cloud Service
Save-AzureServiceProjectPackage
</pre>
<p>This produces a package named <strong>cloud_package.cspkg</strong>, which is required for the service&#8217;s deployment.</p>
<img class="aligncenter size-full wp-image-5676" src="https://alexandrebrisebois.files.wordpress.com/2014/12/cloud-service-package.png?w=580" alt="cloud-service-package"   />
<h2>Deploying the Cloud Service</h2>
<p>This step has a prerequisite. We must start by importing a publish profile from our Microsoft Azure Subscription. PowerShell will use it to publish our Cloud Service to our Microsoft Azure.</p>
<p>In the PowerShell console, execute the following commands.</p>
<pre class="brush: powershell; title: ; notranslate">
# Opens a website that allows us to download the Publish Profile
# associated with our Microsoft Azure Subscription
Get-AzurePublishSettingsFile
</pre>
<p>Save the publish settings files to your downloads folder then import it using the following command.</p>
<pre class="brush: powershell; title: ; notranslate">
Import-AzurePublishSettingsFile -PublishSettingsFile 'C:\Users\&lt;user id&gt;\Downloads\&lt;subscription name&gt;-credentials.publishsettings'
</pre>
<p>We are now ready to publish our brand-new Cloud Service. The following command will create a new storage account to upload our package. This is the default behavior because we did not provide a storage account for the command. We specified a name for the service, a location (datacenter), a slot (production or staging) and a deployment name. For more information about the <a href="http://msdn.microsoft.com/en-us/library/azure/dn495166.aspx" target="_blank">Publish-AzureServiceProject command please refer to the official documentation</a>.</p>
<pre class="brush: powershell; title: ; notranslate">
Publish-AzureServiceProject -ServiceName 'lift-and-shift-demo' 
                            -Location 'East US' 
                            -Slot 'Production' 
                            -DeploymentName '2014-12-14-15-46' 
                            -Verbose
</pre>
<p>If the Publish-AzureServiceProject&nbsp;command is executed with the -Verbose flag, it will produce a detailed output that allows you to understand what is happening. It&#8217;s also very useful when you need to debug a failed deployment.</p>
<pre class="brush: powershell; title: ; notranslate">
WARNING: Publishing lift-and-shift-demo to Microsoft Azure. This may take several minutes...
WARNING: 3:47:10 PM - Preparing runtime deployment for service 'lift-and-shift-demo'
WARNING: 3:47:11 PM - Verifying storage account 'liftx2dandx2dshiftx2ddem'...
WARNING: 3:47:43 PM - Preparing deployment for lift-and-shift-demo with Subscription ID: dfbedef7-xxxx-xxxx-xxxx-650ca03208ee...
WARNING: 3:47:47 PM - Connecting...
WARNING: 3:47:48 PM - Creating...
WARNING: 3:47:49 PM - Created hosted service 'lift-and-shift-demo'.
WARNING: 3:47:49 PM - Uploading Package to storage service liftx2dandx2dshiftx2ddem...
WARNING: 3:47:56 PM - Starting...
WARNING: 3:48:30 PM - Created Deployment ID: 03e36c62a5f74d5f9ebd0a2ec0b16880.
WARNING: 3:48:30 PM - Initializing...
WARNING: 3:51:49 PM - Instance ConsoleWorkerRole_IN_0 of role ConsoleWorkerRole is busy.
WARNING: 3:52:22 PM - Instance ConsoleWorkerRole_IN_0 of role ConsoleWorkerRole is ready.
WARNING: 3:52:23 PM - Created Website URL: http://lift-and-shift-demo.cloudapp.net/.

PersistentVMDowntime : Microsoft.WindowsAzure.Commands.Utilities.CloudService.Model.PersistentVMDowntimeInfo
Name                 : 2014-12-14-15-46
DeploymentSlot       : Production
PrivateID            : 03e36c62a5f74d5f9ebd0a2ec0b16880
Status               : Running
Label                : lift-and-shift-demo
Url                  : http://lift-and-shift-demo.cloudapp.net/
Configuration        : &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;ServiceConfiguration xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
                       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; serviceName=&quot;lift-and-shift-demo&quot; osFamily=&quot;4&quot; osVersion=&quot;*&quot;
                       xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration&quot;&gt;  &lt;Role name=&quot;ConsoleWorkerRole&quot;&gt;
                       &lt;ConfigurationSettings /&gt;    &lt;Instances count=&quot;1&quot; /&gt;    &lt;Certificates /&gt;  &lt;/Role&gt;&lt;/ServiceConfiguration&gt;
RoleInstanceList     : {ConsoleWorkerRole}
UpgradeStatus        :
UpgradeDomainCount   : 1
RoleList             : {ConsoleWorkerRole}
SdkVersion           : 2.5.6496.10
Locked               : False
RollbackAllowed      : False
VirtualNetworkName   :
CreatedTime          : 2014-12-14 3:47:58 PM
LastModifiedTime     : 2014-12-14 3:52:23 PM
ExtendedProperties   : {}
Dns                  :
VirtualIPs           : {Microsoft.WindowsAzure.Commands.Utilities.CloudService.Model.VirtualIP}
</pre>
<p>Once the Cloud Service has completed its deployment, you can log into the <a href="https://manage.windowsazure.com" target="_blank">https://manage.windowsazure.com</a> portal and you will be able to monitor and alter its configurations.</p>
<img class="aligncenter wp-image-5684 size-large" src="https://alexandrebrisebois.files.wordpress.com/2014/12/azure-portal.png?w=580&#038;h=308" alt="azure-portal" width="580" height="308" />
<p>Because this solution does not rely on the .NET Azure SDK and since the CMD script has an infinite loop, I did not see a recycling status for my Azure Worker Role when it wasn’t configured properly. In the previous screen capture, we can observe a high CPU, which is unexpected for my Console Application. This was because I had deployed my Cloud Service on Guest OS Family 2 instead of 4 and that the .NET Framework 4.5 was missing. This cause my Console Application to continuously fail to start. The CMD worker script kept restarting my Console Application and ate up the entire CPU. Consequently, I updated the ServiceConfiguration.Cloud.cscfg file with the correct Guest OS Family and redeployed the Cloud Service.   </p>
<p>Out of curiosity, I configured the Remote Desktop Extension through the management portal and peaked into the provisioned instance. I was happy to find my Console Application running normally.</p>
<img class="aligncenter wp-image-5685 size-large" src="https://alexandrebrisebois.files.wordpress.com/2014/12/running-console-app.png?w=580&#038;h=462" alt="running-console-app" width="580" height="462" />
<h2>Bringing it All Together</h2>
<p>Azure Worker Roles support a surprising variety of scenarios! Here&#8217;s a quick recap of the steps taken to Lift &amp; Shift a Console Application to Microsoft Azure.</p>
<pre class="brush: powershell; title: ; notranslate">
# Create the Cloud Service
New-AzureServiceProject -ServiceName 'console-lift-and-shift' -Verbose

# Create the Worker Role
Add-AzureWorkerRole -Name 'ConsoleWorkerRole' -Instances 1 -Verbose
</pre>
<p>Update the configurations files with the appropriate Guest OS Family and with the desired VM Size for your Cloud Service. Then copy the Console Application and its dependencies to the Role&#8217;s folder. Don&#8217;t forget to update the worker.cmd script file so that it executes the desired Console Application.</p>
<pre class="brush: powershell; title: ; notranslate">
# Package the Cloud Service
Save-AzureServiceProjectPackage

# Publish the Package to Microsoft Azure 
Publish-AzureServiceProject -ServiceName 'lift-and-shift-demo' 
                            -Location 'East US' 
                            -Slot 'Production' 
                            -DeploymentName '2014-12-14-15-46' 
                            -Verbose
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/ansi/'>ANSI</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configurations/'>Configurations</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/guest-os/'>Guest OS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/lift-shift/'>Lift &amp; Shift</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/paas/'>PaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/package/'>Package</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/queue-storage/'>Queue Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/roles/'>Roles</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/worker-role/'>Worker Role</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/xml/'>XML</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5606/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5606/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5606/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5606/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5606/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5606/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5606/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5606/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5606/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5606/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5606/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5606/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5606/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5606/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5606&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/12/14/lift-and-shift-of-a-console-appication-to-microsoft-azure/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<georss:point>45.501689 -73.567256</georss:point>
		<geo:lat>45.501689</geo:lat>
		<geo:long>-73.567256</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/12/lift-and-shift-5.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/lift-and-shift-5.jpg?w=150" medium="image">
			<media:title type="html">lift-and-shift-5</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/project.png" medium="image">
			<media:title type="html">project</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/project.png" medium="image">
			<media:title type="html">project</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/worker-role.png" medium="image">
			<media:title type="html">worker-role</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/console-role.png" medium="image">
			<media:title type="html">console-role</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/encoding-e1418584138831.png" medium="image">
			<media:title type="html">encoding</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/cloud-service-package.png" medium="image">
			<media:title type="html">cloud-service-package</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/azure-portal.png?w=580" medium="image">
			<media:title type="html">azure-portal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/12/running-console-app.png?w=580" medium="image">
			<media:title type="html">running-console-app</media:title>
		</media:content>
	</item>
		<item>
		<title>Doing Something is Better Than Doing Nothing at All</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/11/03/doing-something-is-better-than-doing-nothing-at-all/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/11/03/doing-something-is-better-than-doing-nothing-at-all/#comments</comments>
		<pubDate>Mon, 03 Nov 2014 16:31:08 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Kanban]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5573</guid>
		<description><![CDATA[A manager once told me that even if you make the best decision today, chances are that it will be revised at a later time. From this I understood the importance of balancing facts, urgency and forth sight. Don't try to make the ultimate decision that will cover all your bases. Failing at making the best choice today, will provide you with insight that will influence subsequent decisions. This process is iterative and must be driven by a vision. <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5573&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/11/03/doing-something-is-better-than-doing-nothing-at-all/" target="_blank" title="Doing Something is Better Than Doing Nothing at&nbsp;All"><img width="580" height="580" src="https://alexandrebrisebois.files.wordpress.com/2014/11/8771332111_d82f803230_z.jpg?w=580" class="attachment-large wp-post-image" alt="eye on the ball" /></a></p><h1>Doing <u>Something</u><br />Is Better Than Doing Nothing at All</h1>
<p>There are times where uncertainty is high, the process is not suitable and the risk of missed deadlines looms on the horizon.</p>
<p>This is when we find ourselves in a sort of no man&#8217;s land, where everyone is terrified to make the call. At this point it’s important to note that inaction is a collective decision that we must all live with for the remainder of the project. More often than not, doing nothing puts your team on edge and produces an extraordinary amount of avoidable stress.<span id="more-5573"></span></p>
<p>A manager once told me that even if you make the best decision today, chances are that it will be revised at a later time. From this I understood the importance of balancing facts, urgency and foresight. Don&#8217;t try to make the ultimate decision that will cover all your bases. Failing at making the best choice today, will provide you with insight that will influence subsequent decisions. This process is iterative and must be driven by a vision. </p>
<p>The important thing to remember here is that attaining your goal is more important than how you reach you goal. Keep your eye on the ball.</p>
<p>On the path to achieving a goal, your team may adjust and course correct multiple times. Keep an eye out for irritants, blockers, delays and process issues. Address them quickly and keep moving forward. A decision made today may provide further details about the root cause. In turn, providing you with the tools necessary to keep your team motivated and on track.</p>
<p>I find Kanban to be very effective at identifying improvement opportunities. It highlights slowdowns and process issues. But most important of all, it allows you to continuously observe and adapt your process.</p>
<p>Teams that adopted this &#8220;can do&#8221; attitude have reaped the benefits of lower stress levels, better quality and better flow.</p>
<p>Encouraging teams to learn from their mistakes empowers individual team members to speak up and take ownership. This ultimately results in rich opportunities that would have gone unnoticed.</p>
<p>Ideas, solutions, challenges and opportunities have to originate from everyone on a team. I personally love discussions based on facts. These discussions typically start by exposing a challenge and ends with a plan of action. It&#8217;s important to keep these brief and on topic.  The best way I have found to achieve this, is to be prepared. Schedule a talk a head of time. Detail the topics and be ready to make a call. Don&#8217;t worry, make the best call based on the facts at hand. Test your hypothesis and iterate.</p>
<p>Acting sooner rather than later will allow you to be agile and adapt to unforeseen events.</p>
<p>Remember, keep your eye on the ball and seize the opportunity to define your fate. Doing something is better than doing nothing at all.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/thoughts/'>Thoughts</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/agile/'>Agile</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/best-practices/'>Best Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/kanban/'>Kanban</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5573/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5573/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5573/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5573&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/11/03/doing-something-is-better-than-doing-nothing-at-all/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/11/8771332111_d82f803230_z.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/11/8771332111_d82f803230_z.jpg?w=150" medium="image">
			<media:title type="html">eye on the ball</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>#Azure Table Storage &#8211; Using StartsWith to Filter on RowKeys</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/10/30/azure-table-storage-using-startswith-to-filter-on-rowkeys/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/10/30/azure-table-storage-using-startswith-to-filter-on-rowkeys/#comments</comments>
		<pubDate>Thu, 30 Oct 2014 19:42:14 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Table Storage]]></category>
		<category><![CDATA[Azure Storage]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Partition]]></category>
		<category><![CDATA[PartitionKey]]></category>
		<category><![CDATA[Range]]></category>
		<category><![CDATA[RowKey]]></category>
		<category><![CDATA[StartsWith]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5534</guid>
		<description><![CDATA[There are many scenarios where filtering on partial RowKeys makes sense. One of these scenarios is Azure Diagnostics Log analysis where events are partitioned by <a href="https://alexandrebrisebois.wordpress.com/2014/06/16/using-time-based-partition-keys-in-azure-table-storage/" target="_blank">time based PartitionKeys</a> and by compound RowKeys. This allows us to filter and find information effectively.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5534&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/10/30/azure-table-storage-using-startswith-to-filter-on-rowkeys/" target="_blank" title="#Azure Table Storage &#8211; Using StartsWith to Filter on&nbsp;RowKeys"><img width="580" height="327" src="https://alexandrebrisebois.files.wordpress.com/2014/10/search-magnifying-glass-620x350.jpg?w=580" class="attachment-large wp-post-image" alt="StartsWith" /></a></p><h1>Using StartsWith to Filter on RowKeys</h1>
<p>There are many scenarios where filtering on partial RowKeys makes sense. One of these scenarios is Azure Diagnostics Log analysis where events are partitioned by <a href="https://alexandrebrisebois.wordpress.com/2014/06/16/using-time-based-partition-keys-in-azure-table-storage/" target="_blank">time based PartitionKeys</a> and by compound RowKeys. This allows us to filter and find information effectively.</p>
<p>Event RowKeys are composed of deployment IDs, role names, instance names, categories and other information:</p>
<blockquote><p>8637d014bcf94452a1e48f393a11674b___Brisebois.WorkerRole___Brisebois.WorkerRole_IN_0___0000000001652031520___WADLogsLocalQuery</p></blockquote>
<h2>Querying WADLogsTable Effectively</h2>
<p><img src="https://alexandrebrisebois.files.wordpress.com/2014/10/2014-10-30_12-31-271.png?w=580&#038;h=175" alt="WADLogsTable" width="580" height="175" class="aligncenter size-large wp-image-5549" /><br />
The following example, shows how to target a specific table partition and filter events based on a StartsWith pattern.</p>
<pre class="brush: csharp; title: ; notranslate">
var storageAccount = Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse(connectionString);
var client = storageAccount.CreateCloudTableClient();

var table = client.GetTableReference(&quot;WADLogsTable&quot;);

// Querying Windows Azure Diagnostics by Partition for a partial RowKey
var query = new FindWithinPartitionStartsWithByRowKey(&quot;0635204061600000000&quot;, &quot;8637d014bcf94452a&quot;);
var result = query.Execute(table);
</pre>
<p><span id="more-5534"></span><br />
The <strong>FindWithinPartitionStartsWithByRowKey</strong> query returned many events from my pet project &#8216;<a href="https://alexandrebrisebois.wordpress.com/2014/02/18/this-day-on-windowsazure-will-be-back-shortly/" target="_blank">This day on Azure</a>&#8216;. As we can observe, the RowKey structure allows us to partially filter from left to right. This example shows data from a single Cloud Service. But there are times when many Cloud Service uses the same Azure Storage Account to persist Azure Diagnostics. </p>
<pre class="brush: jscript; title: ; notranslate">
{Microsoft.WindowsAzure.Storage.Table.DynamicTableEntity}
    ETag: &quot;W/\&quot;datetime'2013-11-18T21%3A17%3A38.0626707Z'\&quot;&quot;
    PartitionKey: &quot;0635204061600000000&quot;
    Properties: Count = 9
    RowKey: &quot;8637d014bcf94452a1e48f393a11674b___Brisebois.WorkerRole___Brisebois.WorkerRole_IN_0___0000000001652031489___WADLogsLocalQuery&quot;
    Timestamp: {2013-11-18 9:17:38 PM +00:00}

{Microsoft.WindowsAzure.Storage.Table.DynamicTableEntity}
    ETag: &quot;W/\&quot;datetime'2013-11-18T21%3A17%3A38.0626707Z'\&quot;&quot;
    PartitionKey: &quot;0635204061600000000&quot;
    Properties: Count = 9
    RowKey: &quot;8637d014bcf94452a1e48f393a11674b___Brisebois.WorkerRole___Brisebois.WorkerRole_IN_0___0000000001652031490___WADLogsLocalQuery&quot;
    Timestamp: {2013-11-18 9:17:38 PM +00:00}
</pre>
<h2>Filtering Within a Partition</h2>
<p>In order to produce a StartsWith search pattern with Azure Table Storage queries, one must query based on RowKey (this also works for PartitionKeys) and set the lower bound greater or equal to the StartsWith pattern. Then we must increment the last character from the lower bound string in order to produce the upper bound of the query. This will produce the desired StartsWith  capability that we all have come to cherish.  </p>
<pre class="brush: csharp; title: ; notranslate">
public class FindWithinPartitionStartsWithByRowKey
    : IQuery&lt;CloudTable, List&lt;DynamicTableEntity&gt;&gt;
{
    private readonly string partitionKey;
    private readonly string startsWithPattern;

    public FindWithinPartitionStartsWithByRowKey(string partitionKey,
        string startsWithPattern)
    {
        if (partitionKey == null)
            throw new ArgumentNullException(&quot;partitionKey&quot;);
        if (startsWithPattern == null)
            throw new ArgumentNullException(&quot;startsWithPattern&quot;);

        this.partitionKey = partitionKey;
        this.startsWithPattern = startsWithPattern;
    }

    public List&lt;DynamicTableEntity&gt; Execute(CloudTable model)
    {
        var query = new TableQuery();

        var length = startsWithPattern.Length - 1;
        var lastChar = startsWithPattern[length];

        var nextLastChar = (char) (lastChar + 1);

        var startsWithEndPattern = startsWithPattern.Substring(0, length) + nextLastChar;

        var prefixCondition = TableQuery.CombineFilters(
            TableQuery.GenerateFilterCondition(&quot;RowKey&quot;,
                QueryComparisons.GreaterThanOrEqual,
                startsWithPattern),
            TableOperators.And,
            TableQuery.GenerateFilterCondition(&quot;RowKey&quot;,
                QueryComparisons.LessThan,
                startsWithEndPattern)
            );

        var filterString = TableQuery.CombineFilters(
            TableQuery.GenerateFilterCondition(&quot;PartitionKey&quot;,
                QueryComparisons.Equal,
                partitionKey),
            TableOperators.And,
            prefixCondition
            );

        var entities = model.ExecuteQuery(query.Where(filterString));

        return entities.ToList();
    }
}
</pre>
<h2>Filtering Within a Partition Range</h2>
<p>This query is essentially the same as the previous query, but it allows us to extend our search to multiple partitions. Remember that smaller data sets produce faster results.</p>
<pre class="brush: csharp; title: ; notranslate">
public class FindWithinPartitionRangeStartsWithByRowKey
    : IQuery&lt;CloudTable, List&lt;DynamicTableEntity&gt;&gt;
{
    private readonly string partitionLowerBound;
    private readonly string partitionUpperBound;
    private readonly string startsWithPattern;

    public FindWithinPartitionRangeStartsWithByRowKey(string partitionLowerBound,
        string partitionUpperBound,
        string startsWithPattern)
    {
        if (partitionLowerBound == null)
            throw new ArgumentNullException(&quot;partitionLowerBound&quot;);
        if (partitionUpperBound == null)
            throw new ArgumentNullException(&quot;partitionUpperBound&quot;);
        if (startsWithPattern == null)
            throw new ArgumentNullException(&quot;startsWithPattern&quot;);

        this.partitionLowerBound = partitionLowerBound;
        this.partitionUpperBound = partitionUpperBound;
        this.startsWithPattern = startsWithPattern;
    }

    public List&lt;DynamicTableEntity&gt; Execute(CloudTable model)
    {
        var query = new TableQuery();

        var length = startsWithPattern.Length - 1;
        var lastChar = startsWithPattern[length];

        var nextLastChar = (char) (lastChar + 1);

        var startsWithEndPattern = startsWithPattern.Substring(0, length) + nextLastChar;

        var prefixCondition = TableQuery.CombineFilters(
            TableQuery.GenerateFilterCondition(&quot;RowKey&quot;,
                QueryComparisons.GreaterThanOrEqual,
                startsWithPattern),
            TableOperators.And,
            TableQuery.GenerateFilterCondition(&quot;RowKey&quot;,
                QueryComparisons.LessThan,
                startsWithEndPattern)
            );

        var partitionFilterString = TableQuery.CombineFilters(
            TableQuery.GenerateFilterCondition(&quot;PartitionKey&quot;,
                QueryComparisons.GreaterThanOrEqual,
                partitionLowerBound),
            TableOperators.And,
            TableQuery.GenerateFilterCondition(&quot;PartitionKey&quot;,
                QueryComparisons.LessThanOrEqual,
                partitionUpperBound)
            );

        var filterString = TableQuery.CombineFilters(
            partitionFilterString,
            TableOperators.And,
            prefixCondition
            );

        var entities = model.ExecuteQuery(query.Where(filterString));

        return entities.ToList();
    }
}
</pre>
<h2>Reusable Queries</h2>
<p>In 2012, I wrote about <a href="https://alexandrebrisebois.wordpress.com/2012/02/13/build-reusable-testable-queries-part-1/" target="_blank">building reusable and testable queries</a>. This query object interface has been tested on several of my projects and has proven to clean up solutions. It provides a way to name questions so that we can discover them by using tools like R# (ReSharper). It also has the added benefit of promoting code reuse and strongly encourages self documenting code. </p>
<p>New developers can browse the solution and discover the application&#8217;s capabilities by reading file names. Each name describes a question that is used throughout the application. </p>
<p>I have used this technique on Cloud Services, Web APIs and even on Clients. And every time I put this into practice, the code got cleaner and easier to work with.</p>
<p>A query isn&#8217;t just SQL or LINQ, it&#8217;s a question that is asked about or to something. In this specific case, <a href="https://alexandrebrisebois.wordpress.com/2013/03/12/persisting-data-in-windows-azure-table-storage-service/" target="_blank">we are asking questions to Azure Table Storage</a>, but this same pattern can be applied to business domains, databases and plain old objects.</p>
<pre class="brush: csharp; title: ; notranslate">
public interface IQuery&lt;in TModel, out TResult&gt;
{
    TResult Execute(TModel model);
}
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/table-storage/'>Table Storage</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/azure-storage/'>Azure Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/best-practices/'>Best Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/c/'>C#</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/partition/'>Partition</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/partitionkey/'>PartitionKey</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/range/'>Range</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/rowkey/'>RowKey</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/startswith/'>StartsWith</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/table-storage/'>Table Storage</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5534/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5534/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5534/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5534/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5534/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5534/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5534/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5534/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5534&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/10/30/azure-table-storage-using-startswith-to-filter-on-rowkeys/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/10/search-magnifying-glass-620x350.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/10/search-magnifying-glass-620x350.jpg?w=150" medium="image">
			<media:title type="html">StartsWith</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/10/2014-10-30_12-31-271.png?w=580" medium="image">
			<media:title type="html">WADLogsTable</media:title>
		</media:content>
	</item>
		<item>
		<title>Don&#8217;t Frown on CSVs</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/10/22/dont-frown-on-csvs/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/10/22/dont-frown-on-csvs/#comments</comments>
		<pubDate>Wed, 22 Oct 2014 18:08:13 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Analysis]]></category>
		<category><![CDATA[Avro]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[CPU]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Dataset]]></category>
		<category><![CDATA[EDI]]></category>
		<category><![CDATA[electronic data interchange]]></category>
		<category><![CDATA[HDInsight]]></category>
		<category><![CDATA[Logs]]></category>
		<category><![CDATA[MapReduce]]></category>
		<category><![CDATA[Microsoft Excel]]></category>
		<category><![CDATA[RAM]]></category>
		<category><![CDATA[Resources]]></category>
		<category><![CDATA[Table Storage]]></category>
		<category><![CDATA[Worker Role]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5490</guid>
		<description><![CDATA[CSV files are surprisingly compact. They compresses really well and allows us to work with datasets that do not fit in RAM. This low-tech solution is often overlooked and frowned upon by developers who don't get the opportunity to work with very large datasets.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5490&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/10/22/dont-frown-on-csvs/" target="_blank" title="Don&#8217;t Frown on&nbsp;CSVs"><img width="580" height="389" src="https://alexandrebrisebois.files.wordpress.com/2014/10/csv_1.png?w=580" class="attachment-large wp-post-image" alt="csv_" /></a></p><h1>Don&#8217;t Frown on CSVs</h1>
<p>In <a title="Microsoft Azure" href="http://azure.microsoft.com/en-us/" target="_blank">Microsoft Azure</a> (Azure) CSV and Avro can help you deal with unpredictable amounts of data.</p>
<p>CSV files are surprisingly compact. They compresses really well and allows us to work with datasets that do not fit in RAM. This low-tech solution is often overlooked and frowned upon by developers who don&#8217;t get the opportunity to work with very large datasets.</p>
<blockquote><p>
Root cause analysis scenarios have led me to comb through several days’ worth of logs. More often than not, this represents gigabytes worth of data. Exporting application logs to a CSV files, I was able to parse and analyze them with minimal resources.
</p></blockquote>
<p>With these two options available to us, why should we consider using the CSVs? Well, Avro is still fairly new and unsupported by most systems. CSVs can be imported into Databases, Azure Table Storage, Hadoop (HDInsight), ERPs&#8230; And a slew of other systems with minimal effort. Heck, you can even open CSV files in Microsoft Excel!<span id="more-5490"></span></p>
<p>CSVs are used for electronic data interchange (EDI) between companies. Of course, it requires the consumers to have knowledge about columns and intended data types. XML was a great idea. It brought data, structure and semantics together. Although the idea was good, it resulted in huge files.</p>
<p>Then came Avro. Avro is interesting, because like XML, it packs the structure and semantics with the data. It’s a very compact serialization protocol and even if it’s fairly new, it is natively supported by HDInsight.</p>
<p>So how do you choose between CSV and Avro? It all depends on intent. How will the files be consumed? Are these destined to be used for Big Data or are these files used to share datasets with partner companies? Who will consume the dataset?</p>
<p>Notice that I haven&#8217;t mentioned Json. That&#8217;s because Json isn&#8217;t as compact as CSV or Avro. I use Json and XML for service responses, for object graphs or for documents. I use CSV and Avro for archives, batching and cold storage.</p>
<h2>Playing Around</h2>
<p>Using <a href="https://www.nuget.org/packages/CsvHelper/" target="_blank">CsvHelper</a> I wrote 1 million times the same object in a CSV file. I&#8217;m using a Solid State Disk (SSD) and my results show that a similar operation using Avro isn&#8217;t much slower.</p>
<p>For both tests I used the following entity</p>
<pre class="brush: csharp; title: ; notranslate">
[DataContract]
public class Data
{
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string Email { get; set; }
    [DataMember]
    public double Lat { get; set; }
    [DataMember]
    public double Long { get; set; }
    [DataMember]
    public string Description { get; set; }
}
</pre>
<p>And the following instance</p>
<pre class="brush: csharp; title: ; notranslate">
static readonly Data DataInstance = new Data
{
    Id = 1000,
    Description = &quot;Established in 1985, Microsoft Canada Inc. &quot; +
                  &quot;is the Canadian subsidiary of Microsoft Corp.&quot; +
                  &quot; (Nasdaq \&quot;MSFT\&quot;), the worldwide leader in software,&quot; +
                  &quot; services and solutions that help people and&quot; +
                  &quot; businesses realize their full potential.&quot;,
    Email = &quot;example@microsoft.com&quot;,
    Lat = 45.502399d,
    Long = -73.573653d,
    Name = &quot;Microsoft, Montreal Canada&quot;
};
</pre>
<p>To Write the entities using <a href="https://www.nuget.org/packages/CsvHelper/" target="_blank">CsvHelper</a> I used the following mapping</p>
<pre class="brush: csharp; title: ; notranslate">
public class DataCsvMap : CsvClassMap&lt;Data&gt;
{
    public DataCsvMap()
    {
        Map(data =&gt; data.Id).Index(0)
                            .TypeConverterOption(NumberStyles.Integer);
        Map(data =&gt; data.Name).Index(1)
                              .TypeConverterOption(CultureInfo.InstalledUICulture);
        Map(data =&gt; data.Description).Index(2)
                                     .TypeConverterOption(CultureInfo.InstalledUICulture);
        Map(data =&gt; data.Lat).Index(3)
                             .TypeConverterOption(NumberStyles.AllowDecimalPoint);
        Map(data =&gt; data.Long).Index(4)
                              .TypeConverterOption(NumberStyles.AllowDecimalPoint);
        Map(data =&gt; data.Email).Index(5)
                               .TypeConverterOption(CultureInfo.InstalledUICulture);
    }
}
</pre>
<p>Created an empty file and executed the following to fill the file.</p>
<pre class="brush: csharp; title: ; notranslate">
private static void WriteCsv(string filePath)
{
    var streamWriter = new StreamWriter(File.Create(filePath));
    var csvSerializer = new CsvSerializer(streamWriter);
    var writer = new CsvWriter(csvSerializer);

    writer.Configuration.HasHeaderRecord = true;
    writer.Configuration.RegisterClassMap(new DataCsvMap());

    writer.WriteHeader&lt;Data&gt;();
    for (var i = 0; i &lt; 1000000; i++)
        writer.WriteRecord(DataInstance);

    writer.Dispose();
}
</pre>
<p>Then next part of my little experiment was reading all the entities sequentially from the file</p>
<pre class="brush: csharp; title: ; notranslate">
private static void ReadCsv(string filePath)
{
    using (var file = File.Open(filePath, FileMode.Open, FileAccess.Read))
    {
        var reader = new CsvReader(new StreamReader(file));

        while (reader.Read())
        {
            var data = reader.GetRecord&lt;Data&gt;();
        }
    }
}
</pre>
<p>My results were surprising!</p>
<pre class="brush: plain; title: ; notranslate">
Writing  1 000 000 records to : C:\archive.csv

Archive Size 292 MB

CSV Write Completed in 192 milliseconds

CSV Read Completed in &lt; 1 milliseconds
</pre>
<p>Then I used the <a href="https://www.nuget.org/packages/Microsoft.Hadoop.Avro/" target="_blank">Microsoft .NET Library for Avro</a> to conduct the same experiment.</p>
<p>Using the following code and the entity instance from the CSV experiment I created and filled a new archive file.</p>
<pre class="brush: csharp; title: ; notranslate">
private static void WriteAvro(string filePath)
{
    using (var file = File.Open(filePath, FileMode.Create, FileAccess.Write))
    {
        var container = AvroContainer.CreateWriter&lt;Data&gt;(file, Codec.Null);
        for (var i = 0; i &lt; 1000000; i++)
        {
            var avroWriterBlock = container.CreateBlock();
            avroWriterBlock.Write(DataInstance);
            container.WriteBlock(avroWriterBlock);
        }
        container.Close();
        file.Flush();
    }
}
</pre>
<p>Then I read all the entities sequentially from the file in order to observe possible latency.</p>
<pre class="brush: csharp; title: ; notranslate">
private static void ReadAvro(string filePath)
{
    using (var file = File.Open(filePath, FileMode.Open, FileAccess.Read))
    {
        var container = AvroContainer.CreateReader&lt;Data&gt;(file);
        while (container.MoveNext())
        {
            var data = container.Current.Objects;
        }
    }
}</pre>
<p>Once again my results caught me by surprise. I was expecting that Avro would take more time to complete the serialization.</p>
<pre class="brush: plain; title: ; notranslate">
Writing  1 000 000 records to : C:\archive.avro

Archive Size 297 MB

Avro Write Completed in 211 milliseconds

Avro Read Completed in &lt; 1 milliseconds
</pre>
<p>Although Avro performed admirably well, I believe that both formats answer to different scenarios. CSVs are a wonderful low-tech solution to a common challenge. Avro is emerging and is still limited in terms of adoption. Choosing the right format comes down to how you plan to consume the resulting dataset.</p>
<h2>CSVs on Azure</h2>
<p>When developing Cloud Services on Azure, CSVs can help keep operational costs under control by reducing the amount of resources required to process large datasets. Imagine a service whose purpose is to parse logs in order to extract telemetry. There are two approaches to this challenge. </p>
<p>The first is to load the dataset in memory and extract metrics. This can require a substantial amount of memory. Luckily, <a href="http://azure.microsoft.com/blog/2014/10/20/azures-getting-bigger-faster-and-more-open/" target="_blank">Microsoft announced the G-series (Godzilla) Virtual Machines</a> which will provide more memory and more local Solid State Drive (SSD) storage. The largest Godzilla VM will offer 448 GB RAM and 6.5 TB of local SSD storage. But think of the price tag that comes with these reserved resources…</p>
<p>As developers we forget about the Virtual Machine’s local storage (temporary storage). This is where the second approach come into to play. Using CSVs we can stream large amounts of loosely structured data from Azure Table Storage to local storage. They allow us to consume datasets line by line with a very small memory footprint. When you take a step back and think about it, this approach resembles <a href="http://en.wikipedia.org/wiki/MapReduce" target="_blank">MapReduce</a>. And because of this small memory footprint, we can get away with small A1 (1 CPU, 1.75 GB RAM, 224 GB HD) VM for about ~$63.27/mo. If the analysis requires more IOPS we can use a D1 (1 CPU, 3.5 GB RAM, 50GB SSD) VM for about ~$133.93/mo.</p>
<p>As developers we must strive to use resources responsibly. Finding ways to reduce the amount of resources necessary to support our applications, means that we can take on more load without adding more resources. Now, this is when things get interesting for everyone. By handling more load with the same amount of resources, you are effectively raising profit margins and creating new business opportunities.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/analysis/'>Analysis</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/avro/'>Avro</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/c/'>C#</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cpu/'>CPU</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/csv/'>CSV</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/data/'>Data</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dataset/'>Dataset</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/edi/'>EDI</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/electronic-data-interchange/'>electronic data interchange</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/hdinsight/'>HDInsight</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/logs/'>Logs</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/mapreduce/'>MapReduce</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-excel/'>Microsoft Excel</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/ram/'>RAM</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/resources/'>Resources</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/table-storage/'>Table Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/worker-role/'>Worker Role</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5490/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5490/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5490/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5490/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5490/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5490/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5490/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5490/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5490/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5490/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5490/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5490/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5490/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5490/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5490&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/10/22/dont-frown-on-csvs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>45.508670 -73.553992</georss:point>
		<geo:lat>45.508670</geo:lat>
		<geo:long>-73.553992</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/10/csv_1.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/10/csv_1.png?w=150" medium="image">
			<media:title type="html">csv_</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>The Greenfield to Brownfield Transition</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/10/03/the-greenfield-to-brownfield-transition/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/10/03/the-greenfield-to-brownfield-transition/#comments</comments>
		<pubDate>Fri, 03 Oct 2014 14:48:49 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[ALM]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[Brownfield]]></category>
		<category><![CDATA[Culture]]></category>
		<category><![CDATA[Discipline]]></category>
		<category><![CDATA[Feedback]]></category>
		<category><![CDATA[Greenfield]]></category>
		<category><![CDATA[Greenfield projects]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Practices]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[Technical Debt]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5463</guid>
		<description><![CDATA[The transition of a project from Greenfield to a Brownfield is an event that we can all appreciate. It's delicate and  requires attention from everyone on the team.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5463&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/10/03/the-greenfield-to-brownfield-transition/" target="_blank" title="The Greenfield to Brownfield&nbsp;Transition"><img width="580" height="387" src="https://alexandrebrisebois.files.wordpress.com/2014/10/first-career-transition.jpg?w=580" class="attachment-large wp-post-image" alt="transition" /></a></p><h1>The Greenfield to Brownfield Transition</h1>
<p>There&#8217;s a special moment in every project where it transitions from a Greenfield (new) project to a Brownfield (legacy) project. This moment usually occurs close to the second release.</p>
<p>As developers, we love Greenfield projects. It&#8217;s a new adventure where creativity runs wild and free.</p>
<p>The transition of a project from Greenfield to a Brownfield is an event that we can all appreciate. It&#8217;s delicate and requires attention from everyone on the team.<span id="more-5463"></span></p>
<p>During this transition the architecture starts to settle, patterns and practices start to immerge. New features now require developers to examine what can be reused. Quality Assurance personnel has expectations and can put more effort on exploratory testing. Team members are often called to contribute to new projects and knowledge transfer becomes crucial.</p>
<p>On Microsoft Azure (a.k.a Azure), this transition comes rather quickly. Azure is a platform that evolves at a very fast pace. Each release is accompanied with new features and services that create new opportunities. These opportunities drive teams to reassess their strategy in order to gain an edge on competitors.</p>
<p>Regular reassessment of a team&#8217;s strategy is crucial in modern development practices. The Application Lifecycle is often composed of an analysis phase, a build phase, a release phase and an observation phase.</p>
<img class="alignnone size-medium wp-image-5472" src="https://alexandrebrisebois.files.wordpress.com/2014/10/1805_teched20na20-20alm.png?w=300&#038;h=155" alt="ALM" width="300" height="155" />
<p>On regular occasions, we forget about the observation phase. This is where Brownfield projects go bad, because this forgotten phase is an invaluable source of feedback. Feedback that must be used to drive subsequent efforts.</p>
<h3>Types of Feedback</h3>
<ul>
<li><strong>Application Metrics</strong> &#8211; metrics are great at providing insight and context about a live application. They can be used to troubleshoot, monitor and identify areas that require more effort.</li>
<li><strong>Consumer Feedback</strong> &#8211; applications often use services like UserVoice to empower consumers to provide feedback about their experiences and suggestions about missing features. Remember, consumers use your application because it satisfies their needs. Missing features, quality issues and lack of support will drive them away.</li>
<li><strong>Development Metrics</strong> &#8211; development metrics including but not limited to test coverage, number of lines of code, number of defects, average number story points covered per sprint, cyclomatic complexity and number of defects versus number of new features are crucial key performance indicators (KPI) that help teams refine their practices.</li>
</ul>
<p>The success of a project depends on a successful transition from a Greenfield project to a mature Brownfield project. This transition must be prepared adequately. Failure to do so usually results in developers demanding rewrites. Those who find themselves in this delicate situation are rarely happy. They lose interest, passion and fear the code base. Our industry has named this <strong>Fear Driven Development</strong> (FDD).</p>
<p>Preparing for the transition starts on day one. A solid organic architecture that follows best practices is the foundation for everything else. Architectures are hard to change. Therefore, it requires constant attention from everyone on the team. Developers, Architects, Team Leads, Testers and Management must be critical and raise issues as they come up.</p>
<p><strong>YAGTNI</strong> (you aren&#8217;t going to need it) is a principle that helps to manage technical debt. Its premise lies in the practice of building only what you need for the current release. Building for future releases often results in rigidity that we must deal with for the project&#8217;s lifetime.</p>
<p>Rigidity robs us of future opportunities. I see this regularly, when project efforts are geared towards a database centric design. The database becomes the business domain and the application itself. A change to the database results in lots of effort because the entire application is affected. Good architectures strive to protect against this sort of rigidity by creating opportunities to use different storage strategies for different workloads.</p>
<p>Azure is all about opportunities. Using design principles like <strong>Dependency Inversion</strong>, teams build flexible designs that can evolve and adapt to an ever changing ecosystem.</p>
<p>Preserving a project&#8217;s agility is an ongoing process that starts on day one. Take time to address technical debt early. Iterate, assess and course correct on a regular basis. If your development process hinders you from producing quality software, try something different. Adapt your process as your team and project mature.</p>
<p>So the next time you&#8217;re invited to participate on a Brownfield, <strong>don&#8217;t panic</strong>. Iterate, assess and course correct. If you get invited to participate on a Greenfield project, tell yourself that it&#8217;s your chance to experience the transition. Your efforts and your open mind will make the difference.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/architecture/'>Architecture</a>, <a href='https://alexandrebrisebois.wordpress.com/category/devops/'>DevOps</a>, <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/agile/'>Agile</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/alm/'>ALM</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/application/'>Application</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/architecture/'>Architecture</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/brownfield/'>Brownfield</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/culture/'>Culture</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/devops/'>DevOps</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/discipline/'>Discipline</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/feedback/'>Feedback</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/greenfield/'>Greenfield</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/greenfield-projects/'>Greenfield projects</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/patterns/'>Patterns</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/practices/'>Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/project/'>Project</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/technical-debt/'>Technical Debt</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5463/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5463&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/10/03/the-greenfield-to-brownfield-transition/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>43.653226 -79.383184</georss:point>
		<geo:lat>43.653226</geo:lat>
		<geo:long>-79.383184</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/10/first-career-transition.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/10/first-career-transition.jpg?w=150" medium="image">
			<media:title type="html">transition</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/10/1805_teched20na20-20alm.png?w=300" medium="image">
			<media:title type="html">ALM</media:title>
		</media:content>
	</item>
		<item>
		<title>#Azure Talk &#8211; Working with Microsoft Azure Resources</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/09/23/azure-talk-working-with-microsoft-azure-resources/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/09/23/azure-talk-working-with-microsoft-azure-resources/#comments</comments>
		<pubDate>Tue, 23 Sep 2014 14:50:13 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Blobs Storage]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Diagnostics]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[MSDEVMTL]]></category>
		<category><![CDATA[PaaS]]></category>
		<category><![CDATA[Performance Counters]]></category>
		<category><![CDATA[Queue Storage]]></category>
		<category><![CDATA[SQL Database]]></category>
		<category><![CDATA[Subscription]]></category>
		<category><![CDATA[Table Storage]]></category>
		<category><![CDATA[Virtual Machine]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5434</guid>
		<description><![CDATA[Working with Microsoft Azure Resources On September 22 2014, I had the pleasure of speaking to the MSDEVMTL community about working with Microsoft Azure Resources. Microsoft Azure Resources include Blob Storage, Table Storage, Queue Storage, Service Bus, Virtual Machines, Cloud Services and SQL Database. During my talk, I introduced a couple of tools that allow [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5434&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/09/23/azure-talk-working-with-microsoft-azure-resources/" target="_blank" title="#Azure Talk &#8211; Working with Microsoft Azure&nbsp;Resources"><img width="580" height="94" src="https://alexandrebrisebois.files.wordpress.com/2014/09/2014-09-23_10-12-03.png?w=580" class="attachment-large wp-post-image" alt="MSDEVMTL" /></a></p><h2>Working with Microsoft Azure Resources</h2>
<p>On September 22 2014, I had the pleasure of speaking to the <a href="http://www.meetup.com/msdevmtl/events/201153752/" target="_blank">MSDEVMTL</a> community about working with Microsoft Azure Resources.</p>
<p>Microsoft Azure Resources include Blob Storage, Table Storage, Queue Storage, Service Bus, Virtual Machines, Cloud Services and SQL Database. During my talk, I introduced a couple of tools that allow us to work with these resources. Some tools are built by Microsoft others are built by companies like Cerebrata, Cloud Berry and Zudio.<span id="more-5434"></span></p>
<table>
<tbody>
<tr>
<td><b>Windows Azure Storage<br />
Explorer</b></td>
<td><b>Block Blob</b></td>
<td><b>Page Blob</b></td>
<td><b>Tables</b></td>
<td><b>Queues</b></td>
<td><b>Free?</b></td>
</tr>
<tr>
<td><b><a href="http://www.cerebrata.com/products/azure-explorer/introduction">Azure Explorer by Cerebrata</a></b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td></td>
<td></td>
<td><b>Y</b></td>
</tr>
<tr>
<td><b><a href="http://www.cerebrata.com/">Cerebrata Azure Management Studio</a></b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>Trial</b></td>
</tr>
<tr>
<td><b><a href="http://www.microsoft.com/en-us/download/details.aspx?id=40893">Windows Azure SDK Storage Explorer for Visual Studio 2013 (Developed by Microsoft)</a></b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td></td>
<td><b>Y</b></td>
</tr>
<tr>
<td><b><a href="http://storageexplorer.codeplex.com/">Azure Web Storage Explorer</a></b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>Y</b></td>
</tr>
<tr>
<td><b><a href="http://azurestorageexplorer.codeplex.com/">Azure Storage Explorer</a></b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>Y</b></td>
</tr>
<tr>
<td><b><a href="http://www.risefly.com/fsedwld.htm">BestSync</a></b></td>
<td><b>X</b></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><b><a href="http://www.cloudberrylab.com/default.aspx?page=explorer-azure">Cloud Berry Explorer</a></b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td></td>
<td></td>
<td><b>Y/N</b></td>
</tr>
<tr>
<td><b><a href="http://www.gapotchenko.com/cloudcombine">Cloud Combine</a></b></td>
<td><b>X</b></td>
<td></td>
<td></td>
<td></td>
<td><b>Trial</b></td>
</tr>
<tr>
<td><b><a href="http://clumsyleaf.com/products/cloudxplorer">Clumsy Leaf AzureXplorer, TableXplorer, and CloudXplorer</a></b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>Trial</b></td>
</tr>
<tr>
<td><b><a href="http://www.gladinet.com/">Gladinet Cloud Drive</a></b></td>
<td><b>X</b></td>
<td></td>
<td></td>
<td></td>
<td><b>Y</b></td>
</tr>
<tr>
<td><b><a href="https://zud.io/">Zudio</a></b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>X</b></td>
<td><b>Trial</b></td>
</tr>
</tbody>
</table>
<p>I compared and contrasted <a href="http://www.cerebrata.com/products/azure-explorer/introduction">Azure Explorer by Cerebrata</a>, <a href="http://www.cerebrata.com/">Cerebrata Azure Management Studio</a> and the Azure tools found in Visual Studio. I spoke about my personal experiences and about how I chose which tool I use based on what I need to do.</p>
<p>For example, Azure Management Studio has a great feature that allows me to <strong>export a storage table to CSV</strong>. Another great feature mentioned during my talk was the ability to <strong>copy a deployed package (cscfg and cspkg) to blob storage</strong>. This is an awesome feature! Imagine starting on a new project and being asked to redeploy a Cloud Service to a new Azure subscription. The catch, is that the person you&#8217;re replacing, used to deploy directly from Visual Studio. You have no historical Packages and absolutely no guarantee that the deployed package is the latest and greatest. Chances are that the package is a few weeks behind the source&#8230; The only option that you have, is pulling the deployed package from the Azure deployment and using it to deploy to the new Azure Subscription.</p>
<p><strong>Tip</strong>: Importing Azure Subscriptions to Azure Management Studio is easily done by importing Publish Settings. To download your Publish Settings,&nbsp;log into <a href="manage.windowsazure.com" target="_blank">manage.windowsazure.com</a> and select your desired subscription. Then browse to <a href="http://bit.ly/getmyazurecert" target="_blank">http://bit.ly/getmyazurecert</a>.</p>
<h2>Talk Slides</h2>
<iframe src='https://www.slideshare.net/slideshow/embed_code/39427137' width='580' height='475' allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/community/'>Community</a>, <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/blobs-storage/'>Blobs Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/community/'>Community</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/diagnostics/'>Diagnostics</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iaas/'>IaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/msdevmtl/'>MSDEVMTL</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/paas/'>PaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/performance-counters/'>Performance Counters</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/queue-storage/'>Queue Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/sql-database/'>SQL Database</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/subscription/'>Subscription</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/table-storage/'>Table Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5434/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5434&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/09/23/azure-talk-working-with-microsoft-azure-resources/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/09/2014-09-23_10-12-03.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/09/2014-09-23_10-12-03.png?w=150" medium="image">
			<media:title type="html">MSDEVMTL</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Releasing Memory Pressure on Memory Intensive #Azure Roles</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/09/17/releasing-memory-pressure-on-memory-intensive-azure-roles/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/09/17/releasing-memory-pressure-on-memory-intensive-azure-roles/#comments</comments>
		<pubDate>Wed, 17 Sep 2014 15:27:40 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Emulator]]></category>
		<category><![CDATA[Garbage Collection]]></category>
		<category><![CDATA[Garbage Collector]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[Memory]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Roles]]></category>
		<category><![CDATA[Startup Task]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5409</guid>
		<description><![CDATA[Traditionally, in .NET applications we adjust the Garbage Collector to operate in server mode by modifying the <strong>App.config</strong> or <strong>Web.config</strong> files. However, Worker Roles work differently because your code is actually hosted by the WaWorkerHost.exe process. So you must modify the <strong>WaWorkerHost.exe.config</strong> file instead of app.config and web.config.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5409&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/09/17/releasing-memory-pressure-on-memory-intensive-azure-roles/" target="_blank" title="Releasing Memory Pressure on Memory Intensive #Azure&nbsp;Roles"><img width="460" height="276" src="https://alexandrebrisebois.files.wordpress.com/2014/09/2fa36b2.jpg?w=460" class="attachment-large wp-post-image" alt="pressure!" /></a></p><h1>Releasing Memory Pressure</h1>
<p>Traditionally, in .NET applications we&nbsp;adjust the Garbage Collector to operate in server mode by modifying the <strong>App.config</strong> or <strong>Web.config</strong> files. However, Worker Roles work differently because your code is actually hosted by the WaWorkerHost.exe process. So you must modify the&nbsp;<strong>WaWorkerHost.exe.config</strong> file instead of app.config and web.config.</p>
<blockquote><p>This article covers the <strong>Worker Role</strong>. However, the same concepts and techniques may be used to change the <strong>Web Roles</strong> mode by changing <strong>WaWebHost.exe.config</strong> instead of <strong>WaWorkerHost.exe.config</strong>.</p></blockquote>
<p><strong>WaWorkerHost.exe.config&nbsp;is in %approot%\base\x64</strong></p>
<h2>What is ServerGC &amp; Why is it Important?</h2>
<p>The Server Garbage Collection process allows us to reclaims objects that are no longer being used, clears memory, and makes it&nbsp;available for future allocations. In contrast to the Work Station Garbage Collector mode, the Server Garbage Collection mode aggressively releases memory and can prevent your roles from running out of memory due to memory bloat.</p>
<p>Reducing memory bloat allows us to increased density, which typically <strong>reduces overall operational costs</strong> in a <em>pay for what you consume</em> environment. Furthermore, Background Server Garbage Collection can increase performance.</p>
<h3>Conditions for a Garbage Collection Include</h3>
<ul>
<li>The system has low physical memory.</li>
<li>The memory that is used by allocated objects on the managed heap surpasses an acceptable threshold. This threshold is continuously adjusted as the process runs.</li>
<li>The <a href="http://msdn.microsoft.com/en-us/library/system.gc.collect.aspx">GC.Collect</a> method is called. In almost all cases, you do not have to call this method, because the garbage collector runs continuously. This method is primarily used for unique situations and testing.</li>
</ul>
<p><span id="more-5409"></span></p>
<h2>Enabling Background Server Garbage Collection</h2>
<p>Leveraging Azure Role Starup Tasks, we call a CMD that executes a PowerShell script if the Azure Role is not executing in the Azure Emulator.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!--
//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Microsoft Public License.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
--&gt;
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;ServiceDefinition name=&quot;ServerModeGC.Solution&quot; xmlns=&quot;http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition&quot; schemaVersion=&quot;2013-10.2.2&quot;&gt;
  &lt;WorkerRole name=&quot;GCServer.Worker&quot; vmsize=&quot;Large&quot;&gt;
    &lt;Startup&gt;
      &lt;Task commandLine=&quot;ServerGC.cmd&quot; executionContext=&quot;elevated&quot; taskType=&quot;simple&quot;&gt;
        &lt;Environment&gt;
          &lt;Variable name=&quot;UseServerGC&quot; value=&quot;True&quot; /&gt;
          &lt;Variable name=&quot;UseBackgroundGC&quot; value=&quot;True&quot; /&gt;
        &lt;/Environment&gt;
      &lt;/Task&gt;
    &lt;/Startup&gt;
  &lt;/WorkerRole&gt;
&lt;/ServiceDefinition&gt;
</pre>
<p>The following Command Line pulls the desired configuration and applies them by executing the PowerShell script. Note that Azure Roles executing inside the Azure Emulator will not execute the PowerShell script.</p>
<pre class="brush: plain; title: ; notranslate">
REM *********************************************************
REM
REM     Copyright (c) Microsoft. All rights reserved.
REM     This code is licensed under the Microsoft Public License.
REM     THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
REM     ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
REM     IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
REM     PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
REM
REM *********************************************************

REM Check if the script is running in the Azure emulator and if so do not run
IF &quot;%IsEmulated%&quot;==&quot;true&quot; goto :EOF 

If &quot;%UseServerGC%&quot;==&quot;False&quot; GOTO :ValidateBackground
If &quot;%UseServerGC%&quot;==&quot;0&quot; GOTO :ValidateBackground
SET UseServerGC=&quot;True&quot;

:ValidateBackground
If &quot;%UseBackgroundGC%&quot;==&quot;False&quot; GOTO :CommandExecution
If &quot;%UseBackgroundGC%&quot;==&quot;0&quot; GOTO :CommandExecution
SET UseBackgroundGC=&quot;True&quot;

:CommandExecution

PowerShell.exe -executionpolicy unrestricted -command &quot;.\GCSettingsManagement.ps1&quot; -serverGC %UseServerGC% -backgroundGC %UseBackgroundGC%

Exit /b
</pre>
<p>This PowerShell script will create the required configuration file if it is missing or update the existing <strong>WaWorkerHost.exe.config</strong> file.</p>
<pre class="brush: powershell; title: ; notranslate">
&lt;#
//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Microsoft Public License.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#&gt;
Param
(
	$serverGC = $True,
	$backgroundGC = $True
)

[string]$configFilePath = &quot;$(${env:RoleRoot})\base\x64\WaWorkerHost.exe.config&quot;

function Create-ConfigFileIfNotExists
{
	# Only create the Xml document if it does not already exist
	if(-not (Test-Path -Path $configFilePath -PathType Leaf))
	{
		[System.Xml.XmlDocument]$document = New-Object System.Xml.XmlDocument

		# config file doesn't exist create a now one
 		[System.Xml.XmlDeclaration]$prolog = $document.CreateXmlDeclaration(&quot;1.0&quot;, &quot;utf-8&quot;, $null)
 		[System.Xml.XmlNode]$child = $document.AppendChild($prolog)
		[System.Xml.XmlElement]$configurationElement = Append-ElementIfNotExists $document $document.DocumentElement &quot;configuration&quot;

		# Save a copy of the document
		$document.Save($configFilePath)
	}
}

function Load-ConfigFile
{
	[System.Xml.XmlDocument]$document = New-Object System.Xml.XmlDocument

	#Check if the document already exists and load it if it does not
	if(Test-Path -Path $configFilePath -PathType Leaf)
	{
		$document.Load($configFilePath)
	}

	return $document
}

function Append-ElementIfNotExists
{
	param
	(
		[System.Xml.XmlDocument]$document,
		[System.Xml.XmlElement]$parent,
		[string]$elementName
	)
	[System.Xml.XmlElement]$element = $null
	[System.Xml.XmlNode]$parentNode = $parent

	if($document -ne $null)
	{
		if($parentNode -eq $null)
		{
			$parentNode = $document
		}

		$element = $parentNode.SelectSingleNode(&quot;./$($elementName)&quot;)

		if($element -eq $null)
		{
			$element = $document.CreateElement($elementName)
			[System.Xml.XmlElement]$child = $parentNode.AppendChild($element)
		}
	}

	return $element
}

function Create-ElementStructureIfNotExists
{
	param
	(
		[System.Xml.XmlDocument]$document
	)
	[bool]$isSuccess = $false

	if($document -ne $null)
	{
		[System.Xml.XmlElement]$configurationElement = Append-ElementIfNotExists $document $null &quot;configuration&quot;

		if($configurationElement -ne $null)
		{
			[System.Xml.XmlElement]$element = Append-ElementIfNotExists $document $configurationElement &quot;runtime&quot;

			$isSuccess = $element -ne $null
		}
	}

	return $isSuccess
}

# Create the document if required
Create-ConfigFileIfNotExists

# Load the configuration file into the XML document
[System.Xml.XmlDocument]$configurationDocument = Load-ConfigFile

if($configurationDocument -ne $null)
{
	if(Create-ElementStructureIfNotExists $configurationDocument)
	{
		# All of the entries are on the runtime element
		[System.Xml.XmlElement]$runtimeElement = $configurationDocument.DocumentElement.SelectSingleNode('./runtime')

		if($runtimeElement -ne $null)
		{
			# Set the Server GC to enabled if requested
			[System.Xml.XmlElement]$serverGCElement = Append-ElementIfNotExists $configurationDocument $runtimeElement &quot;gcServer&quot;
			$serverGCElement.SetAttribute(&quot;enabled&quot;, $serverGC.ToString([System.Globalization.CultureInfo]::InvariantCulture).ToLower()) 

			# Set the concurrent GC to enabled if requested
			[System.Xml.XmlElement]$concurrentGCElement = Append-ElementIfNotExists $configurationDocument $runtimeElement &quot;gcConcurrent&quot;
			$concurrentGCElement.SetAttribute(&quot;enabled&quot;, $backgroundGC.ToString([System.Globalization.CultureInfo]::InvariantCulture).ToLower())
		}
	}

	# Save the document
	$configurationDocument.Save($configFilePath)
}
</pre>
<h2>Adding the Files to the Solution</h2>
<p>Add the command and PowerShell files to the Worker Role that will be elevated. Place both files in the root directory of the Worker Role. Set the “Build Action” to “Content”, and set “Copy to Output Directory” to “Copy Always”.</p>
<h2>Find Out More</h2>
<ul>
<li><a title="Server Garbage Collection Mode in Microsoft Azure" href="http://blogs.msdn.com/b/cclayton/archive/2014/06/05/server-garbage-collection-mode-in-microsoft-azure.aspx" target="_blank">Server Garbage Collection Mode in Microsoft Azure</a></li>
<li><a title="Enable Server GC mode for your worker role" href="http://blogs.msdn.com/b/cie/archive/2013/11/14/enable-server-gc-mode-for-your-worker-role.aspx" target="_blank">Enable Server GC mode for your worker role</a></li>
<li><a title="Fundamentals of Garbage Collection" href="http://msdn.microsoft.com/en-us/library/ee787088.aspx" target="_blank">Fundamentals of Garbage Collection</a></li>
<li><a title="Garbage Collection and Performance" href="http://msdn.microsoft.com/en-us/library/ee851764.aspx" target="_blank">Garbage Collection and Performance</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/emulator/'>Emulator</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/garbage-collection/'>Garbage Collection</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/garbage-collector/'>Garbage Collector</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/gc/'>GC</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/memory/'>Memory</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft/'>Microsoft</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/performance/'>Performance</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/roles/'>Roles</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/startup-task/'>Startup Task</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/xml/'>XML</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5409/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5409/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5409/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5409&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/09/17/releasing-memory-pressure-on-memory-intensive-azure-roles/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/09/2fa36b2.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/09/2fa36b2.jpg?w=150" medium="image">
			<media:title type="html">pressure!</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>How do You Like Your Pizzas Delivered? &#8211; #Azure #PaaS</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/09/08/how-do-you-like-your-pizzas-delivered-azure-paas/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/09/08/how-do-you-like-your-pizzas-delivered-azure-paas/#comments</comments>
		<pubDate>Mon, 08 Sep 2014 15:32:09 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Hybrid Cloud]]></category>
		<category><![CDATA[IaaS]]></category>
		<category><![CDATA[PaaS]]></category>
		<category><![CDATA[SaaS]]></category>
		<category><![CDATA[Services]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5401</guid>
		<description><![CDATA[The Azure ecosystem is rich with Software as a Service (SaaS) applications that developers can use to build their own applications. SaaS provides tremendous value to developers and stakeholders because we as developers don;t have to take ownership of the functionality<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5401&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/09/08/how-do-you-like-your-pizzas-delivered-azure-paas/" target="_blank" title="How do You Like Your Pizzas Delivered? &#8211; #Azure&nbsp;#PaaS"><img width="580" height="466" src="https://alexandrebrisebois.files.wordpress.com/2014/09/paas_64e4888b.jpg?w=580" class="attachment-large wp-post-image" alt="paas_64E4888B" /></a></p><p>Personally, I&#8217;m all about Cloud Native Hyper-Scale applications. WOW! that&#8217;s a lot of buzz words in a row so let&#8217;s distill that to something more meaningful. I love the flexibility I get from <strong>Platform as a Service</strong> (PaaS). This model provides me with granular control over my application&#8217;s structure without thinking too much about the actual Virtual Machines (VMs).</p>
<p>The Azure ecosystem is rich with <strong>Software as a Service</strong> (SaaS) features that developers can use to build their own applications. SaaS provides tremendous value to developers and stakeholders because we as developers don&#8217;t have to take ownership. These are some of the SaaS features available developers on Azure today.</p>
<ul>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/sql-database/" target="_blank">Azure SQL Database</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-tables/" target="_blank">Azure Table Storage</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs/" target="_blank">Azure Blob Storage</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/service-bus/" target="_blank">Azure Service Bus</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">Azure API Management</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/documentdb/" target="_blank">Azure DocumentDB</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/search/" target="_blank">Azure Search</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/traffic-manager/" target="_blank">Azure Traffic Manager</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/cache/" target="_blank">Azure Cache</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/cdn/" target="_blank">Azure Content Delivery Network</a> (CDN)</li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/active-directory/" target="_blank">Azure Active Directory</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/notification-hubs/" target="_blank">Azure Push Notification</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/automation/" target="_blank">Azure Automation</a></li>
<li><a href="http://azure.microsoft.com/en-us/documentation/services/scheduler/" target="_blank">Azure Scheduler</a></li>
<li>&#8230;</li>
</ul>
<p>Every year, the list of services keep growing. Each service is built and maintained by Microsoft. It comes with <strong>Service Level Agreements</strong> (SLAs) and assurances around data and privacy, SLAs also means that Microsoft is responsible for support. In other words, it means that we as developers get to focus on adding business value to our application and let Microsoft worry about the details. As long as we consider performance targets while we design, we get to spend time on the code that matters most to our businesses.</p>
<p>What&#8217;s your Cloud flavor? Mine is like a buffet, I compose with PaaS, Saas, IaaS and Hybrid Cloud solutions to provide the best end user experiences.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/hybrid-cloud/'>Hybrid Cloud</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iaas/'>IaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/paas/'>PaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/saas/'>SaaS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/services/'>Services</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5401/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5401/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5401/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5401/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5401/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5401/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5401/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5401/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5401&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/09/08/how-do-you-like-your-pizzas-delivered-azure-paas/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/09/paas_64e4888b.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/09/paas_64e4888b.jpg?w=150" medium="image">
			<media:title type="html">paas_64E4888B</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>#PowerShell Invoke-RestMethod &#8211; the underlying connection was closed</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/09/05/powershell-invoke-restmethod-the-underlying-connection-was-closed/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/09/05/powershell-invoke-restmethod-the-underlying-connection-was-closed/#comments</comments>
		<pubDate>Fri, 05 Sep 2014 14:00:35 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[Invoke-RestMethod]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[TLS]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5387</guid>
		<description><![CDATA[My machine is not setup with proper certificates and PowerShell doesn't see to like that.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5387&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/09/05/powershell-invoke-restmethod-the-underlying-connection-was-closed/" target="_blank" title="#PowerShell Invoke-RestMethod &#8211; the underlying connection was&nbsp;closed"><img width="400" height="231" src="https://alexandrebrisebois.files.wordpress.com/2014/09/disconnect.jpg?w=400" class="attachment-large wp-post-image" alt="disconnect" /></a></p><h1>The underlying connection was closed</h1>
<p>For the past weeks I&#8217;ve used PowerShell to test REST APIs exposed over HTTPS. Everything was wonderful until I had to execute my script against a local instance of the service. My machine is not setup with proper certificates and PowerShell doesn&#8217;t see to like that. When ever I execute an Invoke-RestMethod command I get the following error message:</p>
<blockquote><p>The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel</p></blockquote>
<p>Looking around I was fortunate to find this one-liner that fixes everything!</p>
<pre class="brush: powershell; title: ; notranslate">
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
</pre>
<p>By turning off certificate validation you are <strong>disabling security</strong>. Beware that<strong> this one-liner is a patch</strong>, and should not be used for anything else than development purposes.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/https/'>HTTPS</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/invoke-restmethod/'>Invoke-RestMethod</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/rest/'>REST</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/ssl/'>SSL</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/tls/'>TLS</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5387/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5387&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/09/05/powershell-invoke-restmethod-the-underlying-connection-was-closed/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/09/disconnect.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/09/disconnect.jpg?w=150" medium="image">
			<media:title type="html">disconnect</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Using PowerShell to Seed #Azure DocumentDB From Blob Storage</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/08/23/using-powershell-to-seed-azure-documentdb-from-blob-storage/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/08/23/using-powershell-to-seed-azure-documentdb-from-blob-storage/#comments</comments>
		<pubDate>Sat, 23 Aug 2014 14:15:50 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Blob]]></category>
		<category><![CDATA[Blobs Storage]]></category>
		<category><![CDATA[BlockBlob]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[cmdlets]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Document]]></category>
		<category><![CDATA[DocumentCollection]]></category>
		<category><![CDATA[DocumentDB]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5352</guid>
		<description><![CDATA[These days I&#8217;m all about automation. As most of us are focused on Python, C# JavaScipt and Node I&#8217;m taking a different approach to Azure DocumentDB. This experiment&#8217;s goal is to facilitate the creation and seeding of DocumentDBs with very little effort from JSON documents stored an Azure Blob Storage container. Meet DocumentDB Azure DocumentDB [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5352&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/08/23/using-powershell-to-seed-azure-documentdb-from-blob-storage/" target="_blank" title="Using PowerShell to Seed #Azure DocumentDB From Blob&nbsp;Storage"><img width="580" height="366" src="https://alexandrebrisebois.files.wordpress.com/2014/08/2014-08-23_9-46-31.png?w=580" class="attachment-large wp-post-image" alt="2014-08-23_9-46-31" /></a></p><p>These days I&#8217;m all about automation. As most of us are focused on Python, C# JavaScipt and Node I&#8217;m taking a different approach to <a href="http://azure.microsoft.com/en-us/documentation/services/documentdb/" target="_blank">Azure DocumentDB</a>. This experiment&#8217;s goal is to facilitate the creation and seeding of <a href="http://azure.microsoft.com/en-us/documentation/services/documentdb/" target="_blank">DocumentDBs</a> with very little effort from JSON documents stored an Azure Blob Storage container.</p>
<h2>Meet DocumentDB</h2>
<blockquote><p>Azure DocumentDB is a NoSQL document database service designed from the ground up to natively support JSON and JavaScript directly inside the database engine. It’s the right solution for web and mobile applications when predictable throughput, low latency, and flexible query are key. Microsoft consumer applications like OneNote already use DocumentDB in production to support millions of users.</p></blockquote>
<p><span id="more-5352"></span></p>
<h2>Getting Started</h2>
<p>We need a DocumentDB and the best way to create one is to navigate to <a href="http://portal.azure.com" target="_blank">portal.azure.com</a>. Then click on <strong>+ NEW</strong> then <strong>Everything</strong> then <strong>Data, storage, cache, + backup</strong> and finally <strong>DocumentDB</strong>. Fill in all the required information and find something to do for the next 5 minutes (while you wait for Azure to provision your DocumentDB instance).</p>
<h2>Creating the Database &amp; Collection</h2>
<p>This adventure initially started with me trying to use the REST API directly from PowerShell. I used available <a href="http://msdn.microsoft.com/en-us/library/azure/dn781481.aspx" target="_blank">documentation </a>and fiddler to produce the following test script. Unfortunately I was unable to generate a valid <strong>authorization</strong> token from the <strong>Get-Key</strong> function.</p>
<pre class="brush: powershell; title: ; notranslate">
$DocumentDbUrl = 'https://{name}.documents.azure.com'

$DocumentDbKey = '{your key}'

$DocumentDbApiVersion = '2014-08-21'

function Get-Key {
  param
  (
    [System.String]
    $Verb,

    [System.String]
    $ResourceId = '',

    [System.String]
    $ResourceType,

    [HashTable]
    $Headers
  )

  $message = $($Verb + '\n' + $ResourceType + '\n' + $ResourceId +'\n' + $Headers.'x-ms-date' + '\n\n')

  $key = [System.Convert]::FromBase64String($DocumentDbKey)

  $hmacsha = new-object -TypeName System.Security.Cryptography.HMACSHA256 -ArgumentList (,$key) 

  $messageBytes =[Text.Encoding]::UTF8.GetBytes($message.ToLowerInvariant())
  $hash = $hmacsha.ComputeHash($messageBytes)
  $signature = [System.Convert]::ToBase64String($hash)

  return [System.Web.HttpUtility]::UrlEncode($('type=master&amp;ver=1.0&amp;sig=' + $signature))
}

function Add-Database{
  param
  (
    [System.String]
    $DbName
  )  

  $ResourceUrl = '/dbs'

  $date = Get-Date
  $utcDate = $date.ToUniversalTime()
  $dateString = $utcDate.ToString('r',[System.Globalization.CultureInfo]::InvariantCulture)

  $headers = @{
             'x-ms-date'= $dateString
              }

  $verb = 'POST'
  $resourceType ='dbs'
  $resourceId = [String]::Empty

  $authorization = Get-Key -Verb $verb -ResourceType $resourceType -ResourceId $resourceId -Headers $headers

  $headers.Add('authorization', $authorization)

  $body = '{&quot;id&quot;:&quot;'+$DbName+'&quot; }'

  $url = $($DocumentDbUrl+$ResourceUrl) 

  $response = Invoke-RestMethod -Method $verb -Uri $url -Headers $headers -Body $body

  $response | Format-List
}

Add-Database -DbName 'DocumentDatabaseName'
</pre>
<p>Executing this consistently returns</p>
<blockquote><p>Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.</p></blockquote>
<p>Not accepting this failure and wanting to setup my environments through PowerShell I decided to create my own Cmdlets.</p>
<h3>Using Cmdlets to Wrap the .NET DocumentDB Client</h3>
<p>After a couple hours of <strong>(401) Unauthorized</strong>, I decided to write a series of Cmdlets that wrap the .NET DocumentDB client library. This turned out to be faster than trying to figure out the APIs authorization token.</p>
<h4>The Cmdlets</h4>
<ul>
<li><strong>New-Context</strong> &#8211; this builds a PowerShell object that contains the DocumentDB URL and Key</li>
<li><strong>Add-Database</strong> &#8211; this creates the Database in DocumentDB and returns the Database object from which we extract the Self Link.</li>
<li><strong>Add-DocumentCollection</strong> &#8211; this creates a new Document Collection and returns the Document Collection object from which we extract the Self Link</li>
<li><strong>Import-FromBlobStorageContainer</strong> &#8211; this reads all blobs from the target container and adds each blob as a new Document to the target Document Collection</li>
</ul>
<h4>Using the Cmdlets</h4>
<pre class="brush: powershell; title: ; notranslate">
Import-Module 'DocumentDB.Cmdlet' -Force

$ctx = New-Context -Url 'https://{name}.documents.azure.com' -Key '{key}'

$database = Add-Database -Context $ctx -Name '{name}'

$collection = Add-DocumentCollection -Context $ctx -DatabaseLink $database.SelfLink -Name '{name}'

Import-FromBlobStorageContainer -Context $ctx -DocumentCollectionLink $collection.SelfLink -ContainerName '{name}' -StorageConnectionString 'DefaultEndpointsProtocol=https;AccountName={name};AccountKey={key}'
</pre>
<h3>Getting Started With Development</h3>
<p>Cmdlets are created by inheriting from one of these classes:</p>
<ul>
<li><strong>Cmdlet</strong>: A simple cmdlet using a .NET class derived from the Cmdlet base<br />
class. This type of cmdlet does not depend on the Windows PowerShell runtime<br />
and can be called directly from a .NET language.</li>
<li><strong>PSCmdlet</strong>: A more complex cmdlet based on a .NET class that derives from the<br />
PSCmdlet base class. This type of cmdlet depends on the Windows PowerShell<br />
runtime, and therefore executes within a runspace.</li>
</ul>
<p>I decided to inherit from <strong>PSCmdlet</strong>, because I will not use these Cmdlets without Windows PowerShell.&nbsp;Once you&#8217;ve chosen a base class, the&nbsp;next challenge is finding the DLL that contains the <strong>System.Management.Automation</strong> namespace.</p>
<p>There are two ways to get this DLL. The first is to install the Windows SDK which will install the DLL in <strong>Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0</strong>. The second option is to run the following PowerShell command.</p>
<pre class="brush: powershell; title: ; notranslate">
Copy ([PSObject].Assembly.Location) C:\
</pre>
<h3>DocumentDB Connection Context</h3>
<p>This Cmdlet creates a Context PSObject used to pass DocumentDB connection information for the other Cmdlets. </p>
<pre class="brush: powershell; title: ; notranslate">
[Cmdlet(VerbsCommon.New, &quot;Context&quot;)]
public class NewContext : PSCmdlet
{
    [Parameter(Position = 0,
        Mandatory = true,
        ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = &quot;DocumentDB Url&quot;)]
    public string Url { get; set; }

    [Parameter(Position = 0,
        Mandatory = true,
        ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = &quot;DocumentDB Key&quot;)]
    public string Key { get; set; }

    protected override void ProcessRecord()
    {
        var obj = new PSObject();
        obj.Properties.Add(new PSVariableProperty(new PSVariable(&quot;Url&quot;,Url)));
        obj.Properties.Add(new PSVariableProperty(new PSVariable(&quot;Key&quot;,Key)));
        WriteObject(obj);
    }
}
</pre>
<h3>DocumentDB Cmdlet Base Class</h3>
<p>This is the base class for the subsequent Cmdlets. It adds the Context object parameter at position 0.</p>
<pre class="brush: csharp; title: ; notranslate">
public abstract class DocumentDbCmdlet : PSCmdlet
{
    [Parameter(Position = 0,
        Mandatory = true,
        ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = &quot;DocumentDB Connection Information&quot;)]
    public PSObject Context { get; set; }
}
</pre>
<h3>Add-Database</h3>
<p>Using a Context and a Name, this Cmdlet uses the .NET DocumentDB client to create a new Database and returns the Database resource from which we can get a SelftLink.</p>
<pre class="brush: csharp; title: ; notranslate">
[Cmdlet(VerbsCommon.Add, &quot;Database&quot;)]
public class AddDatabase : DocumentDbCmdlet
{
    [Parameter(Position = 1,
        Mandatory = true,
        ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = &quot;Database Name&quot;)]
    public string Name { get; set; }

    protected override void ProcessRecord()
    {
        var url = base.Context.Properties[&quot;Url&quot;].Value.ToString();
        var key = base.Context.Properties[&quot;Key&quot;].Value.ToString();

        var client = new DocumentClient(new Uri(url), key);
        var task = client.CreateDatabaseAsync(new Database { Id = Name });

        task.Wait();

        WriteObject(task.Result.Resource);
    }
}
</pre>
<h3>Add-DocumentCollection</h3>
<p>Using a Context, a Name and a Database Link, this Cmdlet uses the .NET DocumentDB client to create a new Document Collection and returns the Document Collection resource from which we can get a SelftLink.</p>
<pre class="brush: csharp; title: ; notranslate">
[Cmdlet(VerbsCommon.Add, &quot;DocumentCollection&quot;)]
public class AddDocumentCollection : DocumentDbCmdlet
{
    [Parameter(Position = 1,
        Mandatory = true,
        ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = &quot;Database Link&quot;)]
    public string DatabaseLink { get; set; }

    [Parameter(Position = 2,
        Mandatory = true,
        ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = &quot;Collection Name&quot;)]
    public string Name { get; set; }

    protected override void ProcessRecord()
    {
        var url = base.Context.Properties[&quot;Url&quot;].Value.ToString();
        var key = base.Context.Properties[&quot;Key&quot;].Value.ToString();

        var client = new DocumentClient(new Uri(url), key);

        var task = client.CreateDocumentCollectionAsync(DatabaseLink,new DocumentCollection()
        {
            Id = Name
        });

        task.Wait();

        WriteObject(task.Result.Resource);
    }
}
</pre>
<h3>Add-FromBlobStorageContainer</h3>
<p>Using a Context, a Document Collection Link, a Storage Connection String and a Container Name, this Cmdlet uses the .NET DocumentDB client to create a new Document for each JSON file it finds in the Azure Blob Storage Container.</p>
<pre class="brush: csharp; title: ; notranslate">
[Cmdlet(VerbsData.Import, &quot;FromBlobStorageContainer&quot;)]
public class ImportFromBlobStorageContainer : DocumentDbCmdlet
{
    [Parameter(Position = 1,
        Mandatory = true,
        ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = &quot;Document Collection Link&quot;)]
    public string DocumentCollectionLink { get; set; }

    [Parameter(Position = 2,
        Mandatory = true,
        ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = &quot;Azure Storage Connection String&quot;)]
    public string StorageConnectionString { get; set; }

    [Parameter(Position = 3,
        Mandatory = true,
        ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true,
        HelpMessage = &quot;Blob Container Name&quot;)]
    public string ContainerName { get; set; }

    protected override void ProcessRecord()
    {
        WriteProgress(new ProgressRecord(0, &quot;Downloading List of Blobs&quot;, &quot;Reading from &quot; + ContainerName));

        var account = CloudStorageAccount.Parse(StorageConnectionString);
        var blobClient = account.CreateCloudBlobClient();
        var container = blobClient.GetContainerReference(ContainerName);

        var blobs = container.ListBlobs(useFlatBlobListing: true).ToList();

        var count = blobs.Count;

        string url = base.Context.Properties[&quot;Url&quot;].Value.ToString();
        string key = base.Context.Properties[&quot;Key&quot;].Value.ToString();

        var client = new DocumentClient(new Uri(url), key);

        var progress = new ProgressRecord(0, &quot;Importing Blobs from &quot; + ContainerName, &quot;Importing Blobs from &quot; + ContainerName);
        WriteProgress(progress);

        for (var i = 0; i &lt; count; i++)
        {
            var blockBlob = blobs[i] as CloudBlockBlob;

            if (blockBlob == null) continue;

            progress.StatusDescription = blockBlob.Name;
            WriteProgress(progress);

            blockBlob.DownloadTextAsync()
                .ContinueWith(t =&gt; client.CreateDocumentAsync(DocumentCollectionLink, t.Result))
                .Wait();
        }

        var collection = client.ReadDocumentCollectionAsync(DocumentCollectionLink);
        collection.Wait();

        WriteObject(collection.Result.Resource);
    }
}
</pre>
<h3>SnapIn</h3>
<p>In order to test the Cmdlets in Windows PowerShell ISE, I implemented a Custom PowerShell SnapIn and placed the the Cmdlet DLLs in <strong>Documents\WindowsPowerShell\Modules</strong>. This folder is read by PowerShell to find Modules. In my case, it found a folder named <strong>DocumentDB.Cmdlet</strong> which I used to import the Module.</p>
<pre class="brush: csharp; title: ; notranslate">
[RunInstaller(true)]
public class SnapIn : CustomPSSnapIn
{
    private Collection cmdlets = new Collection();
    private Collection providers = new Collection();
    private Collection types = new Collection();
    private Collection formats = new Collection();

    public SnapIn()
        : base()
    {
        cmdlets.Add(new CmdletConfigurationEntry(&quot;New-Context&quot;, typeof(NewContext), null));
        cmdlets.Add(new CmdletConfigurationEntry(&quot;Add-Database&quot;, typeof(AddDatabase), null));
        cmdlets.Add(new CmdletConfigurationEntry(&quot;Add-DocumentCollection&quot;, typeof(AddDocumentCollection), null));
        cmdlets.Add(new CmdletConfigurationEntry(&quot;Import-FromBlobStorageContainer&quot;, typeof(ImportFromBlobStorageContainer), null));
    }
    public override string Name
    {
        get { return &quot;DocumentDB Cmdlets&quot;; }
    }
    public override string Vendor
    {
        get { return &quot;Alexandre Brisebois&quot;; }
    }
    public override string VendorResource
    {
        get { return &quot;Alexandre Brisebois&quot;; }
    }
    public override string Description
    {
        get { return &quot;DocumentDB Cmdlet example&quot;; }
    }
    public override string DescriptionResource
    {
        get { return &quot;DocumentDB Cmdlet example&quot;; }
    }
    public override Collection Cmdlets
    {
        get { return cmdlets; }
    }

    public override Collection Providers
    {
        get { return providers; }
    }

    public override Collection Types
    {
        get { return types; }
    }

    public override Collection Formats
    {
        get { return formats; }
    }
}
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/blob/'>Blob</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blobs-storage/'>Blobs Storage</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/blockblob/'>BlockBlob</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/c/'>C#</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cmdlets/'>cmdlets</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/container/'>Container</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/document/'>Document</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/documentcollection/'>DocumentCollection</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/documentdb/'>DocumentDB</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/json/'>JSON</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/nosql/'>NoSQL</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/rest/'>REST</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5352/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5352/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5352/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5352&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/08/23/using-powershell-to-seed-azure-documentdb-from-blob-storage/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/08/2014-08-23_9-46-31.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/2014-08-23_9-46-31.png?w=150" medium="image">
			<media:title type="html">2014-08-23_9-46-31</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Semantic Logging Application Block (SLAB) &#8211; Out-of-process Service is not Logging to #Azure Table Storage?</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/08/22/semantic-logging-application-block-slab-out-of-process-service-is-not-logging-to-azure-table-storage/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/08/22/semantic-logging-application-block-slab-out-of-process-service-is-not-logging-to-azure-table-storage/#comments</comments>
		<pubDate>Fri, 22 Aug 2014 13:29:30 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Application Block]]></category>
		<category><![CDATA[Azure Cloud Services]]></category>
		<category><![CDATA[Configurations]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Out-of-Process]]></category>
		<category><![CDATA[Semantic]]></category>
		<category><![CDATA[SLAB]]></category>
		<category><![CDATA[Windows Service]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5343</guid>
		<description><![CDATA[With the latest update of the Semantic Logging Application Block &#8211; Out-of-process Service NuGet Package, the user under which the Windows Service is executed has changed. In hopes to save you countless hours of debugging I am sharing the configurations that should be used on Azure Cloud Services. When you start the Out-of-Process service be [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5343&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>With the latest update of the <a href="https://www.nuget.org/packages/EnterpriseLibrary.SemanticLogging.Service/" target="_blank">Semantic Logging Application Block &#8211; Out-of-process Service</a> NuGet Package, the user under which the Windows Service is executed has changed. In hopes to save you countless hours of debugging I am sharing the configurations that should be used on Azure Cloud Services.</p>
<p>When you start the Out-of-Process service be sure to specify the LocalSystem account.</p>
<pre class="brush: powershell; title: ; notranslate">
SemanticLogging-svc.exe -s -a=LocalSystem
</pre>
<p>Failure to execute under the right account will prevent the Out-of-Process service from logging Events to Azure Table Storage.</p>
<ul>
<li><a href="https://www.nuget.org/packages/EnterpriseLibrary.SemanticLogging.Service/" target="_blank">Semantic Logging Application Block &#8211; Out-of-process Service</a></li>
<li><a href="http://slab.codeplex.com/SourceControl/latest#Readme.txt" target="_blank">Semantic Logging Application Block &#8211; Source Code &amp; Samples</a></li>
</ul>
<h2>What is SLAB?</h2>
<blockquote><p>The <strong>Semantic Logging Application Block</strong> (<strong>SLAB</strong>) provides a set of destinations (sinks) to persist application events published using a subclass of the EventSource class from the System.Diagnostics.Tracing namespace. Sinks include Azure table storage, SQL Server databases, file, console and rolling files with several formats and you can extend the block by creating your own custom formatters and sinks. The console sink is part of this nuget package. Other Sinks mentioned above are available as separate nuget packages. For the sinks that can store structured data, the block preserves the full structure of the event payload in order to facilitate analysing or processing the logged data.</p></blockquote><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/application-block/'>Application Block</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/azure-cloud-services/'>Azure Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/configurations/'>Configurations</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/devops/'>DevOps</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/logging/'>Logging</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/out-of-process/'>Out-of-Process</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/semantic/'>Semantic</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/slab/'>SLAB</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/windows-service/'>Windows Service</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5343/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5343/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5343/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5343&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/08/22/semantic-logging-application-block-slab-out-of-process-service-is-not-logging-to-azure-table-storage/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>#PowerShell Module for the #Azure API Management REST APIs</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/08/17/powershell-module-for-the-azure-api-management-rest-apis/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/08/17/powershell-module-for-the-azure-api-management-rest-apis/#comments</comments>
		<pubDate>Mon, 18 Aug 2014 00:36:20 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[API Management]]></category>
		<category><![CDATA[Authorization]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5324</guid>
		<description><![CDATA[What is Azure API Management Microsoft Azure API Management is a service that helps protect your mission critical systems with authentication, rate limiting, quotas and caching to ease load under pressure. Rest easy knowing that only the partners, developers and applications you&#8217;ve authorized have access to your APIs and that those groups are acting in [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5324&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/08/17/powershell-module-for-the-azure-api-management-rest-apis/" target="_blank" title="#PowerShell Module for the #Azure API Management REST&nbsp;APIs"><img width="580" height="326" src="https://alexandrebrisebois.files.wordpress.com/2014/08/api-management.png?w=580" class="attachment-large wp-post-image" alt="api-management" /></a></p><h1>What is Azure API Management</h1>
<p><a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">Microsoft Azure API Management</a> is a service that helps protect your mission critical systems with authentication, rate limiting, quotas and caching to ease load under pressure. Rest easy knowing that only the partners, developers and applications you&#8217;ve authorized have access to your APIs and that those groups are acting in accordance with your policies. Find out more on <a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">Azure.com</a></p>
<h2>REST APIs</h2>
<p>Like many services on Azure, <a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">API Management</a> provides us with a comprehensive REST API. This API allows us to manage <strong>Users</strong>, <strong>Groups</strong>, <strong>Products</strong> and <strong>Subscriptions</strong>.</p>
<p>Working on a multi-region solution, I was really happy to see these APIs. One of the recurring challenges I face everyday, is to replicate my efforts across multiple deployments sprawled over many Azure regions. Now the only way to do this effectively is to <a href="https://alexandrebrisebois.wordpress.com/2014/07/31/automate-everything/" target="_blank">automating everything</a>!</p>
<p>As of August 2014 <a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">API Management</a> is still in public preview and is going through constant evolution. New features make their way to production and pieces fall together. The newly released REST APIs are just that, a piece that was missing. Wanting to reduce my workload I decided to create a PowerShell Module to help automate some of my repetitive tasks.</p>
<blockquote><p><strong>Note</strong>: The API does not allow you to define APIs, Representations. The Developer Portal CMS is not accessible through these APIs. Although these are things I would love to interact with through the REST API, I&#8217;m hopeful that something will come along.</p></blockquote>
<p>Before we start, there are a couple things we need to do. First we need to activate the Management APIs on our <a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">API Management</a> service. Then we need to generate an access token. I opted for the manual process which you can follow on the <a href="http://msdn.microsoft.com/en-us/library/azure/dn798668.aspx" target="_blank">Azure API Management REST API Authentication</a> page.<span id="more-5324"></span></p>
<p>Then in our PowerShell ISE set both the REST API URL and the Access Token to global variable and we&#8217;re good to go.</p>
<pre class="brush: powershell; title: ; notranslate">
Set-Variable -Name authorizatoin -Value 'SharedAccessSignature uid=5{id}&amp;ex={date-time}&amp;sn={signature}'
Set-Variable -Name serviceUrl -Value 'https://{service}.management.azure-api.net'
</pre>
<p>The first thing I tried was to <strong>Add</strong> a <strong>User</strong>. Then I needed a way to validate this first action, so I decided to <strong>List</strong> <strong>Users</strong>. And finally, I needed a way to clean up after my test so I <strong>Removed</strong> the <strong>User</strong> I created.</p>
<pre class="brush: powershell; title: ; notranslate">
#This is the ID I will use to Add and Remove the User
$userID = [guid]::NewGuid()

Add-User -ID $userID -FirstName 'alexandre' -LastName 'brisebois' -Email 'alexandre@test.com' -Password 'test' -State active -Note 'test account will be delete'

#Listing Users so that I can validate that it was added
$users = Get-Users
$users.value | Format-Table -AutoSize

Remove-User -id $('/users/'+$userID)

#Listing Users so that I can validate that it was removed
$users = Get-Users
$users.value | Format-Table -AutoSize
</pre>
<p>The next step in my adventure was to traverse the graph from each resource group. I started by traversing the <strong>User</strong> graph.</p>
<pre class="brush: powershell; title: ; notranslate">
# Getting a list of all Users
$users = Get-Users

foreach($u in $users.value)
{
    # Getting a User by ID
    $user = Get-User -id $u.id
    $user | Format-List

    # Getting the Groups to which a User belogs
    $groups = Get-UserGroupList -id $user.id
    $groups.value | Format-Table -AutoSize

    # Getting the Users Subscriptions
    $subscriptions = Get-UserSubscriptionList -id $user.id
    $subscriptions | Format-Table -AutoSize
}
</pre>
<p>Traversing the <strong>Groups</strong> was very similar and allows us to drill down to list Users per group.</p>
<pre class="brush: powershell; title: ; notranslate">
# Getting a list of all the Groups
$groups = Get-Groups

foreach($g in $groups.value)
{
  # Getting a Group by ID
  $group = Get-Group -id $g.id

  # Getting a Group's User list
  $users = Get-Groupusers -id $group.id

  foreach($u in $users.value)
  {
    $u | Format-List
  }
}
</pre>
<p>Traversing <strong>Products</strong> came just as naturally</p>
<pre class="brush: powershell; title: ; notranslate">
# Getting a list of Products
$products = Get-Products

foreach($p in $products.Value)
{
  # Getting a Product by ID
  Get-Product -id $p.id | Format-List

  # Getting a list of APIs that belong to a Product
  $apiList = Get-ProductApiList -id $p.id

  foreach($a in $apiList.Value)
  {
    # Getting an API by ID
    $api = Get-API -id $a.id 

    $api | Format-List
  }
}
</pre>
<h2>REST API Wrapper PowerShell Module</h2>
<pre class="brush: powershell; title: ; notranslate">
function Add-Version
{
  param
  (
    [System.String]
    $url
  )

  $version ='2014-02-14'

  return $($url+'?api-version='+$version)
}

function Invoke-ApiManagementResource
{
  param
  (
    [System.String]
    $MethodUrl,

    [System.String]
    $Authorization,

    [System.String]
    $Body,

    [System.String]
    $ContentType

  )

  $dict = @{}
  $dict.Add('Authorization',$authorization)

  $response = Invoke-RestMethod -Method 'POST' -Uri $(Add-Version -url $MethodUrl) -Headers $dict -ContentType $ContentType -Body $body

  return $response
}

function Remove-ApiManagementResource
{
  param
  (
    [System.String]
    $MethodUrl,

    [System.String]
    $Authorization,

    [System.String]
    $Body,

    [System.String]
    $ETag,

    [System.String]
    $ContentType

  )

  $dict = @{}
  $dict.Add('Authorization',$authorization)
  $dict.Add('If-Match',$ETag)

  $response = Invoke-RestMethod -Method 'DELETE' -Uri $(Add-Version -url $MethodUrl) -Headers $dict -ContentType $ContentType
  return $response
}

function Update-ApiManagementResource
{
  param
  (
    [System.String]
    $MethodUrl,

    [System.String]
    $Authorization,

    [System.String]
    $Body,

    [System.String]
    $ContentType

  )

  $dict = @{}
  $dict.Add('Authorization',$authorization)

  $response = Invoke-RestMethod -Method 'PUT' -Uri $(Add-Version -url $MethodUrl) -Headers $dict -ContentType $ContentType -Body $body

  return $response
}

function Get-ApiManagementResourceMetadata
{
  param
  (
    [System.String]
    $MethodUrl,

    [System.String]
    $Authorization,

    [System.String]
    $ContentType

  )

  $dict = @{}
  $dict.Add('Authorization',$authorization)

  $response = Invoke-WebRequest -Method 'HEAD' -Uri $(Add-Version -url $MethodUrl) -Headers $dict -ContentType $ContentType

  return $response
}

function Get-ApiManagementResource
{
  param
  (
    [System.String]
    $MethodUrl,

    [System.String]
    $Authorization,

    [System.String]
    $ContentType

  )

  $dict = @{}
  $dict.Add('Authorization',$authorization)

  $response = Invoke-RestMethod -Method 'GET' -Uri $(Add-Version -url $MethodUrl) -Headers $dict -ContentType $ContentType

  return $response
}

function Get-Products
{
    return Get-ApiManagementResource -MethodUrl $($serviceUrl+'/products') -Authorization $authorizatoin -ContentType $contentType
}

function Get-Product
{
   param
   (
     [System.String]
     $id
   )

    return Get-ApiManagementResource -MethodUrl $($serviceUrl+''+$id) -Authorization $authorizatoin -ContentType $contentType
}

function Get-API
{
   param
   (
     [System.String]
     $id
   )

    return Get-ApiManagementResource -MethodUrl $($serviceUrl+''+$id) -Authorization $authorizatoin -ContentType $contentType
}

function Get-ProductApiList
{
   param
   (
     [System.String]
     $id
   )

    return Get-ApiManagementResource -MethodUrl $($serviceUrl+''+$id+'/apis') -Authorization $authorizatoin -ContentType $contentType
}

function Get-ProductMetadata
{
   param
   (
     [System.String]
     $id
   )

    $response = Get-ApiManagementResourceMetadata -MethodUrl $($serviceUrl+''+$id) -Authorization $authorizatoin -ContentType $contentType

    return $response.Headers.'ETag'
}

function Get-Users
{
    return Get-ApiManagementResource -MethodUrl $($serviceUrl+'/users') -Authorization $authorizatoin -ContentType $contentType
}

function Get-User
{
   param
   (
     [System.String]
     $id
   )

    return Get-ApiManagementResource -MethodUrl $($serviceUrl+''+$id) -Authorization $authorizatoin -ContentType $contentType
}

function Get-UserMetadata
{
   param
   (
     [System.String]
     $id
   )

    $response = Get-ApiManagementResourceMetadata -MethodUrl $($serviceUrl+''+$id) -Authorization $authorizatoin -ContentType $contentType

    return $response.Headers.'ETag'
}

function Remove-User
{
   param
   (
     [System.String]
     $id
   )

    $etag = Get-UserMetadata  -id $id
    return Remove-ApiManagementResource -MethodUrl $($serviceUrl+''+$id) -Authorization $authorizatoin -ContentType $contentType -ETag $etag
}

function Add-User
{
   param
   (
     [System.String]
     $ID,

     [System.String]
     $FirstName,

     [System.String]
     $LastName,

     [System.String]
     $Email,

     [System.String]
     $Password,

     [System.String]
     [ValidateSet('active','blocked')]
     $State,

     [System.String]
     $Note = ''
   )

    $body = @{}
    $body.Add('firstName',$FirstName)
    $body.Add('lastName',$LastName)
    $body.Add('email',$Email)
    $body.Add('note',$Note)
    $body.Add('password',$Password)
    $body.Add('state',$State)

    return Update-ApiManagementResource -MethodUrl $($serviceUrl+'/users/'+$ID) -Authorization $authorizatoin -Body $(ConvertTo-Json $body) -ContentType $contentType
}

function Get-UserGroupList
{
   param
   (
     [System.String]
     $id
   )

    return Get-ApiManagementResource -MethodUrl $($serviceUrl+''+$id+'/groups') -Authorization $authorizatoin -ContentType $contentType
}

function Get-UserSubscriptionList
{
   param
   (
     [System.String]
     $id
   )

    return Get-ApiManagementResource -MethodUrl $($serviceUrl+''+$id+'/subscriptions') -Authorization $authorizatoin -ContentType $contentType
}

function Get-Groups
{
    return Get-ApiManagementResource -MethodUrl $($serviceUrl+'/groups') -Authorization $authorizatoin -ContentType $contentType
}

function Get-Group
{
   param
   (
     [System.String]
     $id
   )

    return Get-ApiManagementResource -MethodUrl $($serviceUrl+''+$id) -Authorization $authorizatoin -ContentType $contentType
}

function Get-GroupUsers
{
   param
   (
     [System.String]
     $id
   )

    return Get-ApiManagementResource -MethodUrl $($serviceUrl+''+$id+'/users') -Authorization $authorizatoin -ContentType $contentType
}

function Get-Subscriptions
{
    return Get-ApiManagementResource -MethodUrl $($serviceUrl+'/subscriptions') -Authorization $authorizatoin -ContentType $contentType
}

Set-Variable -Name contentType -Value 'application/json'

Export-ModuleMember 'Add-Version'
Export-ModuleMember 'Get-ApiManagementResource'
Export-ModuleMember 'Get-ApiManagementResourceMetadata'
Export-ModuleMember 'Remove-ApiManagementResource'
Export-ModuleMember 'Update-ApiManagementResource'
Export-ModuleMember 'Invoke-ApiManagementResource'
Export-ModuleMember 'Get-Subscriptions'
Export-ModuleMember 'Add-User'
Export-ModuleMember 'Remove-User'
Export-ModuleMember 'Get-Users'
Export-ModuleMember 'Get-User'
Export-ModuleMember 'Get-UserGroupList'
Export-ModuleMember 'Get-UserSubscriptionList'
Export-ModuleMember 'Get-Products'
Export-ModuleMember 'Get-Product'
Export-ModuleMember 'Get-ProductMetadata'
Export-ModuleMember 'Get-ProductApiList'
Export-ModuleMember 'Get-Groups'
Export-ModuleMember 'Get-Group'
Export-ModuleMember 'Get-GroupUsers'
Export-ModuleMember 'Get-API'
</pre>
<h2>Release Note</h2>
<p>This is my preliminary attempt at using the API Management REST APIs for Automation. This script is a great starting point for those who wish to follow the same path. The code is available on GitHub <a href="https://github.com/brisebois/Brisebois.Azure.PowerShell" target="_blank">https://github.com/brisebois/Brisebois.Azure.PowerShell</a></p>
<p>My first impression of these APIs is that it&#8217;s discoverable, well documented and easy to use from PowerShell.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/api-management/'>API Management</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/authorization/'>Authorization</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/automation/'>Automation</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/devops/'>DevOps</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/rest/'>REST</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5324/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5324/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5324/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5324&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/08/17/powershell-module-for-the-azure-api-management-rest-apis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/08/api-management.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/api-management.png?w=150" medium="image">
			<media:title type="html">api-management</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Using PowerShell to Rebuild #Azure SQL Database Indexes</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/08/16/using-powershell-to-rebuild-azure-sql-database-indexes/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/08/16/using-powershell-to-rebuild-azure-sql-database-indexes/#comments</comments>
		<pubDate>Sun, 17 Aug 2014 01:42:24 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[SQL Database]]></category>
		<category><![CDATA[ADO.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Indexes]]></category>
		<category><![CDATA[Maintenance]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SQL Data Sync]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5304</guid>
		<description><![CDATA[If indexes aren't maintained, your application will slow down. Queries may timeout and users may look for alternatives. Rebuilding indexes is something we overlook on a regular basis, along with missing indexes, it can really harm the overall performance of an application.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5304&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/08/16/using-powershell-to-rebuild-azure-sql-database-indexes/" target="_blank" title="Using PowerShell to Rebuild #Azure SQL Database&nbsp;Indexes"><img width="580" height="580" src="https://alexandrebrisebois.files.wordpress.com/2014/08/clean.jpg?w=580" class="attachment-large wp-post-image" alt="clean" /></a></p><h1>Rebuilding&nbsp;SQL Database Indexes</h1>
<p>A few months ago I wrote a blog post titled &#8220;<a href="https://alexandrebrisebois.wordpress.com/2013/02/06/dont-forget-about-index-maintenance-on-windows-azure-sql-database/" target="_blank">Don’t Forget About Index Maintenance on Azure SQL Database</a>&#8220;. Since then, Microsoft Azure SQL Database has changed&nbsp;a lot. We aren&#8217;t as concerned about the size of the database anymore, because databases can reach 500 GB in size. Take a moment to think about that number. <strong>500GB is a lot of data!</strong>&nbsp;Before you get excited and move on to more important things, ask yourself&nbsp;this question, <a href="https://alexandrebrisebois.wordpress.com/2013/02/15/does-your-data-really-belong-in-your-sql-database/" target="_blank">does all that data really belong in my SQL Database?</a>&nbsp;Put some thought into it, you may be surprised by the answers you come up with.<span id="more-5304"></span></p>
<p>So if we&#8217;re not as concerned about size, why should we care about index fragmentation. Well, if indexes aren&#8217;t maintained, your application will slow down. Queries may timeout and users may look for alternatives. Rebuilding indexes is something we overlook on a regular basis, along with missing indexes, it can really harm the overall performance of an&nbsp;application.</p>
<p>Since I started <a href="https://alexandrebrisebois.wordpress.com/2014/07/31/automate-everything/" target="_blank">automating everything</a>, I decided it was time to revamp the console application from my earlier post. I reused bits from a couple of blog posts and produced something that will make my life easier. The following PowerShell script is a mix of C# and PowerShell. It takes in the Server name, the Database name, the Username and the Password to build its execution context.</p>
<pre class="brush: powershell; title: ; notranslate">
Start-SqlDatabaseIndexRebuild  -Server '' -Database '' -User '' -Password ''
</pre>
<p>Optionally you can override the default Fragmentation Percentage Threshold of 10%. Ideally, you don&#8217;t want to rebuild costly indexes too often, but you don;t want them to get out of hand either. Since you cannot REORGANIZE indexes on SQL Database, I tent to rebuild earlier than we&#8217;re used to on SQL Server.</p>
<p>Use this script to rebuild indexes on your Microsoft SQL Databases, it will skip SQL Data Sync tables and will inspect&nbsp;User Tables for fragmented indexes. Feel free to adapt it to your needs. This code is available on&nbsp;my <a href="https://github.com/brisebois/Brisebois.Azure.PowerShell" target="_blank">Azure PowerShell GitHub Repository</a>.</p>
<pre class="brush: powershell; title: ; notranslate">
&lt;#
.Synopsis
  This will scan a Microsoft Azure SQL Database for Indexes whose Index fragmentation is greater than the defined threshold percentage and will rebuild them sequentially.
.DESCRIPTION
   Be sure to rebuild fragmented indexes on a regular basis on Azure SQL Database. Fragmentation increases Index size and results in slower queries.
.EXAMPLE
   Start-SqlDatabaseIndexRebuild -Server '' -Database '' -User '' -Password ''
.EXAMPLE
   Start-SqlDatabaseIndexRebuild  -Server '' -Database '' -User '' -Password '' -FragmentationPercentageThreshold 10
#&gt;
Function Start-SqlDatabaseIndexRebuild
{
  [CmdletBinding()]
  Param
  (
    # SQL Database Server
    [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)]
    [string]
    $Server,

    # SQL Database Name
    [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)]
    [string]
    $Database,

    # SQL Database Username
    [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=2)]
    [string]
    $User,

    # SQL Database Password
    [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=3)]
    [string]
    $Password,

    # Fragmentation Percentage Threshold used to select indexes to defragment
    [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=4)]
    [int]
    $FragmentationPercentageThreshold = 10,

    # A flag used to skip tables created by Azure SQL DataSync
    [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=5)]
    [bool]
    $SkipSqlDataSyncTables = $true
  )

  $assemblies = (
    'System.Data',
    'System.Collections',
    'System.Data.DataSetExtensions',
    'System.Xml',
    'System.Linq'
  ) 

  $source = @'
    using System;
    using System.Linq;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Globalization;

    public class DbContext
    {
        public string Server { get; set; }
        public string Database { get; set; }
        public string User { get; set; }
        public string Password { get; set; }

        private string ConnectionString
        {
            get
            {
                return String.Format(CultureInfo.InvariantCulture,
                                     &quot;Server=tcp:{0}.database.windows.net,1433;Database={1};User ID={2}@{0};Password={3};Trusted_Connection=False;Encrypt=True;Connection Timeout=3600;&quot;,
                                     Server,
                                     Database,
                                     User,
                                     Password);
            }
        }

        const string listTablesQuery = @&quot;SELECT o.name AS [table_name]
                                            FROM  sys.objects AS o
                                            WHERE o.is_ms_shipped = 0 AND o.[type] = 'U'&quot;;
        public List GetTableNames()
        {
            return Query(listTablesQuery)
                        .AsEnumerable()
                        .Select(r =&gt; r[0].ToString())
                        .ToList();
        }

        const string findFragmentedIndexesQuery = @&quot;SELECT name, avg_fragmentation_in_percent
                                                    FROM sys.dm_db_index_physical_stats (
                                                            DB_ID(N'DatabaseName')
                                                            , OBJECT_ID('{0}')
                                                            , NULL
                                                            , NULL
                                                            , NULL) AS a
                                                    JOIN sys.indexes AS b
                                                    ON a.object_id = b.object_id AND a.index_id = b.index_id
                                                    WHERE avg_fragmentation_in_percent &gt; {1}&quot;;

        public Hashtable GetFragmentedTableIndexes(string table, int fragmentationThreshold)
        {
            return ToIndexTableMap(table, Query(string.Format(CultureInfo.InvariantCulture,
                findFragmentedIndexesQuery,
                table,
                fragmentationThreshold)));
        }

        private static Hashtable ToIndexTableMap(string table, DataTable indexes)
        {
            var t = new Hashtable();
            foreach (var i in indexes.AsEnumerable())
                t.Add(i[0],i[1]);    

            return t;
        }

        private DataTable Query(string query)
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                connection.Open();

                var command = new SqlCommand(query, connection);
                var reader = new SqlDataAdapter(command);
                var table = new DataTable();
                reader.Fill(table);
                return table;
            }
        }

        const string rebuildIndex = &quot;ALTER INDEX [{0}] ON [{1}] REBUILD WITH (ONLINE=ON);&quot;;

        public int RebuildIndex(string indexName, string table)
        {
            return Command(string.Format(CultureInfo.InvariantCulture, rebuildIndex, indexName, table));
        }

        private int Command(string cmd)
        {
            using (var connection = new SqlConnection(ConnectionString))
            {
                connection.Open();

                var command = new SqlCommand(cmd, connection);
                return command.ExecuteNonQuery();
            }
        }
    }
'@

  Add-Type -Language CSharp -TypeDefinition $source -ReferencedAssemblies $assemblies

  $db = New-Object DBContext
  $db.Server = $Server
  $db.Database = $Database
  $db.User = $User
  $db.Password = $Password    

  Write-Verbose 'Connecting'

  $tables = $db.GetTableNames()

  Write-Verbose $('Found ' + $tables.Count + ' Tables')

  $percent = 0
  $tableIndex = 0

  foreach($t in $tables){

    if($SkipSqlDataSyncTables -and $t.Contains('dss'))
    {
      Write-Warning $('Skipping  Table ' + $t)
      continue
    }

    $indexes = $db.GetFragmentedTableIndexes($t, $FragmentationPercentageThreshold)
    foreach($i in $indexes.Keys)
    {
      $message = 'Successful'
      try
      {
        $result = $db.RebuildIndex($i,$t)
      }
      catch
      {
        $message = 'Failed'
        Write-Warning $(&quot;Exception Message: $($_.Exception.Message)&quot;)
      }
      finally
      {
        Write-Verbose $($message + ' Rebuild &gt; Table '+ $t+ ' Index ' + $i + ' fragmented @ '+ $indexes[$i] + '%')
      }
    }
    $tableIndex ++
    $percent = ($tableIndex/$tables.Count) * 100
    Write-Progress $t -PercentComplete $percent
  }
}
</pre><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/sql-database/'>SQL Database</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/ado-net/'>ADO.NET</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/c/'>C#</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/indexes/'>Indexes</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/maintenance/'>Maintenance</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/sql-data-sync/'>SQL Data Sync</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/sql-database/'>SQL Database</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/t-sql/'>T-SQL</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5304/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5304&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/08/16/using-powershell-to-rebuild-azure-sql-database-indexes/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<georss:point>45.508670 -73.553992</georss:point>
		<geo:lat>45.508670</geo:lat>
		<geo:long>-73.553992</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/08/clean.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/clean.jpg?w=150" medium="image">
			<media:title type="html">clean</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Using PowerShell to Authenticate Against OAuth &#8211; #Azure API Management</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/08/13/using-powershell-to-authenticate-against-oauth-azure-api-management/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/08/13/using-powershell-to-authenticate-against-oauth-azure-api-management/#comments</comments>
		<pubDate>Thu, 14 Aug 2014 02:16:54 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Access Token]]></category>
		<category><![CDATA[API Management]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[ConvertFrom-Json]]></category>
		<category><![CDATA[DTO]]></category>
		<category><![CDATA[GET]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Invoke-RestMethod]]></category>
		<category><![CDATA[Invoke-WebRequest]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[OAuth 2.0]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5275</guid>
		<description><![CDATA[From development to deployment, PowerShell is becoming the 'go to' automation technology on Microsoft Azure. So, I decided to use PowerShell to perform automated tests against a Web API (a.k.a REST service). These tests are built to run during the execution of a Continuous Release cycle and confirm that the API is responding as expected.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5275&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/08/13/using-powershell-to-authenticate-against-oauth-azure-api-management/" target="_blank" title="Using PowerShell to Authenticate Against OAuth &#8211; #Azure API&nbsp;Management"><img width="580" height="385" src="https://alexandrebrisebois.files.wordpress.com/2014/08/security_dxo.jpg?w=580" class="attachment-large wp-post-image" alt="security_DxO" /></a></p><h1>Using PowerShell to Authenticate Against OAuth</h1>
<p>From development to deployment, PowerShell is becoming the &#8216;go to&#8217; automation technology on Microsoft Azure. So, I decided to use PowerShell to perform automated tests against a Web API (a.k.a REST service). These tests are built to run during the execution of a Continuous Release cycle and confirm that the API is responding as expected.</p>
<p><span id="more-5275"></span></p>
<p>The Web API I&#8217;m testing is exposed to the outside world through<span class="apple-converted-space"> </span><a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">Microsoft Azure API Management</a>. Therefore, consumers of my API must subscribe and must use a Subscription Key for every request. This key is used to authenticate against <a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">Microsoft Azure API Management</a>, which acts as a proxy between the outside world and the Web API. The Subscription Key does not authenticate the client against the Web API. Therefore, clients must authenticate by posting requests to the OAuth endpoint.</p>
<h2>Getting an Access Token from OAuth on Azure API Management</h2>
<pre class="brush: powershell; title: ; notranslate">
#OAuth Basic Token
$basicToken = 'Basic lots-of-alphanumerics=='

#API Management URL &amp; Key
$url = 'https://test.azure-api.net/api/token'
$subscriptionKey = 'lots-of-alphanumerics'

#Service User Info
$username ='brisebois'
$password = 'zxcvbnm'

#Getting an Access Token
$context = Get-ApiToken -methodUrl $url -username $username -password $password -authorization $basicToken -subscriptionkey $subscriptionKey

#Testing the AccessToken by making a GET request against the API
$peoplelistUrl = 'https://test.azure-api.net/api/people'

$peopleList = Get-ApiResource -methodurl $peoplelistUrl -oauthContext $context -subscriptionkey $subscriptionKey
</pre>
<h2>Wait! How Does That Work?</h2>
<p>First I need a Data Transfer Object (DTO). This DTO will be used to make subsequent secured calls to the Web API.</p>
<pre class="brush: powershell; title: ; notranslate">
Add-Type @'
    using System;
    public class OAuthContext{
        public string AccessToken{get;set;}
        public string TokenType{get;set;}
        public string ExpiresIn{get;set;}
        public string RefreshToken{get;set;}
    }
'@
</pre>
<p>Using <strong>Invoke-RestMethod</strong> to authenticate against an OAtuh endpoint, I encapsulate the response in an OAuthContext instance. I decided to use <strong>Invoke-RestMethod</strong> instead of <strong>Invoke-WebRequest</strong> because it automatically applies <strong>ConvertFrom-Json</strong> to the response. This is quite useful, because I can work directly with the object.</p>
<p>Headers for the request need an IDictionary collection. In PowerShell, we use a Hash collection to store key/value pairs. I really want to highlight this, because it took me a couple of minutes to find out how to satisfy the IDictionary dependency. The following will create a collection to which you can add your headers.</p>
<pre class="brush: powershell; title: ; notranslate">
$dict = @{}
$dict.Add('Authorization',$authorization)
</pre>
<p>I&#8217;m sure I could have done this differently, but considering that I&#8217;m still new to PowerShell, I&#8217;m pretty happy with the outcome. The following builds a request that is used to authenticate against an OAuth endpoint that is exposed through <a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">Microsoft Azure API Management</a>. Notice that I systematically add the Subscription Key as a query string, this is done so that <a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">Microsoft Azure API Management</a> allows us to reach the API.</p>
<pre class="brush: powershell; title: ; notranslate">
function Get-ApiToken([string]$methodUrl, [string]$username,[string] $password,[string] $authorization, [string] $subscriptionkey)
{
  $methodtype = 'POST'
  $contentType = 'application/x-www-form-urlencoded'

  $dict = @{}
  $dict.Add('Authorization',$authorization)

  $methodURL = $methodURL+'?subscription-key='+$subscriptionkey

  $body = [System.Text.Encoding]::UTF8.GetBytes('grant_type=password&amp;username='+$username+'&amp;password='+$password) 

  $response = Invoke-RestMethod -Method $methodtype -Uri $methodUrl -Headers $dict -ContentType $contentType -Body $body

  $context = New-Object OAuthContext

  $context.AccessToken = $response.access_token
  $context.ExpiresIn = $response.expires_in
  $context.RefreshToken = $response.refresh_token
  $context.TokenType = $response.token_type

  return $context
}
</pre>
<p>To test the acquired <strong>Access Token</strong> I perform a <strong>GET</strong> request against a resource exposed by my Web API. The following creates a <strong>GET</strong> request and returns the Json payload as an object to the caller.</p>
<pre class="brush: powershell; title: ; notranslate">
function Get-ApiResource([string]$methodurl,[OAuthContext]$oauthContext,[string]$subscriptionkey)
{
	$headers = @{}
	$headers.Add('Authorization',$oauthContext.TokenType + ' ' + $oauthContext.AccessToken)

	$methodtype = 'GET'
	$methodurl = $methodurl+'?subscription-key='+$subscriptionkey

	return Invoke-RestMethod -Method $methodtype -Uri $methodurl -Headers $headers
}
</pre>
<h2>That was Cool, What&#8217;s Next?</h2>
<p>The goal of this post was provide a happy path REST call against a Web API exposed through <a href="http://azure.microsoft.com/en-us/documentation/services/api-management/" target="_blank">Microsoft Azure API Management</a>. These examples lack error handling, retry policies and everything else needed to create robust solutions. Use this is a starting point, but remember that it still needs a lot of love.</p>
<p>Do you use PowerShell to make requests to Web APIs (a.k.a REST services)? Have you done this using different a technique? I very curious to find out what I missed.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/access-token/'>Access Token</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/api-management/'>API Management</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/authentication/'>Authentication</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/c/'>C#</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/convertfrom-json/'>ConvertFrom-Json</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dto/'>DTO</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/get/'>GET</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/http/'>HTTP</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/invoke-restmethod/'>Invoke-RestMethod</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/invoke-webrequest/'>Invoke-WebRequest</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft/'>Microsoft</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/oauth-2-0/'>OAuth 2.0</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/rest/'>REST</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5275/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5275&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/08/13/using-powershell-to-authenticate-against-oauth-azure-api-management/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/08/security_dxo.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/security_dxo.jpg?w=150" medium="image">
			<media:title type="html">security_DxO</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>How do You Version Packages?</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/08/11/how-do-you-version-components-and-services/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/08/11/how-do-you-version-components-and-services/#comments</comments>
		<pubDate>Mon, 11 Aug 2014 16:01:33 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[ALM]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Nuget]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[Semantic Versioning]]></category>
		<category><![CDATA[Version]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5253</guid>
		<description><![CDATA[This topic seems to come up regularly. And is usually a friction point for teams because many of us do this differently. In an attempt to standardize versioning and to remove this friction point I decided to promote Semantic Versioning (http://semver.org/).<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5253&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/08/11/how-do-you-version-components-and-services/" target="_blank" title="How do You Version&nbsp;Packages?"><img width="580" height="166" src="https://alexandrebrisebois.files.wordpress.com/2014/08/version.png?w=580" class="attachment-large wp-post-image" alt="Version" /></a></p><h1>How do You Version Packages?</h1>
<p>This topic seems to come up regularly. And is usually a friction point for teams because many of us do this differently. In an attempt to standardize versioning and to remove this undesired friction I decided to promote <strong>Semantic Versioning</strong> (<a href="http://semver.org/" rel="nofollow">http://semver.org/</a>).<span id="more-5253"></span></p>
<h2>Familiarizing Ourselves with Semantic Versioning</h2>
<blockquote><p>This is not a new or revolutionary idea. In fact, you probably do something close to this already. The problem is that &#8220;close&#8221; isn&#8217;t good enough. Without compliance to some sort of formal specification, version numbers are essentially useless for dependency management. By giving a name and clear definition to the above ideas, it becomes easy to communicate your intentions to the users of your package. Once these intentions are clear, flexible (but not too flexible) dependency specifications can finally be made.</p></blockquote>
<p>Given a version number is composed of the following 4 parts: MAJOR.MINOR.PATCH and INCREMENT. The recommended approach to incrementing each part is as follows:</p>
<ol>
<li><strong>MAJOR</strong> version when you make incompatible API changes</li>
<li><strong>MINOR</strong> version when you add functionality in a backwards-compatible manner</li>
<li><strong>PATCH</strong> version when you make backwards-compatible bug fixes</li>
<li><strong>INCREMENT</strong> version when you make a build (should be automatically set by the build server)</li>
</ol>
<p>Additional labels for pre-release and build metadata are available as extensions to this format.</p>
<p>NuGet has wonderful <a href="http://docs.nuget.org/docs/reference/versioning" target="_blank">documentation about versioning</a>. The following package versions illustrate the flexibility that we get from using metadata. In this list, we can clearly observe the distinctions created by the use of metadata.</p>
<p>1.0.0.0-preview<br />
1.0.0.0-rc<br />
1.0.0.0-alpha<br />
1.0.0.0-beta<br />
1.0.0.0</p>
<p>To summarize, the template for a package version is <strong>MAJOR</strong>.<strong>MINOR</strong>.<strong>PATCH</strong>.<strong>INCREMENT</strong><br />
optionally we can add <strong>-METADATA</strong> to denote various stages of preview packages.</p>
<h2>Why is this Standard Important?</h2>
<p>Having a standard in place simplifies the communication of intent to the consumers of your packages. Seeing that a package has changed <strong>MAJOR</strong> versions is a clear indicator for consumers to review a packages’s release notes. In turn, helping the consumers save countless hours of troubleshooting because of breaking changes.</p>
<p>Noticing a <strong>MINOR</strong>, <strong>PATCH</strong> or <strong>INCREMENT</strong> version change should not be alarming to the consumers of the package. This type of version change should be welcomed with greater confidence. Release notes remain important, but should not convey any breaking changes.</p>
<h2>Should we Produce Release Notes?</h2>
<p>The short answer is <strong>YES</strong>. Release notes should documents fundamental changes to the component. These are especially important for <strong>MAJOR </strong>versions. <strong>MINOR </strong>and <strong>PATCH </strong>versions also deserve to have release notes, but I consider these to be relaxed because these versions should be backward compatible and should be tested accordingly.</p>
<h2 style="font:bold 24px/33.59px 'Helvetica Neue', Helvetica, Arial, sans-serif;color:#404040;text-transform:none;text-indent:0;letter-spacing:normal;margin-bottom:10px;word-spacing:0;white-space:normal;font-size-adjust:none;font-stretch:normal;">Safely Updating Packages Through NuGet</h2>
<p style="font:13px/18px 'Helvetica Neue', Helvetica, Arial, sans-serif;color:#333333;text-transform:none;text-indent:0;letter-spacing:normal;margin-bottom:9px;word-spacing:0;white-space:normal;font-size-adjust:none;font-stretch:normal;">In a blog post by <a href="https://alexandrebrisebois.wordpress.com/wp-admin/blog.decayingcode.com" target="_parent">Maxime Rouiller</a> titled <a href="http://blog.decayingcode.com/post/nugetupgrading-your-packages-like-a-boss" target="_parent">NuGet–Upgrading your packages like a boss</a> we get introduced to NuGet&#8217;s <strong>-Safe</strong> flag. If everyone applies <strong>Semantic</strong> <strong>Versioning</strong> to their packages, this flag can definitely become your best friend, because it can save you countless hours of refactoring and debugging. By using this flag you are assured that only PATCH versions are applied to your solution. Find out how this work by reading his blog post.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/alm/'>ALM</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/best-practices/'>Best Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/nuget/'>Nuget</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/package/'>Package</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/semantic-versioning/'>Semantic Versioning</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/version/'>Version</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5253/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5253/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5253/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5253&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/08/11/how-do-you-version-components-and-services/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/08/version.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/version.png?w=150" medium="image">
			<media:title type="html">Version</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Busy (Starting role&#8230; Sites were deployed.) #Azure Role Diagnostics</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/08/07/busy-starting-role-sites-were-deployed-azure-role-diagnostics/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/08/07/busy-starting-role-sites-were-deployed-azure-role-diagnostics/#comments</comments>
		<pubDate>Thu, 07 Aug 2014 18:51:48 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Bindings]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Event Viewer]]></category>
		<category><![CDATA[Fusion Logging]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Remote Desktop]]></category>
		<category><![CDATA[Roles]]></category>
		<category><![CDATA[Troubleshooting]]></category>
		<category><![CDATA[Virtual Machine]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5204</guid>
		<description><![CDATA[Busy&#8230; Starting Role… Repeat So you deployed a Cloud Service and it&#8217;s status is stuck on &#8220;Busy (Starting role&#8230; Sites were deployed.)&#8221; By now you&#8217;ve probably checked the SDK assembly versions, checked that your Cloud Service runs in the Azure Emulator and probably everything else that you could think of. So what&#8217;s next? In August [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5204&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/08/07/busy-starting-role-sites-were-deployed-azure-role-diagnostics/" target="_blank" title="Busy (Starting role&#8230; Sites were deployed.) #Azure Role&nbsp;Diagnostics"><img width="580" height="329" src="https://alexandrebrisebois.files.wordpress.com/2014/08/2014-08-06_19-11-563.png?w=580" class="attachment-large wp-post-image" alt="2014-08-06_19-11-56" /></a></p><h1>Busy&#8230; Starting Role… Repeat</h1>
<p>So you deployed a Cloud Service and it&#8217;s status is stuck on &#8220;<strong>Busy (Starting role&#8230; Sites were deployed.)</strong>&#8221; By now you&#8217;ve probably checked the SDK assembly versions, checked that your Cloud Service runs in the Azure Emulator and probably everything else that you could think of. So what&#8217;s next?</p>
<p>In August 2013&nbsp;<a class="internal-link view-user-profile" href="http://blogs.msdn.com/350567/ProfileUrlRedirect.ashx">Kevin Williamson</a>&nbsp;published an awesome blog series titled&nbsp;<a href="http://blogs.msdn.com/b/kwill/archive/2013/08/09/windows-azure-paas-compute-diagnostics-data.aspx" target="_blank">Windows Azure PaaS Compute Diagnostics Data</a>. It contains a wealth of priceless information that ended my<strong> 24 hour debug session</strong>.<span id="more-5204"></span></p>
<p>Since my Cloud Service already had a Remote Desktop Connection setup at publish time, I went a head with the proposed path to diagnose the issue. This adventure ended abruptly as I was presented with this prompt.</p>
<img class="aligncenter wp-image-5225 size-large" src="https://alexandrebrisebois.files.wordpress.com/2014/08/2014-08-06_19-42-09.png?w=580&#038;h=231" alt="2014-08-06_19-42-09" width="580" height="231" />
<p>I decided remove the Remote Desktop configurations from my Cloud Service and to redeploy it to Azure. This allowed me to&nbsp;try to&nbsp;dynamically&nbsp;enable Microsoft Azure Remote Desktop. I used this <a href="http://channel9.msdn.com/Series/DIY-Windows-Azure-Troubleshooting/Dynamically-Enabling-Windows-Azure-Remote-Desktop" target="_blank">DIY Microsoft Azure Troubleshooting Tutorial</a>&nbsp;which takes you through the steps.</p>
<p>After a few minutes, I was finally able to open a Remote Desktop session to one of my Cloud Service Role instances. Finally I got a glimpse of light from the other end of the tunnel!</p>
<p>Troubleshooting effectively and in a timely manner requires you to install a couple tools. I was happy to find out that Microsoft has made this process easy for us. On the Azure VM hosting the Cloud Service Role open a&nbsp;PowerShell console and&nbsp;Copy/Paste and Run the following script</p>
<pre class="brush: plain; title: ; notranslate">md c:\tools; Import-Module bitstransfer; Start-BitsTransfer http://dsazure.blob.core.windows.net/azuretools/AzureTools.exe c:\tools\AzureTools.exe;c:\tools\AzureTools.exe</pre>
<p>*This only works on Guest OS Family 2 or later</p>
<p>PowerShell will start AzureTools and present you with the following screen. Right click on the tool of you choice to select download from the context menu.</p>
<img class="aligncenter size-large wp-image-5235" src="https://alexandrebrisebois.files.wordpress.com/2014/08/2451-image_thumb_12fa6343.png?w=580&#038;h=481" alt="2451.image_thumb_12FA6343" width="580" height="481" />
<p>Generally when I troubleshoot, I usually need a way to persist files to blob storage. The second tab in AzureTools allows you to do just that.</p>
<img class="aligncenter size-large wp-image-5234" src="https://alexandrebrisebois.files.wordpress.com/2014/08/1780-image_thumb_290bdfb3.png?w=580&#038;h=481" alt="1780.image_thumb_290BDFB3" width="580" height="481" />
<p>The third tab is full of great shortcuts and tools that&nbsp;help you focus on finding the root cause you&#8217;re after.</p>
<img class="aligncenter size-large wp-image-5236" src="https://alexandrebrisebois.files.wordpress.com/2014/08/7206-image_thumb_2cbc8bb0.png?w=580&#038;h=481" alt="7206.image_thumb_2CBC8BB0" width="580" height="481" />
<p>From this tab you can start by clicking the <strong>Open Log Files. </strong>This will open logs that could shed some light into what&#8217;s going on. I started by looking at the&nbsp;<strong>WaAppAgent.log</strong> from which I got a view at a log showing the Role starting and stopping on a regular interval. Then I looked at the&nbsp;<strong>AppAgentRuntime.log</strong>, this provided me with a lot more information and I got lost for a little while. If something is going wrong, this is a great place to start. it&#8217;s got lots and lots of detailed information about the Roles.</p>
<blockquote><p><strong>Open Log Files</strong> – This will open the current log file for all of the log files most commonly used when troubleshooting on an Azure VM (see <a href="http://blogs.msdn.com/b/kwill/archive/2013/08/09/windows-azure-paas-compute-diagnostics-data.aspx" target="_blank">Windows Azure PaaS Compute Diagnostics Data</a>).&nbsp; This is useful when you are troubleshooting an issue and you don’t quite know where to begin looking so you want to see all of the data without having to go searching for all of it</p></blockquote>
<p>Then I navigated to the <strong>Event Viewer</strong> to get a feel for the exceptions that could be contributing to the Role&#8217;s behavior.</p>
<img class="aligncenter size-large wp-image-5239" src="https://alexandrebrisebois.files.wordpress.com/2014/08/2014-08-07_1-01-24.png?w=580&#038;h=354" alt="2014-08-07_1-01-24" width="580" height="354" />
<p>From the<strong> Windows Azure Event Log</strong> I was able to&nbsp;find clues as to what was happening.</p>
<pre class="brush: plain; title: ; notranslate">
WaIISHost
Role entrypoint could not be created: System.TypeLoadException: Unable to load the role entry point due to the following exceptions:
-- System.IO.FileLoadException: Could not load file or assembly 'System.Web.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'System.Web.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
</pre>
<p>This started to be helpful, but which library is actually depending on this dependency? To find this information, go to the third tab in the AzureTools and click on <strong>Fusion Logging</strong>. This turns on or off .NET Fusion Logging verbose output. Remember that this slows down the Role, but it provides you with insights about&nbsp;Bindings and dependencies between assemblies.</p>
<pre class="brush: plain; title: ; notranslate">
=== Pre-bind state information ===
LOG: DisplayName = System.Web.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
 (Fully-specified)
LOG: Appbase = file:///E:/approot/bin
LOG: Initial PrivatePath = E:\approot\bin
Calling assembly : WebApi.OutputCache.V2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: E:\base\x64\WaIISHost.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from D:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: System.Web.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: Attempting download of new URL file:///E:/approot/bin/System.Web.Http.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Minor Version
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
</pre>
<p>Having identified the dependency that cause this issue I decided to <a href="https://github.com/filipw/AspNetWebApi-OutputCache" target="_blank">contribute to the GitHub project</a> by updating all of it&#8217;s dependencies and it&#8217;s target framework to 4.5.1. The code can be downloaded from my <a href="https://github.com/brisebois/aspnetwebapi-outputcache" target="_blank">GitHub repository</a>. Subsequently, I created a <a href="https://github.com/filipw/AspNetWebApi-OutputCache/pull/88" target="_blank">pull request</a> so that everyone working on the latest version of Web API may benefit from this adventure.</p>
<p>If you&#8217;re curious about Azure Roles and about troubleshooting them I recommend that you browse through the following resources. I found them to be very good at pointing me in the right direct when I was out of ideas.</p>
<ul>
<li><a href="http://blogs.msdn.com/b/kwill/" target="_blank">Windows Azure &#8211; Troubleshooting &amp; Debugging</a></li>
<li><a href="http://blogs.msdn.com/b/kwill/archive/2013/08/26/azuretools-the-diagnostic-utility-used-by-the-windows-azure-developer-support-team.aspx" target="_blank">The Diagnostic Utility used by the Windows Azure Developer Support Team</a></li>
<li><a href="http://blogs.msdn.com/b/kwill/archive/2013/08/20/troubleshooting-scenario-1-role-recycling.aspx" target="_blank">Troubleshooting Scenario 1 – Role Recycling</a></li>
<li><a href="http://blogs.msdn.com/b/kwill/archive/2013/08/26/troubleshooting-scenario-2-role-recycling-after-running-fine-for-2-weeks.aspx" target="_blank">Troubleshooting Scenario 2 – Role Recycling After Running Fine For 2 Weeks</a></li>
<li><a href="http://blogs.msdn.com/b/kwill/archive/2013/09/06/troubleshooting-scenario-3-role-stuck-in-busy.aspx" target="_blank">Troubleshooting Scenario 3 – Role Stuck in Busy</a></li>
<li><a href="http://blogs.msdn.com/b/kwill/archive/2013/09/06/troubleshooting-scenario-4-windows-azure-traffic-manager-degraded-status.aspx" target="_blank">Troubleshooting Scenario 4 &#8211; Windows Azure Traffic Manager Degraded Status</a></li>
<li><a href="http://blogs.msdn.com/b/kwill/archive/2013/09/19/troubleshooting-scenario-5-internal-server-error-500-in-webrole.aspx" target="_blank">Troubleshooting Scenario 5 – Internal Server Error 500 in WebRole</a></li>
<li><a href="http://blogs.msdn.com/b/kwill/archive/2013/09/23/troubleshooting-scenario-6-role-recycling-after-running-for-some-time.aspx" target="_blank">Troubleshooting Scenario 6 – Role Recycling After Running For Some Time</a></li>
<li><a href="http://blogs.msdn.com/b/kwill/archive/2013/10/03/troubleshooting-scenario-7-role-recycling.aspx" target="_blank">Troubleshooting Scenario 7 – Role Recycling</a></li>
<li><a href="http://channel9.msdn.com/Series/DIY-Windows-Azure-Troubleshooting">DIY Microsoft Azure&nbsp;Troubleshooting</a></li>
<li><a href="http://channel9.msdn.com/Series/DIY-Windows-Azure-Troubleshooting/Enabling-Windows-Azure-Remote-Desktop-When-Publishing" target="_blank">Enabling Microsoft Azure Remote Desktop When&nbsp;Publishing</a></li>
</ul>
<h1>Diagnostic Data Locations</h1>
<blockquote><p>This list includes the most commonly used data sources used when troubleshooting issues in a PaaS VM, roughly ordered by importance (ie. the frequency of using the log to diagnose issues).</p>
<ul>
<li><strong>Windows Azure Event Logs</strong> – <em>Event Viewer –&gt; Applications and Services Logs –&gt; Windows Azure</em>
<ul>
<li>Contains key diagnostic output from the Windows Azure Runtime, including information such as Role starts/stops, startup tasks, OnStart start and stop, OnRun start, crashes, recycles, etc.</li>
<li>This log is often overlooked because it is under the “Applications and Services Logs” folder in Event Viewer and thus not as visible as the standard Application or System event logs.</li>
<li>This one diagnostic source will help you identify the cause of several of the most common issues with Azure roles failing to start correctly – startup task failures, and crashing in OnStart or OnRun.</li>
<li>Captures crashes, with callstacks, in the Azure runtime host processes that run your role entrypoint code (ie. WebRole.cs or WorkerRole.cs).</li>
</ul>
</li>
<li><strong>Application Event Logs</strong> – <em>Event Viewer –&gt; Windows Logs –&gt; Application</em>
<ul>
<li>This is standard troubleshooting for both Azure and on-premise servers.&nbsp; You will often find w3wp.exe related errors in these logs.</li>
</ul>
</li>
<li><strong>App Agent Runtime Logs</strong> – <em>C:\Logs\AppAgentRuntime.log</em>
<ul>
<li>These logs are written by WindowsAzureGuestAgent.exe and contain information about events happening within the guest agent and the VM.&nbsp; This includes information such as firewall configuration, role state changes, recycles, reboots, health status changes, role stops/starts, certificate configuration, etc.</li>
<li>This log is useful to get a quick overview of the events happening over time to a role since it logs major changes to the role without logging heartbeats.</li>
<li>If the guest agent is not able to start the role correctly (ie. a locked file preventing directory cleanup) then you will see it in this log.</li>
</ul>
</li>
<li><strong>App Agent Heartbeat Logs</strong> – <em>C:\Logs\WaAppAgent.log</em>
<ul>
<li>These logs are written by WindowsAzureGuestAgent.exe and contain information about the status of the health probes to the host bootstrapper.</li>
<li>The guest agent process is responsible for reporting health status (ie. Ready, Busy, etc) back to the fabric, so the health status as reported by these logs is the same status that you will see in the Management Portal.</li>
<li>These logs are typically useful for determining what is the current state of the role within the VM, as well as determining what the state was at some time in the past.&nbsp; With a problem description like “My website was down from 10:00am to 11:30am yesterday”, these heartbeat logs are very useful to determine what the health status of the role was during that time.</li>
</ul>
</li>
<li><strong>Host Bootstrapper Logs</strong> – <em>C:\Resources\WaHostBootstrapper.log</em>
<ul>
<li>This log contains entries for startup tasks (including plugins such as Caching or RDP) and health probes to the host process running your role entrypoint code (ie. WebRole.cs code running in WaIISHost.exe).</li>
<li>A new log file is generated each time the host bootstrapper is restarted (ie. each time your role is recycled due to a crash, recycle, VM restart, upgrade, etc) which makes these logs easy to use to determine how often or when your role recycled.</li>
</ul>
</li>
<li><strong>IIS Logs</strong> &#8211; <em>C:\Resources\Directory\{DeploymentID}.{Rolename}.DiagnosticStore\LogFiles\Web</em>
<ul>
<li>This is standard troubleshooting for both Azure and on-premise servers.</li>
<li>One key problem scenario where these logs are often overlooked is the scenario of “My website was down from 10:00am to 11:30am yesterday”.&nbsp; The natural tendency is to blame Azure for the outage (“My site has been working fine for 2 weeks, so it must be a problem with Azure!”), but the IIS logs will often indicate otherwise.&nbsp; You may find increased response times immediately prior to the outage, or non-success status codes being returned from IIS, which would indicate a problem within the website itself (ie. in the ASP.NET code running in w3wp.exe) rather than an Azure issue.</li>
</ul>
</li>
<li><strong>Performance Counters</strong> – <em>perfmon, or Windows Azure Diagnostics</em>
<ul>
<li>This is standard troubleshooting for both Azure and on-premise servers.</li>
<li>The interesting aspect of these logs in Azure is that, assuming you have setup WAD ahead of time, you will often have valuable performance counters to troubleshoot problems which occurred in the past (ie. &#8220;My website was down from 10:00am to 11:30am yesterday&#8221;).</li>
<li>Other than specific problems where you are gathering specific performance counters, the most common uses for the performance counters gathered by WAD is to look for regular performance counter entries, then a period of no entries, then resuming the regular entries (indicating a scenario where the VM was potentially not running), or 100% CPU (usually indicating an infinite loop or some other logic problem in the website code itself).</li>
</ul>
</li>
<li><strong>HTTP.SYS Logs</strong> – <em>D:\WIndows\System32\LogFiles\HTTPERR</em>
<ul>
<li>This is standard troubleshooting for both Azure and on-premise servers.</li>
<li>Similar to the IIS Logs, these are often overlooked but very important when trying to troubleshoot an issue with a hosted service website not responding.&nbsp; Often times it can be the result of IIS not being able to process the volume of requests coming in, the evidence of which will usually show up in the HTTP.SYS logs.</li>
</ul>
</li>
<li><strong>IIS Failed Request Log Files</strong> &#8211; <em>C:\Resources\Directory\{DeploymentID}.{Rolename}.DiagnosticStore\FailedReqLogFiles</em>
<ul>
<li>This is standard troubleshooting for both Azure and on-premise servers.</li>
<li>This is not turned on by default in Windows Azure and is not frequently used.&nbsp; But if you are troubleshooting IIS/ASP.NET specific issues you should consider turning FREB tracing on in order to get additional details.</li>
</ul>
</li>
<li><strong>Windows Azure Diagnostics Tables and Configuration</strong> &#8211; <em>C:\Resources\Directory\{DeploymentID}.{Rolename}.DiagnosticStore\Monitor</em>
<ul>
<li>This is the local on-VM cache of the Windows Azure Diagnostics (WAD) data.&nbsp; WAD captures the data as you have configured it, stores in in custom .TSF files on the VM, then transfers it to storage based on the scheduled transfer period time you have specified.</li>
<li>Unfortunately because they are in a custom .TSF format the contents of the WAD data are of limited use, however you can see the diagnostics configuration files which are useful to troubleshoot issues when Windows Azure Diagnostics itself is not working correctly.&nbsp; Look in the Configuration folder for a file called config.xml which will include the configuration data for WAD.&nbsp; If WAD is not working correctly you should check this file to make sure it is reflecting the way that you are expecting WAD to be configured.</li>
</ul>
</li>
<li><strong>Windows Azure Caching Log Files</strong> &#8211; <em>C:\Resources\Directory\{DeploymentID}.{Rolename}.DiagnosticStore\AzureCaching</em>
<ul>
<li>These logs contain detailed information about Windows Azure role-based caching and can help troubleshoot issues where caching is not working as expected.</li>
</ul>
</li>
<li><strong>WaIISHost Logs</strong> &#8211; <em>C:\Resources\Directory\{DeploymentID}.{Rolename}.DiagnosticStore\WaIISHost.log</em>
<ul>
<li>This contains logs from the WaIISHost.exe process which is where your role entrypoint code (ie. WebRole.cs) runs for WebRoles.&nbsp; The majority of this information is also included in other logs covered above (ie. the Windows Azure Event Logs), but you may occasionally find additional useful information here.</li>
</ul>
</li>
<li><strong>IISConfigurator Logs</strong> &#8211; <em>C:\Resources\Directory\{DeploymentID}.{Rolename}.DiagnosticStore\IISConfigurator.log</em>
<ul>
<li>This contains information about the IISConfigurator process which is used to do the actual IIS configuration of your website per the model you have defined in the service definition files.</li>
<li>This process rarely fails or encounters errors, but if IIS/w3wp.exe does not seem to be setup correctly for your service then this log is the place to check.</li>
</ul>
</li>
<li><strong>Role Configuration Files</strong> – <em>C:\Config\{DeploymentID}.{DeploymentID.{Rolename}.{Version}.xml</em>
<ul>
<li>This contains information about the configuration for your role such as settings defined in the ServiceConfiguration.cscfg file, LocalResource directories, DIP and VIP IP addresses and ports, certificate thumbprints, Load Balancer Probes, other instances, etc.</li>
<li>Similar to the Role Model Definition File, this is not a log file which contains runtime generated information, but can be useful to ensure that your service is being configured in the way that you are expecting.</li>
</ul>
</li>
<li><strong>Role Model Definition File</strong> – <em>E:\RoleModel.xml (or F:\RoleModel.xml)</em>
<ul>
<li>This contains information about how your service is defined according to the Azure Runtime, in particular it contains entries for every startup task and how the startup task will be run (ie. background, environment variables, location, etc).&nbsp; You will also be able to see how your &lt;sites&gt; element is defined for a web role.</li>
<li>This is not a log file which contains runtime generated information, but it will help you validate that Azure is running your service as you are expecting it to.&nbsp; This is often helpful when a developer has a particular version of a service definition on his development machine, but the build/package server is using a different version of the service definition files.</li>
</ul>
</li>
</ul>
<p><strong><em>* A note about ETL files</em></strong></p>
<p>If you look in the C:\Logs folder you will find RuntimeEvents_{iteration}.etl and WaAppAgent_{iteration}.etl files.&nbsp; These are ETW traces which contain a compilation of the information found in the Windows Azure Event Logs, Guest Agent Logs, and other logs.&nbsp; This is a very convenient compilation of all of the most important log data in an Azure VM, but because they are in ETL format it requires a few extra steps to consume the information.&nbsp; If you have a favorite ETW viewing tool then you can ignore several of the above mentioned log files and just look at the information in these two ETL files.
</p></blockquote>
<p>Find more details from&nbsp;: <a href="http://blogs.msdn.com/b/kwill/archive/2013/08/09/windows-azure-paas-compute-diagnostics-data.aspx" target="_blank">Windows Azure PaaS Compute Diagnostics Data</a></p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/cloud-services-azure/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/bindings/'>Bindings</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/devops/'>DevOps</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/event-viewer/'>Event Viewer</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/fusion-logging/'>Fusion Logging</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/remote-desktop/'>Remote Desktop</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/roles/'>Roles</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/troubleshooting/'>Troubleshooting</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/virtual-machine/'>Virtual Machine</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5204/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5204/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5204/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5204&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/08/07/busy-starting-role-sites-were-deployed-azure-role-diagnostics/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>45.508670 -73.553992</georss:point>
		<geo:lat>45.508670</geo:lat>
		<geo:long>-73.553992</geo:long>
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/08/2014-08-06_19-11-563.png?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/2014-08-06_19-11-563.png?w=150" medium="image">
			<media:title type="html">2014-08-06_19-11-56</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/2014-08-06_19-42-09.png?w=580" medium="image">
			<media:title type="html">2014-08-06_19-42-09</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/2451-image_thumb_12fa6343.png?w=580" medium="image">
			<media:title type="html">2451.image_thumb_12FA6343</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/1780-image_thumb_290bdfb3.png?w=580" medium="image">
			<media:title type="html">1780.image_thumb_290BDFB3</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/7206-image_thumb_2cbc8bb0.png?w=580" medium="image">
			<media:title type="html">7206.image_thumb_2CBC8BB0</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/2014-08-07_1-01-24.png?w=580" medium="image">
			<media:title type="html">2014-08-07_1-01-24</media:title>
		</media:content>
	</item>
		<item>
		<title>How do you Update Your Wetware?</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/08/02/how-do-you-update-your-wetware/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/08/02/how-do-you-update-your-wetware/#comments</comments>
		<pubDate>Sat, 02 Aug 2014 17:20:46 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[Book]]></category>
		<category><![CDATA[Collaboration]]></category>
		<category><![CDATA[Communication]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[People]]></category>
		<category><![CDATA[Sharing]]></category>
		<category><![CDATA[Wetware]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5195</guid>
		<description><![CDATA[I'm passionate about technology, but sometimes I need a wetware update. A reminder that technology needs people in order to change the world.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5195&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/08/02/how-do-you-update-your-wetware/" target="_blank" title="How do you Update Your&nbsp;Wetware?"><img width="580" height="326" src="https://alexandrebrisebois.files.wordpress.com/2014/08/brain_dxo.jpg?w=580" class="attachment-large wp-post-image" alt="brain_DxO" /></a></p><h1>How do you Update Your Wetware?</h1>
<p>I&#8217;m passionate about technology, but sometimes I need a <a href="http://en.wikipedia.org/wiki/Wetware_(brain)" target="_blank">wetware </a>update. A reminder that technology needs people to change the world.</p>
<blockquote><p>Wetware is a term drawn from the computer-related idea of hardware or software, but applied to biological life forms. Here the prefix &#8220;wet&#8221; is a reference to the water found in living creatures. Wetware is used to describe the elements equivalent to hardware and software found in a person, namely the central nervous system (CNS) and the human mind. The term wetware finds use both in works of fiction and in scholarly publications.</p></blockquote>
<p>Communicating effectively doesn&#8217;t come easily. Surprisingly, the skills required to be heard include paying attention to others. Listening with intent and genuine interest has a greater effect than one can imagine.</p>
<p>As a technology enthusiast, and as a dreamer, it&#8217;s important that I remember that I need to communicate to succeed. Ideas grow and mature to fruition through collaboration and care.</p>
<p>Curiosity drives me to update my wetware through various activities. For one, I am an active participant in my local and worldwide community where I learn about technology. By interacting with others, I learn from their experiences and expand my understanding. I listen to podcasts and comment on blog posts. I ask and answer questions on social networks like <a href="http://stackoverflow.com/" target="_blank">Stackoverflow</a> and I participate in forums.</p>
<p>Human interaction is at the center of my personal growth and this fact has driven me to two wonderful books. The first book that I had the pleasure of discovering is &#8220;<a href="http://www.amazon.com/Speaking-As-Leader-Every-Meeting-ebook/dp/B006UJUHAS" target="_blank">Speaking as a Leader</a>&#8220;. This book is rich with advice about how to move others with your vision. Using the right approach and the right tools makes a world of difference. The second book is time-tested and has captured the interest of millions. &#8220;<a href="http://www.amazon.com/How-Win-Friends-Influence-People-ebook/dp/B004GKMPSA" target="_blank">How to Win Friends and Influence People</a>&#8221; is a book that conveys principles through stories about people who have left their mark on history.</p>
<p>Both books complement each other really well. And both are rich with a wealth of wisdom that begs for a second read.</p>
<p>How do you update your <a href="http://en.wikipedia.org/wiki/Wetware_(brain)" target="_blank">wetware</a>?</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/thoughts/'>Thoughts</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/book/'>Book</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/collaboration/'>Collaboration</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/communication/'>Communication</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/community/'>Community</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/learning/'>Learning</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/people/'>People</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/sharing/'>Sharing</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/wetware/'>Wetware</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5195/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5195&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/08/02/how-do-you-update-your-wetware/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/08/brain_dxo.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/08/brain_dxo.jpg?w=150" medium="image">
			<media:title type="html">brain_DxO</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Automate Everything!</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/07/31/automate-everything/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/07/31/automate-everything/#comments</comments>
		<pubDate>Fri, 01 Aug 2014 02:24:45 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Book]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[DoD]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5187</guid>
		<description><![CDATA[Automate Everything! These two words immediately caught my attention! This is one of the hardest things for me as a developer. I spend most of my time designing and coding away, but I hardly spend anytime with PowerShell&#8230; so I&#8217;ll be blunt, as a developer, I must learn PowerShell and I must change my Definition of Done [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5187&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/07/31/automate-everything/" target="_blank" title="Automate Everything!"><img width="580" height="707" src="https://alexandrebrisebois.files.wordpress.com/2014/07/3617_9780735695658f_58f7bb03.jpg?w=580" class="attachment-large wp-post-image" alt="3617_9780735695658f_58F7BB03" /></a></p><h1>Automate Everything!</h1>
<p>These two words immediately caught my attention! This is one of the hardest things for me as a developer. I spend most of my time designing and coding away, but I hardly spend anytime with PowerShell&#8230; so I&#8217;ll be blunt, as a developer, I <strong>must</strong> learn PowerShell and I <strong>must</strong> change my Definition of Done (DoD). I am not done until my feature can be deployed repeatedly and reliably. Automation makes me sleep better at night because my deployments yield predictable results.</p>
<p>This new <a href="http://blogs.msdn.com/b/microsoft_press/archive/2014/07/23/free-ebook-building-cloud-apps-with-microsoft-azure.aspx">e-book</a>  is all about taking advantage of what the cloud has to offer. It&#8217;s packed with best practices for DevOps, data storage and high availability. Since the authors took a pattern-based approach, each chapter can be read independently.</p>
<p>Download all formats (PDF, Mobi and ePub) as well as link to the companion content hosted by the <a href="http://www.microsoftvirtualacademy.com/ebooks">Microsoft Virtual Academy</a>.</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/best-practices/'>Best Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/book/'>Book</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/devops/'>DevOps</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/dod/'>DoD</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/patterns/'>Patterns</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/powershell/'>PowerShell</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5187/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5187&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/07/31/automate-everything/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/07/3617_9780735695658f_58f7bb03.jpg?w=123" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/3617_9780735695658f_58f7bb03.jpg?w=123" medium="image">
			<media:title type="html">3617_9780735695658f_58F7BB03</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting Acquainted with #Azure Service Bus Event Hubs</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/07/18/getting-acquainted-with-azure-service-bus-event-hubs/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/07/18/getting-acquainted-with-azure-service-bus-event-hubs/#comments</comments>
		<pubDate>Fri, 18 Jul 2014 15:59:30 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Event Hubs]]></category>
		<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Service Bus]]></category>
		<category><![CDATA[AMQP]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Event Processor]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[IoT]]></category>
		<category><![CDATA[performance targets]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5028</guid>
		<description><![CDATA[Event Hub join ranks with Queues, Topics and Relays to offer options adapted to your needs. They provide the mechanisms necessary to collection of event streams at high throughput, from a diverse set of devices and services.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5028&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/07/18/getting-acquainted-with-azure-service-bus-event-hubs/" target="_blank" title="Getting Acquainted with #Azure Service Bus Event&nbsp;Hubs"><img width="580" height="387" src="https://alexandrebrisebois.files.wordpress.com/2014/07/0727_web_a_growth_t618.jpg?w=580" class="attachment-large wp-post-image" alt="0727_WEB_a_Growth_t618" /></a></p><h1>Getting Acquainted With #Azure Service Bus Event Hubs</h1>
<p>The Microsoft Azure ecosystem just keeps growing. This week Microsoft unveiled a very welcomed addition to the Microsoft Azure Service Bus. Event Hubs join ranks with Queues, Topics and Relays to offer options adapted to your needs.</p>
<h2>Contrasting available Service Bus Flavors?</h2>
<ul>
<li><strong>Relays</strong> – are used to bridge communications over the cloud in a secure and transparent manner.</li>
<li><strong>Queues</strong> – are pipes that allow for many publishes and many consumers to communicate over a single channel. This is great for <a href="http://msdn.microsoft.com/en-us/library/dn568101.aspx">Competing Consumers</a> and for <a href="http://msdn.microsoft.com/en-us/library/dn589783.aspx">Queue-based Load Leveling</a>.</li>
<li><strong>Topics</strong> – are pipes that allow fan out scenarios, where each consumer gets his own copy of the inbound queue. It also has some handy features like filters. Use this flavor to implement <a href="http://msdn.microsoft.com/en-us/library/dn568100.aspx">Pipes and Filters</a>.</li>
<li>
<div><strong>Event Hubs</strong> – are a bit more complex. Event Hubs enable the collection of event streams at high throughput, from a diverse set of devices and services. In other words, they help us deal with the 3 <strong>V</strong>s.</div>
<ul>
<li><strong>V</strong>olume (amount of data)</li>
<li><strong>V</strong>elocity (speed of data in and out)</li>
<li><strong>V</strong>ariety (range of data types and sources).</li>
</ul>
</li>
</ul>
<h2>Microsoft Azure Service Bus Event Hubs</h2>
<p>Event Hub join ranks with Queues, Topics and Relays to offer options adapted to your needs. They province the mechanisms necessary to collection of event streams at high throughput, from a diverse set of devices and services. They are composed of a Published Policy, of Consumer Groups and of Partitions.</p>
<p style="text-align:center;"><img src="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_1953_gettingacqu1.png?w=580" alt="" /></p>
<h3>Event Hubs support the following scenarios:</h3>
<ul>
<li>Collecting event streams at high throughput from devices/services for use in real-time and batch processing.</li>
<li>Connecting millions of devices from diverse platforms for sending data (with individual authentication and flow control).</li>
<li>Process event streams per device &#8220;in order&#8221; using several backend services (publish/subscribe).</li>
</ul>
<h3>Considerations Prior to Creating an Event Hub</h3>
<p>You must put some effort in capacity planning before you create an Event Hub. In order to make the right decisions let&#8217;s go over a couple details about Event Hubs.<span id="more-5028"></span></p>
<p>Event Hubs are partitioned. The minimum number of partitions is <strong>8</strong> and the maximum (public) number of partitions is <strong>32</strong>. If you need more partitions you must go through a support ticket. At that time, you can request up to <strong>1024 </strong>(and higher) partitions for your Event Hub.</p>
<p>Each partition has a performance target of <strong>1 MB ingress</strong> or <strong>1000 operations</strong> and <strong>2 MB egress</strong> per second. By default, each Event Hub is created with <strong>16</strong> <strong>partitions</strong>. This corresponds to <strong>16 MB ingress</strong> or <strong>16,000 operations</strong> and <strong>32 MB egress</strong> per second.</p>
<p>At first glance this seems like way too much so let&#8217;s put some perspective on this.</p>
<p>Imagine that our messages are <strong>5 KB</strong> in size. We could stream <strong>3276.8</strong> events per second. If messages were <strong>1 KB</strong> in size we could technically hit the performance target of <strong>1000</strong> operations per second. This could technically represent <strong>16,000</strong> messages per second. In order to reach the performance targets on all partitions of the Event Hub, we would need as many uniquely identified publisher as we have partitions. Each publisher is pinned to one partition by the Event Hub Service.</p>
<p>Calculating the number of partitions you need starts by calculating potential throughput in megabytes. Then you need to calculate the number of messages per second. This will give you the first part of the equation. The second part of the equation is found by calculating the number of processing nodes required to meet your performance targets.</p>
<p>Since a single partition cannot be processed concurrently by multiple nodes, you must have at least as many partitions as you have backend node instances. For example, a system that must process 30 messages simultaneously, where each process requires a dedicated processing node, requires the Event Hub to have at least 30 partitions.</p>
<blockquote><p>Number of partitions = MAX (<strong>cumulative throughput required for the stream – given 1 MB per partition</strong>, <strong>number of nodes needed by the backend processing application</strong>)</p></blockquote>
<p>Calculating the number of partitions based on performance targets is important because it cannot be changed after the creation of the Event Hub.</p>
<p>Changing the number of partitions once in production can cause quite a bit of headaches because it means that we need to create a new Event Hub and reconfigure publishers to use the new Event Hub. While events are piling up let the backend nodes empty the Event Hub. Once it&#8217;s empty, you can reconfigure your backend nodes to consumer events from the new Event Hub. Switching to the backend processing nodes to the new Event Hub too early would break the order of events. From a billing perspective, the number of partitions is irrelevant because there is not charge for partitions.</p>
<p>Once the application is deployed you can provision throughput units to scale the Event Hub&#8217;s throughput capacity. A single throughput unit (as of July 2014) has the capacity of <strong>1 MB</strong> per second of ingress events (events sent into an Event Hub), but no more than <strong>1000</strong> ingress events, management operations or control API calls per second. It has <strong>2 MB</strong> per second of egress events (events consumed from an Event Hub) and <strong>84 GB</strong> of event storage (sufficient for the default <strong>24-hour</strong> retention period). In order to max out the total possible capacity of an Event Hub, you will need to provision one throughput unit for each partition. Event Hub throughput units are billed hourly, based on the maximum number of units selected during the given hour.</p>
<h3>Creating an Event Hub</h3>
<p>Click on the <strong>+NEW</strong> area at the bottom of the portal and navigate to the Event Hub service.</p>
<img src="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_0108_gettingacqu1.png?w=580" alt="" />
<p>A wizard will show on screen to assist you with the creation. Enter an Event Hub name, select a Region that hosts the services that will process the events and click next. Be sure that you are creating the resource on the correct subscription and desired Azure Service Bus Namespace.</p>
<p style="text-align:center;"><img src="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_0108_gettingacqu2.png?w=580" alt="" /></p>
<p>The next panel prompts for important information. This is where you specify the number of partitions for your Event Hub. Then because this is a Standard Event Hub, you can specie the number of days that an event stays in the Event Hub. This is especially handy when you need to replay events from a week ago. The maximum number of days is set to 30, the minimum is set to 1 day.</p>
<p style="text-align:center;"><img src="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_0108_gettingacqu3.png?w=580" alt="" /></p>
<h2>Publishing Events</h2>
<p>In order to publish events to an Event Hub, you must create Shared Access Policies. I strongly recommend creating a policy that allows single actions. In order to publish an event we need a Shared Access Policy that allows us to send events. Navigate to the Service Bus namespace and click on the <strong>Event Hubs</strong> tab. From the list choose the newly created Event Hub.</p>
<p style="text-align:center;"><img src="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_1953_gettingacqu2.png?w=580" alt="" /></p>
<p>Then click on <strong>Configure</strong>. In this screen, you will be able to create a <strong>Send</strong> enabled Shared Access Policy.</p>
<p style="text-align:center;"><img src="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_1953_gettingacqu3.png?w=580" alt="" /></p>
<p>Now we need to retrieve a SAS key connection strings to authenticate and interact with the Event Hub. Select the <strong>Dashboard</strong> tab and click on the <strong>View Connection String</strong> link.</p>
<p style="text-align:center;"><img src="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_1953_gettingacqu4.png?w=580" alt="" /></p>
<p>From the wizard copy the <strong>Connection String</strong> that is enabled for <strong>Send</strong> operations. Click the copy button to store the connection string in you clipboard. This will allow you to paste the connection string in your project&#8217;s configurations.</p>
<p style="text-align:center;"><img src="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_1953_gettingacqu5.png?w=580" alt="" /></p>
<p>Getting down to the code. Use the connection string we copied from the portal to send events to our newly create Microsoft Azure Service Bus Event Hub. The <strong>EventData</strong> object is the equivalent of the Service Bus <strong><a href="http://msdn.microsoft.com/en-us/library/hh532019.aspx" target="_blank">BrokeredMessage</a></strong> with a twist. The <strong>EventData</strong> object requires a <strong>Partition Key</strong>. This key is used internally to decide which<strong> Event Hub</strong> partition is used to storage and convey the event. The <strong>EventHubClient</strong> used to send the <strong>EventData</strong> is part of the <a href="https://www.nuget.org/packages/WindowsAzure.ServiceBus/">Microsoft Azure Service Bus</a> 2.4.1.1 NuGet package.</p>
<pre class="brush: csharp; title: ; notranslate">
var cs = @&quot;[Service Bus Connection String] &quot;;

var builder = new ServiceBusConnectionStringBuilder(cs)
                    {
                        TransportType = TransportType.Amqp
                    };

var client = EventHubClient.CreateFromConnectionString(builder.ToString(), &quot;brisebois&quot;);

try
{
    var e = new Event
    {
        Message = &quot;Test Message&quot;
    };

    var serializedString = JsonConvert.SerializeObject(e);
    var data = new EventData(Encoding.Unicode.GetBytes(serializedString))
    {
        PartitionKey = &quot;test-app&quot;
    };

    // Set user properties if needed
    data.Properties.Add(&quot;Type&quot;, &quot;Event&quot;);

    await client.SendAsync(data);
}
catch (Exception exp)
{
    Console.WriteLine(&quot;Error on send: &quot; + exp.Message);
}
</pre>
<p>The data encapsulated inside an <strong>EventData</strong> object is stored in bytes. This allows us to use <strong>DataContracs</strong> and efficient serialization libraries like Json.NET, Protobuf and Avro. Keep in mind that like Service Bus Queues and Topics, messages are charged by slices of <strong>64 KB</strong>.</p>
<pre class="brush: csharp; title: ; notranslate">
[DataContract]
public class Event
{
    [DataMember]
    public string Message { get; set; }
}
</pre>
<h2>Consuming Events</h2>
<p>The first step in consuming events from the Event Hub is to implement <strong>IEventProcessor</strong>. The Event Processor is used to process events. It&#8217;s a great way to build an event processing pipeline. By using the <strong>Properties</strong> collection of the <strong>EventData</strong> object we can store the type of the event, which we can use to choose whether to deserialize and process the body of the <strong>EventData</strong> object.</p>
<pre class="brush: csharp; title: ; notranslate">
class EventProcessor : IEventProcessor
{
    public Task OpenAsync(PartitionContext context)
    {
        return Task.FromResult&lt;object&gt;(null);
    }

    public Task ProcessEventsAsync(PartitionContext context, IEnumerable events)
    {
        foreach (var eventData in events)
        {
            if (eventData.Properties[&quot;Type&quot;].ToString() != &quot;Event&quot;)
                continue;

            var bytes = Encoding.Unicode.GetString(eventData.GetBytes());
            var data = JsonConvert.DeserializeObject&lt;Event&gt;(bytes);

            Console.WriteLine(&quot;Processing EVENT [(Message: {0}) PartitionKey: {1}] at PartitionId: {2}&quot;,
                                data.Message,
                                eventData.PartitionKey,
                                context.Lease.PartitionId);

            foreach (KeyValuePair&lt;string, object=&quot;&quot;&gt; p in eventData.Properties)
            {
                if (!p.Key.Equals(&quot;ContentType&quot;))
                {
                    Console.WriteLine(&quot;  [Property: {0} = {1}]&quot;, p.Key, p.Value);
                }
            }
        }

        return Task.FromResult&lt;object&gt;(null);
    }

    public Task CloseAsync(PartitionContext context, CloseReason reason)
    {
        throw new NotImplementedException();
    }
}
</pre>
<p>There are a couple ways to consume messages from the Event Hub. The easiest is to use the <a href="https://www.nuget.org/packages/Microsoft.Azure.ServiceBus.EventProcessorHost">EventProcessorHost</a>. It takes care of scaling and distributing compute resources to process the Event Hub&#8217;s partitions. Create an instance by providing a Connection String that is capable of reading from the Event Hub. Provide an Azure Storage Connection String, it will be used by the <a href="https://www.nuget.org/packages/Microsoft.Azure.ServiceBus.EventProcessorHost">EventProcessorHost</a> to scale and checkpoint the event stream offset to Blob Storage.</p>
<p>This example reads from the default Consumer Group. In practice, we can use multiple Consumer Groups as we use multiple Subscription on Service Bus Topics. Consumer groups are Partitioned Subscriptions. Each Consumer Group gets a copy of the event. Each Consumer Group can be processed in parallel.</p>
<pre class="brush: csharp; title: ; notranslate">
var cs = @&quot;[Service Bus Connection String] &quot;;

var blobConnectionString = @&quot;[Storage Connection String]&quot;;

var builder = new ServiceBusConnectionStringBuilder(cs)
                    {
                        TransportType = TransportType.Amqp
                    };

var client = EventHubClient.CreateFromConnectionString(builder.ToString(), &quot;brisebois&quot;);

try
{
    var eventProcessorHost = new EventProcessorHost(&quot;singleworker&quot;,
                                                    client.Path,
                                                    client.GetDefaultConsumerGroup().GroupName,
                                                    builder.ToString(),
                                                    blobConnectionString);

    eventProcessorHost.RegisterEventProcessorAsync&lt;EventProcessor&gt;();
}
catch (Exception exp)
{
    Console.WriteLine(&quot;Error on send: &quot; + exp.Message);
}
</pre>
<p>We can also manage the way we process events from the Event Hub partitions. The first step is to implement an <strong>ICheckpointManager</strong>. This is used to persist the offset location of the last processed event from an Event Hub partition.</p>
<pre class="brush: csharp; title: ; notranslate">
public class EventProcessorCheckpointManager : ICheckpointManager
{
    public Task CheckpointAsync(Lease lease, string offset)
    {
        Console.WriteLine(&quot;PartitionId: &quot; + lease.PartitionId);
        Console.WriteLine(&quot;Offset: &quot; + offset);
        return Task.FromResult&lt;object&gt;(null);
    }
}
</pre>
<p>Then by using the <strong>EventHubClient</strong> and the <strong>NamespaceManager</strong> we can pick and choose Consumer Groups and partitions to subscribe to. In order to get this solution working, the connection string must contain a SAS key allowing the consuming code to manage the EventHub.</p>
<pre class="brush: csharp; title: ; notranslate">
var cs = @&quot;[Service Bus Connection String] &quot;;

var blobConnectionString = @&quot;[Storage Connection String]&quot;;

var builder = new ServiceBusConnectionStringBuilder(cs)
                    {
                        TransportType = TransportType.Amqp
                    };

var client = EventHubClient.CreateFromConnectionString(builder.ToString(), &quot;brisebois&quot;);

try
{
    var subscriberGroup = client.GetDefaultConsumerGroup();

    var eventHub = NamespaceManager.CreateFromConnectionString(builder.ToString()).GetEventHub(&quot;brisebois&quot;);

    // Register event processor with each shard to start consuming messages
    foreach (var partitionId in eventHub.PartitionIds)
    {
        subscriberGroup.RegisterProcessor&lt;EventProcessor&gt;(new Lease
        {
            PartitionId = partitionId
        }, new EventProcessorCheckpointManager());

        Console.WriteLine(&quot;Processing : &quot; + partitionId);
    }

}
catch (Exception exp)
{
    Console.WriteLine(&quot;Error on send: &quot; + exp.Message);
}
</pre>
<h2>Summary</h2>
<p>The Azure Service Bus Event Hubs enables us to stream millions of events. It allows us to partition and organize the consumption of events. Furthermore, we can use offsets to replay event streams. This is a powerful service. It has its particularities and takes a bit of effort to tame, but once you nailed down the details&#8230; its flat out awesome!</p>
<p>To grok Event Hubs, one has to get to know each of its parts. The service that has many great use cases like the Internet of things (IoT).</p>
<p>In this post I tried to focus on working with Event Hubs from C# using the NuGet packages, these packages are made available by the Azure Service Bus team. Its important to note that you can interact with Even Hubs though a REST API over HTTP. An example of this usage pattern can be found in the sample projects listed below.</p>
<p>Take a look at the following resources. As of July 2014, the documentation isn&#8217;t abundant and it requires us to explore. The next few months will probably bring forth much more documentation and use cases. Until then, please share your findings and your thoughts about this new service.</p>
<h2>NuGet Packages</h2>
<ul>
<li><a href="https://www.nuget.org/packages/WindowsAzure.ServiceBus/">Microsoft Azure Service Bus</a></li>
<li><a href="https://www.nuget.org/packages/Microsoft.Azure.ServiceBus.EventProcessorHost">Microsoft Azure Service Bus Event Hub &#8211; EventProcessorHost</a></li>
</ul>
<h2>Documentation</h2>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/dn789972.aspx">Event Hubs Developer Guide</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/dn790190.aspx">Event Hubs API Overview</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/dn789974.aspx">Event Hubs Authentication and Security Model Overview</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/dn789975.aspx">Event Hubs Preview Availability and Support</a></li>
</ul>
<h2>Sample Projects</h2>
<ul>
<li><a href="http://code.msdn.microsoft.com/windowsazure/Service-Bus-Event-Hub-286fd097">Service Bus Event Hub Getting Started</a></li>
<li><a href="http://code.msdn.microsoft.com/windowsazure/Service-Bus-Event-Hub-99ce67ab">Service Bus Event Hub Large Scale Secure Publishing</a></li>
<li><a href="http://code.msdn.microsoft.com/windowsazure/Event-Hub-Direct-Receivers-13fa95c6" target="_blank">Service Bus Event Hub Direct Receivers</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/service-bus/event-hubs/'>Event Hubs</a>, <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/service-bus/'>Service Bus</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/amqp/'>AMQP</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/best-practices/'>Best Practices</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/c/'>C#</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/event-hubs/'>Event Hubs</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/event-processor/'>Event Processor</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/http/'>HTTP</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/iot/'>IoT</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/performance-targets/'>performance targets</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/rest/'>REST</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/service-bus/'>Service Bus</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5028/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5028/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5028/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5028/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5028/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5028/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5028/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5028/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5028/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5028/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5028/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5028/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5028/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5028/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5028&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/07/18/getting-acquainted-with-azure-service-bus-event-hubs/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/07/0727_web_a_growth_t618.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/0727_web_a_growth_t618.jpg?w=150" medium="image">
			<media:title type="html">0727_WEB_a_Growth_t618</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_1953_gettingacqu1.png" medium="image" />

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_0108_gettingacqu1.png" medium="image" />

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_0108_gettingacqu2.png" medium="image" />

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_0108_gettingacqu3.png" medium="image" />

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_1953_gettingacqu2.png" medium="image" />

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_1953_gettingacqu3.png" medium="image" />

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_1953_gettingacqu4.png" medium="image" />

		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/071614_1953_gettingacqu5.png" medium="image" />
	</item>
		<item>
		<title>Microsoft Azure MVP (2014)</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/07/01/microsoft-azure-mvp-2014/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/07/01/microsoft-azure-mvp-2014/#comments</comments>
		<pubDate>Tue, 01 Jul 2014 04:30:06 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[MVP]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=5010</guid>
		<description><![CDATA[Microsoft Azure MVP (2014) Being recognized for something I&#8217;m so passionate about is amazing! The past year has truly been rewarding. It was a year of change, opportunity and challenges. I&#8217;m honored to receive the 2014 Microsoft Azure MVP award. I joined the Microsoft Azure MVPs last July and was welcomed by a group of [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5010&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/07/01/microsoft-azure-mvp-2014/" target="_blank" title="Microsoft Azure MVP&nbsp;(2014)"><img width="580" height="239" src="https://alexandrebrisebois.files.wordpress.com/2014/07/microsoft-mvp.gif?w=580" class="attachment-large wp-post-image" alt="microsoft-mvp" /></a></p><h1>Microsoft Azure MVP (2014)</h1>
<p>Being recognized for something I&#8217;m so passionate about is amazing! The past year has truly been rewarding. It was a year of change, opportunity and challenges.</p>
<p>I&#8217;m honored to receive the 2014 Microsoft Azure MVP award.</p>
<p>I joined the Microsoft Azure MVPs last July and was welcomed by a group of remarkable individuals. Inspired by our energetic community, I strive to learn and share about what it means to build applications for the cloud.</p>
<p>2013 was a year of change for the Microsoft Azure community. Services, Partners and Technologies have made their way to the cloud. Consumers have a rich ecosystem of services with which to compose their solutions. These are very exciting times for developers who tinker with the cloud. Competition, creativity and business opportunities create the perfect setting for a fast pace evolution. I really think that we&#8217;re only seeing the tip of the iceberg, 2014 is going inspiring!</p>
<p>I&#8217;d like to thank everyone who contributed over the past year. I&#8217;m very grateful for your questions, insights and opinions. The adventure has been very interesting and I truly hope that you will continue to be part of it.</p>
<p>Thank you for this exceptional award.</p>
<blockquote><p>The Microsoft Most Valuable Professional (MVP) Award is our way of saying thank you to exceptional, independent community leaders who share their passion, technical expertise, and real-world knowledge of Microsoft products with others. It is part of Microsoft&#8217;s commitment to supporting and enriching technical communities. Even before the rises of the Internet and social media, people have come together to willingly offer their ideas and best practices in technical communities.</p>
<p><a href="http://mvp.microsoft.com/en-us/default.aspx">Microsoft MVP web site</a></p></blockquote><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/community/'>Community</a>, <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/community/'>Community</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/mvp/'>MVP</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/5010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/5010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/5010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/5010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/5010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/5010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/5010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/5010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/5010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/5010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/5010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/5010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/5010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/5010/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=5010&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/07/01/microsoft-azure-mvp-2014/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/07/microsoft-mvp.gif?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/microsoft-mvp.gif?w=150" medium="image">
			<media:title type="html">microsoft-mvp</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>Microsoft #Azure – Where Should I Start?</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/06/30/microsoft-azure-where-should-i-start/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/06/30/microsoft-azure-where-should-i-start/#comments</comments>
		<pubDate>Mon, 30 Jun 2014 22:00:44 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=4988</guid>
		<description><![CDATA[Microsoft Azure is a vast ecosystem of services that keeps on growing. As a new comer to this ecosystem, you may feel overwhelmed. But don&#8217;t worry, I wrote this post to answer questions like &#8220;where should I start?&#8221; and &#8220;What resources are available to me?&#8221; Where Should I Start? This is often the hardest thing [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=4988&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/06/30/microsoft-azure-where-should-i-start/" target="_blank" title="Microsoft #Azure – Where Should I&nbsp;Start?"><img width="580" height="435" src="https://alexandrebrisebois.files.wordpress.com/2014/06/clouds-from-space1.jpg?w=580" class="attachment-large wp-post-image" alt="clouds" /></a></p><p><a href="http://azure.microsoft.com/en-us/">Microsoft Azure</a> is a vast ecosystem of services that keeps on growing. As a new comer to this ecosystem, you may feel overwhelmed. But don&#8217;t worry, I wrote this post to answer questions like &#8220;where should I start?&#8221; and &#8220;What resources are available to me?&#8221;</p>
<h1>Where Should I Start?</h1>
<p>This is often the hardest thing to identity when we start tinkering with Azure. I started exploring Azure by reading free e-books that you can download from the <a href="http://pnp.azurewebsites.net/en-us/">Patterns &amp; Practices website</a>.</p>
<p>The first books I read were</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/ff728592.aspx">Moving Applications to the Cloud, Third Edition</a> on Microsoft Azure</li>
<li><a href="http://msdn.microsoft.com/en-us/library/ff966499.aspx">Developing Multi-tenant Applications for the Cloud, Third Edition</a> on Microsoft Azure</li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh871440.aspx">Building Hybrid Applications in the Cloud</a> on Microsoft Azure</li>
</ul>
<p>Then I read <a href="http://msdn.microsoft.com/en-us/library/dn568099.aspx">Cloud Design Patterns</a>. The Patterns &amp; Practices team has also written a book about <a href="http://msdn.microsoft.com/en-us/library/jj554200.aspx">CQRS Journey</a>, which can greatly influence your overall design.</p>
<p>If you&#8217;re looking to buy a book, I highly recommend <a href="http://www.amazon.com/gp/product/B009G8PYY4/">Cloud Architecture Patterns: Using Microsoft Azure</a>, a book written by <a href="http://blog.codingoutloud.com/">Bill Wilder</a>. This should probably be the first book you read. It&#8217;s packed with tons of valuable information that applies to most cloud vendors.<span id="more-4988"></span></p>
<h3>Other e-books</h3>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/dn749874.aspx">Developing big data solutions on Microsoft Azure HDInsight</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/dn735912.aspx">Building an On-Demand Video Service with Microsoft Azure Media Services</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/hh680918(v=pandp.50).aspx">Enterprise Library 5.0 Integration Pack for Microsoft Azure</a></li>
</ul>
<p>I found these e-books to be full of valuable information. They helped me define and architect various cloud native solutions. Microsoft has also created a section about <a href="http://azure.microsoft.com/en-us/documentation/articles/architecture-overview/">Architecture on the Azure portal</a>. This section covers patterns, best practices and provides you with a Visio stencil that I find very helpful when I design Azure solutions.</p>
<p>If you&#8217;re like me, you&#8217;ll also like to take some time to browse through <a href="http://azure.microsoft.com/en-us/develop/net/guidance/">guidance around best practices on design, deployment, troubleshooting, security, and performance</a> provided by Microsoft.</p>
<h2>More Guidance on Azure</h2>
<p>Microsoft has also published <a href="http://msdn.microsoft.com/dn630664">scenario-based diagrams that help you build on Azure</a>. These <a href="http://msdn.microsoft.com/dn630664">blueprints</a> can provide you with a starting point for your own solution architecture.</p>
<p>Don&#8217;t forget about <a href="http://msdn.microsoft.com/dn630663">case studies</a>, these can help you build arguments to help you promote the cloud within your organization. One of the biggest challenges for cloud adoption, is resistance to change and the lack of context around one&#8217;s desire to move to the cloud.</p>
<h2>More Resources on Azure</h2>
<p>Microsoft has an amazing collection of free online courses about Azure.</p>
<ul>
<li><a href="http://www.microsoftvirtualacademy.com/training-courses/designing-applications-for-windows-azure-jump-start?prid=ca_mvpab&amp;mtag=MVP5000215">Designing Applications for Windows Azure Jump Start</a></li>
<li><a href="http://www.microsoftvirtualacademy.com/training-courses/moving-to-hybrid-cloud-with-microsoft-azure?prid=ca_mvpab&amp;mtag=MVP5000215">Moving to Hybrid Cloud with Microsoft Azure</a></li>
<li><a href="http://www.microsoftvirtualacademy.com/training-courses/windows-azure-sql-database?prid=ca_mvpab&amp;mtag=MVP5000215">Windows Azure SQL Database</a></li>
<li><a href="http://www.microsoftvirtualacademy.com/training-courses/windows-azure-storage-design-and-implementation-jump-start?prid=ca_mvpab&amp;mtag=MVP5000215">Windows Azure Storage &#8211; Design and Implementation Jump Start</a></li>
<li><a href="http://www.microsoftvirtualacademy.com/training-courses/windows-azure-security-overview?prid=ca_mvpab&amp;mtag=MVP5000215">Windows Azure Security Overview</a></li>
<li><a href="http://www.microsoftvirtualacademy.com/training-courses/windows-azure-for-it-pros-jump-start?prid=ca_mvpab&amp;mtag=MVP5000215">Windows Azure for IT Pros Jump Start</a></li>
<li><a href="http://www.microsoftvirtualacademy.com/training-courses/devops-an-it-pro-guide?prid=ca_mvpab&amp;mtag=MVP5000215">DevOps: An IT Pro Guide</a></li>
</ul>
<p>Visit <a href="http://www.microsoftvirtualacademy.com/product-training/microsoft-azure?prid=ca_mvpab&amp;mtag=MVP5000215">Microsoft Virtual Academy (MVA)</a> for the complete list.</p>
<h2>More Posts on Azure</h2>
<p>From time to time, I like to write about how to approach Azure. These are a few of my posts about the platform and my adventures on Azure.</p>
<ul>
<li><a href="https://alexandrebrisebois.wordpress.com/2014/02/12/what-is-windows-azure/">What is Azure?</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2014/02/27/is-your-application-built-for-the-cloud/">Is your application built for the cloud?</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2013/08/13/create-a-dev-test-environment-in-minutes/">Create a Dev &amp; Test Environment in Minutes!</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2014/05/27/how-do-you-build-features-on-azure/">How do you build features on #Azure?</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2014/01/31/brownfield-windows-azure-solutions-hidden-treasures/">Brownfield Azure solutions &amp; hidden treasures</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2014/01/21/why-is-software-architecture-important/">Why is Software Architecture important?</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2013/08/08/reaching-performance-targets-on-windows-azure-by-preparing-and-pre-calculating-data/">Reaching performance targets on Azure by preparing and pre-calculating data</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2014/02/03/times-have-changed-keep-up/">Times have changed, Keep Up!</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2013/08/30/designing-cloud-services-consider-bulkiness-chattiness/">Designing Cloud Services – consider bulkiness &amp; chattiness</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2013/08/22/keep-your-privates-private/">Keep your privates private!</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2013/07/16/turbo-charging-your-windows-azure-cloud-services/">Turbo charging your Azure Cloud Services</a></li>
<li><a href="https://alexandrebrisebois.wordpress.com/2013/07/11/windows-azure-storage-best-practices/">Azure Storage Best Practices</a></li>
<li><a title="Does Your Data Really Belong in Your SQL Database?
<p>When we move applications to the cloud, there are a few questions that absolutely need our attention. One of these questions comes down to database design. Do you really need&amp;hellip;" href="https://alexandrebrisebois.wordpress.com/2013/02/15/does-your-data-really-belong-in-your-sql-database/">Does your data really belong in your SQL Database?</a></li>
<li><a title="#WindowsAzure Lessons Learned – Continuous Services Require Continuous Attention" href="https://alexandrebrisebois.wordpress.com/2014/02/19/windowsazure-lessons-learned-continuous-services-require-continuous-attention/">Continuous Services require continuous attention</a></li>
</ul>
<h2>In Retrospect</h2>
<p>Azure is alive and kicking, its release cycle is quite short and we continuously see new features make their way to general availability. Keep a close eye on the <a href="http://azure.microsoft.com/blog">official Azure blog</a> and <a href="http://azure.microsoft.com/en-us/documentation/videos/azure-friday/">Azure podcasts</a>. Don&#8217;t forget about events like <a href="http://channel9.msdn.com/Events/Build/2014">Build</a> whose recorded sessions can be found on <a href="http://channel9.msdn.com/Azure">Channel 9</a>.</p>
<p>&nbsp;</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/4988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/4988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/4988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/4988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/4988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/4988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/4988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/4988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/4988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/4988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/4988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/4988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/4988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/4988/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=4988&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/06/30/microsoft-azure-where-should-i-start/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/06/clouds-from-space1.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/06/clouds-from-space1.jpg?w=150" medium="image">
			<media:title type="html">clouds</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>HTTP/1.1 503 Service Unavailable – Lessons Learned on #Azure</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/06/19/http1-1-503-service-unavailable-lessons-learned-on-azure/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/06/19/http1-1-503-service-unavailable-lessons-learned-on-azure/#comments</comments>
		<pubDate>Thu, 19 Jun 2014 17:41:42 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Cloud Services]]></category>
		<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Bandwidth]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[HttpStatusCode]]></category>
		<category><![CDATA[IO]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[SLAB]]></category>
		<category><![CDATA[Telemetry]]></category>
		<category><![CDATA[Web API]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=4985</guid>
		<description><![CDATA[On Azure we must design with cost of operation and service constraints. I recently had an interesting event where my REST Service, deployed on a small (A1) cloud service instance, started to respond with HTTP Status Code 503 Service Unavailable.<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=4985&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/06/19/http1-1-503-service-unavailable-lessons-learned-on-azure/" target="_blank" title="HTTP/1.1 503 Service Unavailable – Lessons Learned on&nbsp;#Azure"><img width="580" height="418" src="https://alexandrebrisebois.files.wordpress.com/2014/07/time_bomb-copy.jpg?w=580" class="attachment-large wp-post-image" alt="Time_Bomb copy" /></a></p><h1><span style="background-color:white;">HTTP/1.1 503 Service Unavailable<br />
</span></h1>
<p>On Azure we must design with cost of operation and service constraints. I recently had an interesting event where my REST Service, deployed on a small (A1) cloud service instance, started to respond with HTTP Status Code 503 Service Unavailable.</p>
<blockquote><p>The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response. [Source: <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP Status Code Definitions</a>]</p></blockquote>
<p>Faced with this interesting challenged I started looking in the usual places, which include SQL Database metrics, Azure Storage Metrics, application logs and performance counters.</p>
<p>Throughout my investigation, I noticed that the service was hit on average 1.5 million times a day. Then, I noticed that the open socket count was quite high. Trying to make some sense out of the situation, I started identifying resource contentions.</p>
<p>Looking at the application logs didn&#8217;t yield much information about why the network requests were piling up, but it did hint at internal process slowdowns following peak loads.</p>
<p>Working on extracting logs from Azure Table Storage I finally got a break. I noticed that the service was generating 5 to 10 megabytes of application logs per minute. To put this into perspective, the service requires enough IO to respond to consumer requests, to push performance counter data to Azure storage, to persist application logs to Azure storage and enough IO capacity to satisfy the application&#8217;s need to interact with external resources.</p>
<p>Base on my observations I came to the conclusion that my resource contention was around IO. Now, I rarely recommend scaling up, but in this case it made sense because the service move lots of data around. One solution would have been to turn off telemetry. But doing so would have made me as comfortable as if I were flying a jumbo jet with a blindfold on. In other words, this isn&#8217;t something I want to consider because I believe that telemetry is crucial when it comes to understanding how an application behaves on the cloud.</p>
<p>Just to be clear, scaling up worked in this situation, but it may not resolve all your issues. There are times when we need to tweak IIS configurations to make better use of resources and to handle large amounts of requests.Scaling up should remain the last option of your list.</p>
<h2>Related Posts</h2>
<ul>
<li><a href="https://alexandrebrisebois.wordpress.com/2014/06/12/lessons-learned-on-azure-log-everything/" target="_blank">Lessons Learned – On #Azure, Log Everything!</a></li>
<li><a title="Choosing The Right Compute Virtual Machine Size" href="https://alexandrebrisebois.wordpress.com/2013/01/05/choosing-the-right-compute-virtual-machine-size/" rel="bookmark">Choosing The Right Compute Virtual Machine Size</a></li>
</ul>
<p>&nbsp;</p><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/cloud-services-azure/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/bandwidth/'>Bandwidth</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/cloud-services/'>Cloud Services</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/devops/'>DevOps</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/httpstatuscode/'>HttpStatusCode</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/io/'>IO</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/logging/'>Logging</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/rest/'>REST</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/slab/'>SLAB</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/telemetry/'>Telemetry</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/web-api/'>Web API</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/4985/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/4985/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/4985/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/4985/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/4985/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/4985/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/4985/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/4985/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/4985/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/4985/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/4985/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/4985/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/4985/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/4985/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=4985&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/06/19/http1-1-503-service-unavailable-lessons-learned-on-azure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/07/time_bomb-copy.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/07/time_bomb-copy.jpg?w=150" medium="image">
			<media:title type="html">Time_Bomb copy</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
		<item>
		<title>#Azure Storage Tables &#8211; DateTime.MinValue is not supported</title>
		<link>https://alexandrebrisebois.wordpress.com/2014/06/18/azure-storage-tables-datetime-minvalue-is-not-supported/</link>
		<comments>https://alexandrebrisebois.wordpress.com/2014/06/18/azure-storage-tables-datetime-minvalue-is-not-supported/#comments</comments>
		<pubDate>Wed, 18 Jun 2014 20:00:23 +0000</pubDate>
		<dc:creator><![CDATA[Alexandre Brisebois]]></dc:creator>
				<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Table Storage]]></category>
		<category><![CDATA[DateTime]]></category>

		<guid isPermaLink="false">http://alexandrebrisebois.wordpress.com/?p=4967</guid>
		<description><![CDATA[#Azure Storage Tables &#8211; DateTime.MinValue is not Within the Supported DateTime Range Azure Table Storage is a NoSQL storage key/value based part of Microsoft Azure Storage services. It&#8217;s really good at absorbing massive amounts of data. It&#8217;s really good at massive parallel operations work on small amounts of data. But it&#8217;s horrible when it comes [&#8230;]<img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=4967&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="https://alexandrebrisebois.wordpress.com/2014/06/18/azure-storage-tables-datetime-minvalue-is-not-supported/" target="_blank" title="#Azure Storage Tables &#8211; DateTime.MinValue is not&nbsp;supported"><img width="580" height="435" src="https://alexandrebrisebois.files.wordpress.com/2014/06/new-nasa-mission-black-holes-nustar-crab-nebula_54876_600x450.jpg?w=580" class="attachment-large wp-post-image" alt="nasa-mission-black-holes-nustar-crab-nebul" /></a></p><h1>#Azure Storage Tables &#8211; DateTime.MinValue is not Within the Supported DateTime Range</h1>
<p>Azure Table Storage is a NoSQL storage key/value based part of Microsoft Azure Storage services. It&#8217;s really good at absorbing massive amounts of data. It&#8217;s really good at massive parallel operations work on small amounts of data. But it&#8217;s horrible when it comes time to extract large amounts of data in a serial manner. We&#8217;ll get to that topic in a future post.</p>
<p>DateTime is a type that is used to represent time in .NET. We use it very liberally without much afterthought. But when we start playing with Azure Table Storage, we have to think about the supported DateTime range. At this time, it&#8217;s also important to note that the local Azure Storage Emulators run on various database flavors like SQL Server and LocalDB. These databases do not impose the same limitations for DateTime values. Therefore, <strong>this bug will only show up on Microsoft Azure</strong>.</p>
<p>In order to limit headaches, I&#8217;m providing the <a href="http://msdn.microsoft.com/en-us/library/azure/dd179338.aspx">following table to help identify what is supported</a> and what isn&#8217;t.</p>
<div>
<table style="border-collapse:collapse;" border="0">
<tbody valign="top">
<tr>
<td style="padding-left:9px;padding-right:9px;"><span style="color:#222222;font-family:Segoe UI;background-color:white;"><strong>Common Language Runtime type</strong></span></td>
<td style="padding-left:9px;padding-right:9px;"><span style="color:#222222;font-family:Segoe UI;background-color:white;"><strong>Details</strong></span></td>
</tr>
<tr>
<td style="padding-left:9px;padding-right:9px;"><strong>byte[]</strong></td>
<td style="padding-left:9px;padding-right:9px;">An array of bytes up to 64 KB in size.</td>
</tr>
<tr>
<td style="padding-left:9px;padding-right:9px;"><strong>bool</strong></td>
<td style="padding-left:9px;padding-right:9px;">A Boolean value.</td>
</tr>
<tr>
<td style="padding-left:9px;padding-right:9px;"><strong>DateTime</strong></td>
<td style="padding-left:9px;padding-right:9px;">A 64-bit value expressed as Coordinated Universal Time (UTC). The supported <strong>DateTime</strong> range begins from 12:00 midnight, January 1, 1601 A.D. (C.E.), UTC. The range ends at December 31, 9999.</td>
</tr>
<tr>
<td style="padding-left:9px;padding-right:9px;"><strong>double</strong></td>
<td style="padding-left:9px;padding-right:9px;">A 64-bit floating point value.</td>
</tr>
<tr>
<td style="padding-left:9px;padding-right:9px;"><strong>Guid</strong></td>
<td style="padding-left:9px;padding-right:9px;"><span style="color:#222222;font-family:Segoe UI;background-color:white;">A 128-bit globally unique identifier.</span></td>
</tr>
<tr>
<td style="padding-left:9px;padding-right:9px;"><strong>Int32 or int</strong></td>
<td style="padding-left:9px;padding-right:9px;"><span style="color:#222222;font-family:Segoe UI;background-color:white;">A 32-bit integer.</span></td>
</tr>
<tr>
<td style="padding-left:9px;padding-right:9px;"><strong>Int64 or long</strong></td>
<td style="padding-left:9px;padding-right:9px;"><span style="color:#222222;font-family:Segoe UI;background-color:white;">A 64-bit integer.</span></td>
</tr>
<tr>
<td style="padding-left:9px;padding-right:9px;"><strong>String</strong></td>
<td style="padding-left:9px;padding-right:9px;">A UTF-16-encoded value. String values may be up to 64 KB in size.</td>
</tr>
</tbody>
</table>
</div>
<h2>Find out More about Azure Storage</h2>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/azure/dd179338.aspx">Understanding the Table Service Data Model</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/jj156169.aspx">Migrating Data to Azure Table Storage</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/jj553018.aspx">Azure Table Storage and Azure SQL Database &#8211; Compared and Contrasted</a></li>
</ul><br />Filed under: <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/category/microsoft-azure/table-storage/'>Table Storage</a> Tagged: <a href='https://alexandrebrisebois.wordpress.com/tag/datetime/'>DateTime</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/microsoft-azure/'>Microsoft Azure</a>, <a href='https://alexandrebrisebois.wordpress.com/tag/table-storage/'>Table Storage</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/alexandrebrisebois.wordpress.com/4967/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/alexandrebrisebois.wordpress.com/4967/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/alexandrebrisebois.wordpress.com/4967/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/alexandrebrisebois.wordpress.com/4967/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/alexandrebrisebois.wordpress.com/4967/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/alexandrebrisebois.wordpress.com/4967/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/alexandrebrisebois.wordpress.com/4967/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/alexandrebrisebois.wordpress.com/4967/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/alexandrebrisebois.wordpress.com/4967/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/alexandrebrisebois.wordpress.com/4967/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/alexandrebrisebois.wordpress.com/4967/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/alexandrebrisebois.wordpress.com/4967/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/alexandrebrisebois.wordpress.com/4967/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/alexandrebrisebois.wordpress.com/4967/" /></a> <img alt="" border="0" src="https://pixel.wp.com/b.gif?host=alexandrebrisebois.wordpress.com&#038;blog=32425054&#038;post=4967&#038;subd=alexandrebrisebois&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://alexandrebrisebois.wordpress.com/2014/06/18/azure-storage-tables-datetime-minvalue-is-not-supported/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:thumbnail url="https://alexandrebrisebois.files.wordpress.com/2014/06/new-nasa-mission-black-holes-nustar-crab-nebula_54876_600x450.jpg?w=150" />
		<media:content url="https://alexandrebrisebois.files.wordpress.com/2014/06/new-nasa-mission-black-holes-nustar-crab-nebula_54876_600x450.jpg?w=150" medium="image">
			<media:title type="html">nasa-mission-black-holes-nustar-crab-nebul</media:title>
		</media:content>

		<media:content url="https://0.gravatar.com/avatar/0ad58350b46012b50b00c5e61d0dc7d3?s=96&#38;d=https%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">codemontreal</media:title>
		</media:content>
	</item>
	</channel>
</rss>
