Thanks to the new Release Management system in VSTS/TFS, creating a release to your on-premise environment is really simple.
In this example I’m using Azure as IAAS, deploying a software on a Windows Virtual Machine. While this is probably not the best approach to cloud (PAAS is surely a better approach), to create a test environment it can be perfectly acceptable.
I’m not going to give you an introduction or explanation of Azure Resource Manager because there are tons of resources on the web, and Azure moves so quickly that the info I’d give you would probably be old by the time I press "publish." The purpose of this post is giving you a general idea on how to use Azure ARM to create a release definition that automatically generates the resource in Azure and deploys your software on it.
My goal is using Azure ARM for DevOps and Automatic / Continuous Deployment and the first step is creating a template file that describes exactly all the Azure resource needed to host my application. Instead of starting to write such template file I start checking on GitHub because there are tons of template filess ready to use.
As an example, I took one of the simplest, called 101-vm-simple-windows. It creates a simple Windows Virtual Machine and nothing else. That template has various parameters that can allow you to specify VM Names and other properties, and it can be directly used by a Release Management definition. I’ve done simple modifications to the template file and, in this situation, it is better to first check if everything is working as expected, triggering the deploy process directly from command line.
New-AzureRmResourceGroupDeployment -Name JarvisRm -ResourceGroupName JarvisRm -TemplateFile "azuredeploy.json" -adminUsername alkampfer -adminPassword ********** -vmName JarvisCmTest -storageAccount jarvisrmstorage -dnsLabelPrefix jarvisrm
As you can see, I need to choose the name of the resource group (JarvisRm), specify the template file (azuredeploy.json), and finally set all the parameters of the template as if they are parameters of the PowerShell cmdlet. Once the script has finished, verify that the resource group was created correctly and all the resources are suitable to deploy your software.
Figure 1: Your Resource group was correctly created.
Once everything is correct, I deleted the JarvisRm resource group, and I’m ready to use the template on a release definition.
Always test your ARM template directly from command line to verify that everything is all right. When the resources are created, try to use them as a manual target of a deploy and only once everything is OK, start automating with Release Management.
When you have a good template file, the best place to store it is in your source control, this allows you to version this file along with the version of the code that is supposed to use it. If you do not need versioning, you can simply store it in a network share, but to avoid problems, it is better to have Release Management Agent run the template from a local disk and not from a network share.
Figure 2: Copy template file from a network share to a local folder of the agent.
The first step of the release process is copying template files from a network share to the $(System.DefaultWorkingDirectory)\ARM folder so PowerShell can run against scripts that are placed on local disk. The second task is Azure Resource Group Deployment that uses the template to deploy all Resources to Azure.
Figure 3: The Azure Deployment task is used to create a Resource Group from a Template definition.
You should only specify the template file and the parameters of the template, such as userName, password, DNS name of the VM, etc. As a nice option, you can choose to Enable Deployment Prerequisites to have your VM be able to be used as a target for Deploy Action. You can read more about prerequisites on the MSDN blog. Basically, when you select this action, the script will configure PowerShell and other options on the target machine to be able to execute the script remotely.
Virtual machines need to be configured to be used as the targets of deploy tasks, such as remote PowerShell execution, but the Azure deployment task can take care of everything for you.
This task requires that you already connected the target Azure subscription with your VSTS account. If you never connected your TFS/VSTS account to your Azure subscription with ARM, you can follow the instruction at this link, that contains a PowerShell script that does EVERYTHING for you. Just run the script and annotate all the data you should insert to your TFS/VSTS instance to connect to Azure with ARM in a safe place .
Another aspect you need to take care of is the version of PowerShell Azure tools installed in the machine where the Release Agent is running. Release Management scripts are tested against specific versions of Azure PowerShell tools, and because the Azure team is constantly upgrading the Tools, it could happen that TFS/VSTS Release Management Tasks are not compatible with the latest version of the Azure Tools.
All of these tasks are open sourced, and you can find information directly on GitHub. As an example, at this link there is information about the DeployAzureResourceGroup task. If you go to the bottom, you can verify the PowerShell tools version suggested to run that task.
Figure 4: Supported version of AzureRM module version.
Clearly, you should install a compatible version in the machine where the Agent is installed. If you are unsure if the agents have a suitable version of Azure PowerShell tools, you can go to the TFS Admin page and verify the capabilities of the agent directly from VSTS/TFS.
Figure 5: Agent capabilities contains the version of Azure PowerShell tools installed.
Demand for Azure PS is present on Release Definition, but it does not specify the version, so it is not guaranteed that your release is going to be successful.
Figure 5: Release process has a demand for Azure PowerShell tools but not to a specific version.
As a result, I had problems in setting up the Release Process because my agents have PowerShell tools version 1.4 installed, but they are not fully compatible with Release Manager Task. Downgrading the tools solved the problem.
If your release fails with strange errors (such as NullReferenceException) you need to check the version of PowerShell tools in GitHub needed to run that task and install the right version in the agent (or at least you can try to change the version until you find the most recent that works).
The Azure Resource Group Deployments takes care of everything, I’ve modified the base script to apply a specific Network Security Group to the VM, but the general concept is that it configures every Azure Resource you need to use. At the end of the script you have everything you need to deploy your software (Virtual Machines, sites, databases, etc).
In my example, I only need a VM, and once it is configured, I can simply use the Copy to Azure VM task and the Execute PowerShell on Azure VM task to release my software, as I did for my on-premise environment.
Figure 6: Configuration of the Task used to copy files to Azure VM.
You can specify the files you want to copy (1) log into the machine (2), and thanks to the Enable Copy Prerequisites (3) option, you can let the Task take care of every step needed to copy files to the VM.This option is not needed if you already chose it in the Azure Deployment task, but it can be really useful if you have a pre-existing Virtual Machine you want to use.
The final step is executing the release script on the target machine, and it has the same options you specified to run a script on a machine on-premise.
Figure 7: Run the installation PowerShell script on target Azure VM.
Once everything is in place you only need to create a release and wait for it to be finished.
Figure 8: Output of release definition with Azure ARM.
With this example, because I’m using a Virtual Machine, the deploy script is the same I used for on-premise release, with a PaaS approach, usually you have a different script that targets Azure-specific resources (WebSites, DocumentDB, etc.).
If the release succeeded, you can log in to portal.azure.com to verify that your new resource group was correctly created Figure 1 and check that all the expected resources are in the resource group Figure 9.
Figure 9: Resources created inside the group.
To verify that everything is OK, you should check the exact version of the software that is actually deployed on the environment. From Figure 10, I can see that the release deployed the version 1.5.2.
Figure 10: List of all most recent releases.
Now I can log into the VM and try to use the software to verify that it is correctly installed and that the installed version is correct.
Figure 11: Software is correctly installed and the version corresponds to the version of the release.
Azure Resource Management is a powerful feature that can dramatically simplify releasing your software to Azure because you can just download scripts from GitHub to automatically create all Azure resources needed by your application. It also lets VSTS Release Management tasks take care of everything.