Azure ARM Templates and REST API

3k views Asked by At

I'm trying to learn Azure Resource Templates and am trying to understand the workflow behind when to use them and when to use the REST API.

My sense is that creating a Virtual Network and Subnets in Azure is a fairly uncommon occurance, once you get that set up as you want you don't modify it too frequently, you deploy things into that structure.

So with regard to an ARM Template let's say I have a template with resources for VNET and Subnet. To take the example from https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-template-walkthrough#virtual-network-and-subnet I might have:

{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('vnetName')]",
"location": "[resourceGroup().location]",
"properties": {
 "addressSpace": {
   "addressPrefixes": [
     "10.0.0.0/16"
   ]
 },
 "subnets": [
   {
     "name": "[variables('subnetName')]",
     "properties": {
       "addressPrefix": "10.0.0.0/24"
     }
   }
 ]
}
}

which I deploy to a Resource Group. Let's say I then add a Load Balancer and redeploy the template. In this case the user then gets asked to supply the value for the vnetName parameter again and of course cannot supply the same value so we would end up with another VNET which is not what we want.

So is the workflow that you define your ARM Template (VNET, LBs, Subnets, NICs etc) in one go and then deploy? Then when you want to deploy VMs, Scale Sets etc you use the REST API to deploy then to the Resource Group / VNET Subnet? Or is there a way to incrementally build up an ARM Template and deploy it numerous times in a way that if a VNET already exists (for example) the user is not prompted to supply details for another one?

I've read around and seen incremental mode (default unless complete is specified) but not sure if this is relevant and if it is how to use it.

Many thanks for any help!

Update

OK so I can now use azure group deployment create -f azuredeploy.json -g ARM-Template-Tests -m Incremental and have modified the VNET resource in my template from

{
  "apiVersion": "2016-09-01",
  "type": "Microsoft.Network/virtualNetworks",
  "name": "[variables('virtualNetworkName')]",
  "location": "[resourceGroup().location]",
  "properties": {
    "addressSpace": {
      "addressPrefixes": [
        "[variables('addressPrefix')]"
      ]
    },
    "subnets": [
      {
        "name": "[variables('subnetName')]",
        "properties": {
          "addressPrefix": "[variables('subnetPrefix')]"
        }
      }
    ]
  }
},

to

{
  "apiVersion": "2015-05-01-preview",
  "type": "Microsoft.Network/virtualNetworks",
  "name": "[parameters('virtualNetworkName')]",
  "location": "[resourceGroup().location]",
  "properties": {
    "addressSpace": {
      "addressPrefixes": [
        "[parameters('addressPrefix')]"
      ]
    },
    "subnets": [
      {
        "name": "[parameters('subnet1Name')]",
        "properties": {
          "addressPrefix": "[parameters('subnet1Prefix')]"
        }
      },
      {
        "name": "[parameters('gatewaySubnet')]",
        "properties": {
          "addressPrefix": "[parameters('gatewaySubnetPrefix')]"
        }
      }
    ]
  }
},

but the subnets don't change. Should they using azure group deployment create -f azuredeploy.json -g ARM-Template-Tests -m Incremental

3

There are 3 answers

6
Mitul On BEST ANSWER

I am going to piggy back on this Azure documentation. Referencing appropriate section below:

Incremental and complete deployments

When deploying your resources, you specify that the deployment is either an incremental update or a complete update. By default, Resource Manager handles deployments as incremental updates to the resource group.

With incremental deployment, Resource Manager

  1. leaves unchanged resources that exist in the resource group but are not specified in the template
  2. adds resources that are specified in the template but do not exist in the resource group
  3. does not reprovision resources that exist in the resource group in the same condition defined in the template
  4. reprovisions existing resources that have updated settings in the template

With complete deployment, Resource Manager:

  1. deletes resources that exist in the resource group but are not specified in the template
  2. adds resources that are specified in the template but do not exist in the resource group
  3. does not reprovision resources that exist in the resource group in the same condition defined in the template
  4. reprovisions existing resources that have updated settings in the template

To choose Incremental update or Complete update it depends on if you have resources that are in use. If devops requirement is to always have resources in sync with what is defined in the json template then Complete Update mode should be used. The biggest benefit of using templates and source code for deploying resources is to prevent configuration drift and it is beneficial to use Complete Update mode.

As for specifying the parameters if you specify in parameters file then you don't have to specify them again.

3
Darius Kvitnickas On

A new template can be deployed in incremental mode which would add new resources to the existing resource group. Define only the new resources in the template, existing resources would not be altered.

From powershell use the following cmdlet

New-AzureRmResourceGroupDeployment -ResourceGroupName "YourResourceGroupName" -TemplateFile "path\to\template.json" -Mode Incremental -Force

0
Daniel Morritt On

My rule of thumb is for things that I want to tear down, or for things I want to replicate across Subscriptions, I use ARM templates.

For example we want things in test environments, I just ARM it up, build on the scripts as developers request things ("Hey I need a cache", "Oh by the way I need to start using a Service Bus"), using incremental mode we can just push it out to Dev, then as we migrate up to different environments you just deploy to a different Subscription in Azure, and it should have everything ready to go.

Also, we've started provisioning our own Cloud Load Test agents in a VMSS, a simple ARM template that's called by a build to scale up to x number of machines, then when done, we just trash the Resource Group. It's repeatable and reliable, sure you can script it up, but as TFS has a task to deploy these things (also with schedules)...

One of the beautiful things I've come across is Key Vault, when you ARM it up and poke all the values from your service busses, storage accounts/whatevers, you can simply get the connection strings/keys/whatevers and put them straight into the Key Vault, so you never need to worry about it, and if you want to regenerate anything (say a dev wants to change the name of a cache or whatever, or accidentally posted the key to GitHub), just redeploy (often I'll just trash the whole Resource Group) and it updates the vault for you.