How Do You Create Servers Using .JSON Files and Resource Manager in Azure?

Problem scenario
You want to automate the creation of servers in Azure.  You want to try ARM templates to learn more about them.  How do you use .json files and Azure PowerShell to do this (without using the web UI)?

Solution
Prerequisites
i. You have a way of running Azure PowerShell commands.  If you need assistance with this, see this posting if your workstation is running Windows 7 or this posting if your workstation is running Windows 10. 
ii. You can log into the Azure Portal at the end (to set the password of the administrator user that you create when you create the VM with this process).

Procedures
This example will create a Windows server. 

1.  Create a file named CreateVMcontint.json with the contents below, but do two things first.  The first thing is to replace variables that start with "cont" or "my" as desired.  The second thing is to replace the user "contint" and its password "neatPassword5" with credentials you want to use.  Keep in mind that this .JSON file will have administrator credentials of the servers you create with it.

Here it is (CreateVMcontint.json):

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": { "type": "string" },
    "adminPassword": { "type": "securestring" },
    "contintuser": {     "type": "string",
        "defaultValue": "contintuser",
       "metadata": {
        "description": "Username for the Virtual Machine."           
       }
       },
     "neatPassword": {     "type": "securestring",
       "defaultValue": "neatPassword5",
       "metadata": {
        "description": "Password for contintuser."           
       }
       },
       "contint": { "type": "string",
          "defaultValue": "contint",
            "metadata": {
        "description": "Name of the Virtual Machine."           
           }
         }
     },
  "variables": {
    "vnetID": "[resourceId('Microsoft.Network/virtualNetworks','continualNET')]",
    "subnetRef": "[concat(variables('vnetID'),'/subnets/contIntSubnet')]",     
  },    
  "resources": [
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/publicIPAddresses",
      "name": "myPublicIPAddress",
      "location": "[resourceGroup().location]",
      "properties": {
        "publicIPAllocationMethod": "Dynamic",
        "dnsSettings": {
          "domainNameLabel": "contintresourcegroupdns1"
        }
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/virtualNetworks",
      "name": "continualNET",
      "location": "[resourceGroup().location]",
      "properties": {
        "addressSpace": { "addressPrefixes": [ "10.0.0.0/16" ] },
        "subnets": [
          {
            "name": "contIntSubnet",
            "properties": { "addressPrefix": "10.0.0.0/24" }
          }
        ]
      }
    },
    {
      "apiVersion": "2016-04-30-preview",
      "name": "contint",
      "type": "Microsoft.Compute/virtualMachines",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces/', 'contIntNic')]"
      ],
      "properties": {
        "hardwareProfile": { "vmSize": "Standard_DS1" },
        "osProfile": {
          "computerName": "[parameters('contint')]",
          "adminUsername": "[parameters('contintuser')]",
          "adminPassword": "[parameters('neatPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "2012-R2-Datacenter",
            "version": "latest"
          },
          "osDisk": {
            "name": "myManagedOSDisk",
            "caching": "ReadWrite",
            "createOption": "FromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces','contIntNic')]"
            }
          ]
        }
      }
    },    
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/networkInterfaces",
      "name": "contIntNic",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses/', 'myPublicIPAddress')]",
        "[resourceId('Microsoft.Network/virtualNetworks/', 'continualNET')]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": { "id": "[resourceId ('Microsoft.Network/publicIPAddresses','myPublicIPAddress')]" },
              "subnet": { "id": "[variables('subnetRef')]" }
            }
          }
        ]
      }
    }
  ]
}

2.  Create a second file named Parameters.json with the contents below, but replace the user "contint" and its password "neatPassword" with credentials you want to use.  Keep in mind that this .JSON file will have administrator credentials of the servers you create with it.

Here is the contents of Parameters.json:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
  "contentVersion": "1.0.0.0",
  "parameters": {
  "adminUserName": { "value": "contintuser" },
    "adminPassword": { "value": "neatPassword" }
  }
}

3.  Run this PowerShell script, but remember two things: first it will require an interactive login to the Azure account.  Secondly you will want to change the paths to the two .json files from "C:\path\to\" to the location they reside in on your server (and you may want to change the ResourceGroupName from "contIntGroup" to something else as well as the the location from "East US" to "West US"):

Login-AzureRMAccount
$storageName = "st" + (Get-Random)
New-AzureRmStorageAccount -ResourceGroupName "contIntGroup" -AccountName $storageName -Location "East US" -SkuName "Standard_LRS" -Kind Storage
$accountKey = (Get-AzureRmStorageAccountKey -ResourceGroupName contIntGroup -Name  $storageName).Value[0]
$context = New-AzureStorageContext -StorageAccountName $storageName -StorageAccountKey  $accountKey
New-AzureStorageContainer -Name "templates" -Context $context -Permission Container

Set-AzureStorageBlobContent -File "C:\path\to\CreateVMcontint.json" -Context $context -Container "templates"
Set-AzureStorageBlobContent -File "C:\path\to\Parameters.json" -Context $context -Container templates

$templatePath = "https://" + $storageName + ".blob.core.windows.net/templates/CreateVMcontint.json"
$parametersPath = "https://" + $storageName + ".blob.core.windows.net/templates/Parameters.json"
New-AzureRmResourceGroupDeployment -Name "contintDeployment" -ResourceGroupName "contIntGroup" -TemplateUri $templatePath -TemplateParameterUri $parametersPath

Leave a comment

Your email address will not be published. Required fields are marked *