Deploy to Azure Button

By now if you have done any work with Azure Resource Manager (ARM) JSON templates you have probably seen the “Deploy to Azure” button.  The “Deploy to Azure” button looks like this.

If you aren’t familiar with this, have a look at some of the templates in the Azure Quickstart Templates  github repo. This is where you will find a lot of sample templates that you can test and/or modify for your own use.

The “Deploy to Azure” button comes in really handy when you want to quickly deploy a template. Although you will find this mostly in github repos you could use this anywhere by simply adding the code. Upon clicking on this button, you will be redirected to the Azure Portal where a blade will open waiting for you to enter the parameters for the deployment. Ok, this is cool so how do I add it? We are getting to that now.

I have seen a few references to the button in other blogs but couldn’t really find out exactly how this is done. With a little testing I figured it out and so I thought I would share with you how you can add this button. I will discuss this from a github repo perspective but as I mentioned above you could utilize this button in other places as well.

What you will want to do is to copy this code block and paste it into your README.md file.

<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FDarylsCorner%2FARM-Templates%2Fmaster%2Fvm-from-user-image%2Fazuredeploy.json" target="_blank">
    <img src="http://azuredeploy.net/deploybutton.png"/>
</a>

The only part you need to change is the location of your template. This is the portion after …/uri/ and before target=. In your Github repo, click on your azuredeploy.json file and click Raw. Copy the link and go back to your README.md file and paste it in. Now you would think this is all that is needed and everything would just work. Wrong.

So why is that? URLs use some characters for special use in defining their syntax. When these characters are not used in their special role inside a URL, they need to be encoded. Some examples include the colon and forward slash. It just so happens we have both of those in our URL. So how is this done? URL encoding of a character consists of a “%” symbol, followed by the two-digit hexadecimal representation (case-insensitive) of the ISO-Latin code point for the character.

So if you look at the code block above you will see that we are using %3A in place of the colon and %2F in place of each forward slash. Once this is done make sure to commit your changes and viola! You now have a “Deploy to Azure” button that will allow for a streamlined deployment process.

I hope this post has been helpful and you find this useful. Stay tuned for another exciting and interesting button that we will discuss tomorrow called “Visualize”.

 

 

 

Deploy Custom Images using ARM and PowerShell

Recently I had a customer ask me about deploying virtual machines using custom images via Azure Resource Manager (ARM). In the Classic (v1) Portal you have the capability to capture a VM directly in the portal. In the Azure (v2) Portal that capability does not exist, at least not yet. Also, you cannot capture an image in the Classic mode and use it to deploy a VM in the ARM mode. So the questions is, how can this be done today. My answer, PowerShell! Let me show you just how easy it is to deploy custom images using ARM and PowerShell.

Take note that the commands below are using Azure PowerShell 0.9.8. If you wish to use the 1.0 Preview you can refer to a previous post I did here on Keeping Azure PowerShell Cmdlets Updated. In addition, you will need to edit the cmdlets using the pattern {verb}-AzureRM{noun}. So let’s move forward.

Prepare VM

Note: This process will destroy your VM!! I see many comments from others complaining that their VM is useless after this procedure so I am warning you ahead of time. This was tested using Server 2012 R2.

1. The first thing you will want to do is to deploy a VM in the Azure Portal and customize your VM with the applications desired in your image. You can also deploy data disks as needed.

2. Next we need to logon the VM, open a PowerShell console as administrator, and run the follow command to sysprep the image. This command is executing the sysprep.exe application. Sysprep removes all unique system information from the Windows installation. In addition, we use the generalize option to prepare the installation to be imaged, the Out Of Box Experience option to enable users to customize their installation, and the shutdown option which is self-explanatory.

& "$Env:SystemRoot\system32\sysprep\sysprep.exe" /generalize /oobe /shutdown

3. Once the sysprep process is complete the VM will shut down as noted by the below screen shots.

Capture VM

The next step is to capture the image. This can be down via PowerShell or by using the ARM Explorer. We will be using PowerShell but for more info on ARM Explorer click here. In a future post we will cover using ARM Explorer.

1. Open your Azure PowerShell console as administrator.

2. Connect to your subscription.

Add-AzureAccount

3. Select which subscription to deploy to.

Select-AzureSubscription "Visual Studio Premium with MSDN"

4. Switch to ARM mode.

Switch-AzureMode -Name AzureResourceManager

5. Here I am just setting some variables based on the VM that I deployed, customized, and sysprepped. You will want to change these to fit your environment.

$rgName = 'gwpccisco-rg2'
$vmName = 'TestVM2'
$destContainerName = 'myimages'
$location = 'West US'

6. Now we want to deallocate the VM.

Stop-AzureVM -ResourceGroupName $rgName -Name $vmName -Force

7. Next, we need to set the state of the VM to generalized.

Set-AzureVM -ResourceGroupName $rgName -Name $vmName -Generalized

