Hey all,
Last week we talked about Continuous Integration and Deployment to Azure. We set up an App Service and deployed a .NET Core application using Visual Studio Team Services (VSTS), Azure and Visual Studio. In this post we’re going to explore deployment of your Azure resources, or infrastructure, using the Azure Resource Manager and ARM Templates. In this post we’re going to use Azure, VSTS and Visual Studio 2017 again. I recommend you read my previous post if you’re not already familiar with Azure and VSTS.
Sample code for this post can be found on my GitHub profile.
ARM Templates
So what’s this Azure Resource Manager template, or ARM template, exactly? Basically, it’s just some JSON that describes the resources, like app services, databases and storage accounts, you want to have in Azure. Azure can process this template and create or update our resources based on the template. This is also called Infrastructure as Code or (IaC). I’m assuming you know what JSON is, so I’m not explaining that here.
ARM templates are declarative, meaning you describe what you want rather than how you want it. In practice this means you’re not writing code to actually create the resources, but simply state which resources you want to have.
ARM Templates in Azure
So let’s have a look at what this looks like. If you go to a resource in Azure, any resource, you should be able to get the ARM template from the left side menu. I still have my imunique Web App from my previous post, so let’s see what that looks like. Just find the “Automation Script” menu item.
On the left side of the panel that opens you can find the different nodes that make up the ARM template.
As you can see this (generated) template has three input parameters, no variables, and three actual resources. A parameter is an input for the script, a variable is a computed value. For now we’re mostly interested in the resources. We have the ‘serverfarm’, or the hosting plan; the actual web app, imunique; and the host name binding, which makes your web app available on imunique.azurewebsites.net (Azure created this for us).
Here’s a part of the actual JSON template describing (a part of) the web app.
So there’s some good news and some bad news. The good news is Azure can create most of most ARM templates for us. The bad news is that they aren’t always of high or even usable quality. Of course we can tweak them however we like.
Azure Resource Group Projects
Let’s create our own ARM template. Open up Visual Studio 2017 and create a new “Azure Resource Group” project (found under “Cloud”) and name it whatever you like. I’ve named my solution AzureResourceSamples and the different projects have ARM templates for different resources. Again, you can find it on my GitHub profile.
Once you create the project you can pick a pre-defined template from Visual Studio, like a web app. You can also get a template from the Azure Quickstart templates on GitHub. There’s literally hundreds of them ranging from web apps to VM’s to databases. You can pick an empty template as well, it’s possible to add resources later. I’ve picked the “Web app” from the Visual Studio templates. This creates a web app with a hosting plan, Application Insights and auto-scaling. The ARM template can be found in the WebSite.json file. I can recommend studying it thoroughly.
The first thing we can do is right-click the “AutoScaleSettings” in the JSON Outline and delete it. We also don’t really need all those Application Insights alert rules for now, so delete those too. In fact, let’s keep it simple and also delete the “AppInsightsComponent”. We’re left with a very basic template that just creates a hosting plan and a web app. Here’s the “resources” node that has the web app and hosting plan, but not the parameters and variables.
Deployment in Visual Studio
Now let’s deploy them to Azure using Visual Studio. Simply right-click on your project and select “Deploy” and then “New…” from the drop down menu. In the form that pops up you can set your Microsoft account, your Azure subscription, the resource group you want to deploy to and the template parameters (those are stored in the *.parameters.json file). Make sure you fill out your parameter values or the deployment will fail. Now simply hit the “Deploy” button and browse to your Azure portal. If all went right you should now see a new hosting plan and a new web app in the resource group you selected.
If the resource you’re deploying already exists Azure will update that resource so it matches the ARM template. You can set literally every property you can set through the Azure portal in an ARM template as well.
A few notes considering the syntax of ARM Templates: when you need a non-static string (a parameter, variable or the result of a function) you can use the "[...]"
syntax. To use a parameter you can use "[parameter('paramName')]"
and to use a variable you can use "[variable('varName')]"
. Another very handy function is concat
, which you can use like "[concat('staticstring', variable('nonstatic'))]"
. Other useful functions are resourceGroup()
and subscription()
, which can be used to get the current resource group id or location or the subscription id.
Deploy per resource
Since it’s possible to reuse hosting plans you may not want to have to deploy these together. Creating a template with only a hosting plan is easy. Simply create an empty template and add an “App Service Plan (Server Farm)” resource. The result is pretty much what we already had in the previous example, but without the web app.
So let’s create a template that only has a web app. This is a little trickier since both Azure and Visual Studio need a hosting plan with a web app. Ideally, you want to be able to set the hosting plan with your deployment since you’re probably going to have different hosting plans for different environments. Since it’s easier to start with something, simply create a template for a web app with a hosting plan.
Parameters
The first thing we’re going to do is add our own parameters. We want to be able to set the hosting plan, the resource group of the hosting plan (Azure will look in the current resource group by default), and the name of your web app because we don’t want a random name like in the previous example. I’ve given the “hostingPlanName” and “hostingPlanResourceGroup” default values because we’re most likely to use these values (for now).
Variables
The next part is where things get tricky. It’s all pretty straightforward, except for the “serverFarmId” variable, which is the hosting plan. Because the hosting plan can be in a different resource group we have to specify the complete path to the resource, including our subscription ID. While it’s possible to share resources in different subscriptions we really don’t want to go there, so I’m sticking to the current subscription.
Now try to deploy this again to a new resource group, but keep the existing hosting plan from the already existing resource group. You can now deploy this web app to any resource group using any hosting plan in any other resource group (within the same subscription).
Connecting VSTS to Azure Active Directory
Before we go any further we have to do one tiny little thing. Head over to Azure and look for the “Team Services administration”. You should be able to see your VSTS account there. Simply click your account and in the options pane that pops up click the “Connect AAD” button. This will hook up your VSTS users to Azure Active Directory (AAD). We’ll need this when we’re going to set up resource deployments to Azure in VSTS.
If it doesn’t work right away try going to the Azure AD first and create a directory there, then try to connect again.
Continuous Deployment using VSTS
We’re now ready to deploy our ARM templates with our web apps or just as a stand-alone release. Head over to VSTS and create a new project or use an existing one. In your project head over to the releases tab, create a new pipeline and choose for the “Empty process”.
You may want to host the examples in VSTS. I’ve used GitHub and it’s perfectly fine to connect GitHub to VSTS (although it’s not in scope of this post so you’re going to have to figure that one out yourself). It’s really easy to do though, just create a new pipeline, add an artifact and set GitHub as a source type. From there VSTS will guide you through setting up GitHub Authorization for VSTS.
Anyway, create a new release pipeline and set your artifact to the ARM templates repository. You can turn on continuous deployment (using the lightning icon in the upper right corner of your artifact). Rename your environment to “Dev” or whatever you like.
Azure Resource Group Deployment
Now it’s time to add a task. Head over to the “Tasks” page for you Dev environment and add the “Azure Resource Group Deployment” (under “Deploy”). Choose your “Azure subscription” and hit the “Authorize” button. This should work because we’ve set up VSTS in Azure AD. Leave the “Action” at “Create or update resource group”. Then pick the resource group you want to deploy to, you can either pick one from the drop down or type any name you want. Next, you have to pick the location of your resource group so either pick the location of the group you’ve picked or set the location for your new resource group.
The next thing we need to set is the “Template”. This field has a browse button for our convenience so use it and select “WebSite.json” in the “WebApp” folder so VSTS will create or update a web app. Do the same thing for “Template parameters”, but instead pick the “WebSite.parameters.json” file. In the “Override template parameters” field you can override your parameters, which you should do. The “hostingPlanName” and the “hostingPlanResourceName” should have a correct default value, but you may want to change the “webSiteName”.
Once you’ve set these you’re good to go! Give your release pipeline a name, save it, and create a new release. If all goes well your web app should be created in your Azure account.
If all goes well you can clone your Dev environment and simply overwrite your parameters (and possibly change your resource group) and create a Test environment.
Wrap up
And that’s it. It really is that easy to automatically deploy your web apps to Azure. And not only that, you can deploy VM’s, databases, queues, storage accounts, and pretty much anything you can think of, using ARM templates. If you turned on continuous deployment your deployment should start automatically when you push a commit to Git. And there’s nothing stopping you from also deploying your actual software or other Azure resources in the same deployment.
Again, don’t forget to remove your resources or you’ll be billed for them.
Happy coding!