8. Finally, we capture the image to our storage account. In this command we are downloading a copy of the ARM template file (JSON) to our local computer. Make sure that you create a folder for the directory structure if its not already in place or the command will fail.

Note: At a minimum two files will be generated, one VHD file  for the OS and another file which is the JSON template. You could have additional ones for each data disk as well. All files will get stored in a container called ‘System’ in the storage account with a blob path as the $destContainerName that you specified. This is a bit odd; however, I kind of like it in that my vhd images are stored out of the way and not intermingled with others. Note to self, do not delete System container!

Save-AzureVMImage -ResourceGroupName $rgName -VMName $vmName -DestinationContainerName $destContainerName -VHDNamePrefix 'template' -Path C:\temp\VMCapture\SampleTemplate.json

In my example you can see the path to the container and blob.

https://gwpcciscorg23687.blob.core.windows.net/system/Microsoft.Compute/Images/myimages/template-osDisk.cc51b4fb-1755-4d43-ae6b-e93b277980f2.vhd

And the files that were generated.

Note: The JSON file that is generated can be used to build a ARM template using your custom images. The info is contained in the Resources/StorageProfile node of the JSON file.

 

Create VM Using Custom Image

The custom VM images need to be stored in the same storage account that the VM will be stored in during deployment. So what I have done is to copy the image files, using PowerShell, from the source storage account to the destination storage account. Keep in mind that once the new VMs are deployed you can delete the templates if you wish. This would be more important if using a Premium storage account to keep the cost down of storing those images.

Now it is simply just running your deployment scripts and editing a few parameters to point at the sourceImageUri location for your OS and Data disks.

In my example I am deploying a Resource Group, new storage account, and virtual network. In that storage account I am creating a container called ‘myimages’. I am copying all blobs with the word ‘disk’ in them to this new container. I am deploying 2 VMs in an Availability Set (AS) with a Network Security Group (NSG) associated to each NIC defining allowed inbound traffic. Each NIC has an Instance-level public IP (ILPIP) associated for direct access from the internet. Finally, we clean-up by removing the container holding the copied images.

Her is a high-level outline of the tasks in my deployment.

If you would like to use this code for your testing you can find it in a GitHub account here. Keep in mind that you will need to modify the script to fit your environment. Pay close attention to the $sourceImageUri and $sourceDataDiskImageUri variables as these will need to match up with your storage account.

I hope you have found this post to be useful to you. Maybe in the near future we will see an option in the Azure (v2) portal to accomplish the same tasks.

 

Keeping Azure PowerShell Cmdlets Updated

In today’s Azure Nugget we discuss keeping Azure PowerShell cmdlets updated. It seems like there is a new service announcement or update in Azure just about every day now. With the fast pace of update releases we need to ensure that we keep our Azure PowerShell cmdlets up-to-date so we can take advantage of the new functionality being provided. Azure PowerShell cmdlets are provided so that you can rapidly and consistently deploy and manage resources in Azure. These cmdlets are being updated regularly so we need to make sure we update our workstations as well.

First we need to see what version of the Azure cmdlets we already have installed.

1. Open Windows PowerShell ISE as administrator as run the following command.

(Get-Module -ListAvailable | Where-Object{ $_.Name -eq 'Azure' }) | Select Version, Name, Author, PowerShellVersion  | Format-List

Here you can see that I am running version 0.9.5. Looks like I am a little behind on this machine.

2. You could also provide your credentials to Azure via the Add-Account cmdlet and run the following command.

(Get-Module Azure).version

3. You can find all the latest releases of Azure PowerShell cmdlets on Github. As of this blog the latest release is 0.9.8.1.

4. You can use the Web Platform Installer (WEB PI) to install the module. If you already have the WEB PI installed just open it and you should be on the Spotlight tab. If you don’t have it installed click on the link to install. It will only take a minute to install. If you prefer you can click on the Windows Standalone link which is an msi installer. We will use WEB PI here.

5. Click on the Add button for Microsoft Azure PowerShell. Now you can double-click on the package to verify its version.

6. Now that we can see we have the latest version, click the Install button. Accept the License Agreement by clicking I Accept.

7. The installation and configuration will begin.

8. The install will only take a minute and you should get a successful installation message.

9. Here you can see the product was installed. Click Exit and lets go verify the new version.

10. If your ISE is still open, close and re-open. Repeat step 1 or step 2 to verify.

or

Now that you know just how easy it is to keep your Azure cmdlets updated and where to find the updates, lets go deploy some stuff.

Note: Keep in mind that Azure PowerShell 1.0 was just released in Preview and there is a breaking change between 0.9.8 and 1.0 for all existing ARM PowerShell deployments. If you recall in our scripts we have to switch to ARM using the Switch-AzureMode cmdlet. Well, this is the fix for that and all Azure Resource Manager PS cmdlets will now be referenced as AzureRM moving forward.