Configure a VHD template – Automating VM Deployments Using ARM Templates

Configure a VHD template

Seeing that the exam objective is to automate the deployment of VMs, we are going to deploy a few resources that will include VHDs, both an operating system (OS) VHD and a data disk VHD.

We are going to deploy the following resources with our ARM template:

  • Windows Server 2019
  • Virtual network
  • Network security group (NSG)

Important Note

Microsoft hasseveral ARM templates available on GitHub to help get you started: https://github.com/Azure/azure-quickstart-templates.

The following ARM template can be used to deploy the resources. The script is quite long and, therefore, has been split up into sections to explain what the ARM code does. To use the following script, all of the code sections need to be copied into a JSON format template:

The following code section indicates the schema version and relevant details:

{

“$schema”: “https://schema.management.azure.com/ schemas/2019-04-01/deploymentTemplate.json#”,

“contentVersion”: “1.0.0.0”,

“metadata”: {

“_generator”: {

“name”: “bicep”,

“version”: “0.4.1.14562”,

“templateHash”: “8381960602397537918”

}

The following code section indicates the start of the parameters section within the main template file, which will reference the parameters file that can be found in the following snippet. This includes the admin username for the VM as well as the password that is required in secure string format:

},

“parameters”: {

“adminUsername”: {

“type”: “string”,

“metadata”: {

“description”: “Username for the Virtual Machine.”

}

},

“adminPassword”: {

“type”: “secureString”,

“minLength”: 12,

“metadata”: {

“description”: “Password for the Virtual Machine.”

}

},

The following code section indicates the DNS name for the public IP address of the VM as well as the definition of the public IP address:

“dnsLabelPrefix”: {

“type”: “string”,

“defaultValue”: “[toLower(format(‘{0}-{1}’, parameters(‘vmName’), uniqueString(resourceGroup().id, parameters(‘vmName’))))]”,

“metadata”: {

“description”: “Unique DNS Name for the Public IP used to access the Virtual Machine.”

}

},

“publicIpName”: {

“type”: “string”,

“defaultValue”: “myPublicIP”,

“metadata”: {

“description”: “Name for the Public IP used to access the Virtual Machine.”

}

The following code section indicates that the public IP address is going to use the dynamic type, which means it will change when the VM is restarted:

},

“publicIPAllocationMethod”: {

“type”: “string”,

“defaultValue”: “Dynamic”,

“allowedValues”: [

“Dynamic”,

“Static”

],

“metadata”: {

“description”: “Allocation method for the Public IP used to access the Virtual Machine.”

}

The following code section indicates that the public IP address is going to make use of the basic SKU; the basic SKU is selected if the user doesn’t provide a value:

},

“publicIpSku”: {

“type”: “string”,

“defaultValue”: “Basic”,

“allowedValues”: [

“Basic”,

“Standard”

],

“metadata”: {

“description”: “SKU for the Public IP used to access the Virtual Machine.”

}

The following code section indicates the different allowed values to choose from when choosing an OS; this will be in the form of a drop-down list within the Azure portal:

},

“OSVersion”: {

“type”: “string”,

“defaultValue”: “2019-Datacenter”,

“allowedValues”: [

“2008-R2-SP1”,

“2012-Datacenter”,

“2012-R2-Datacenter”,

“2016-Nano-Server”,

“2016-Datacenter-with-Containers”,

“2016-Datacenter”,

“2019-Datacenter”,

“2019-Datacenter-Core”,

“2019-Datacenter-Core-smalldisk”,

“2019-Datacenter-Core-with-Containers”, “2019-Datacenter-Core-with-Containers-smalldisk”, “2019-Datacenter-smalldisk”, “2019-Datacenter-with-Containers”, “2019-Datacenter-with-Containers-smalldisk”

],

The following code section indicates the VM SKU, which will, in this case, be a

Standard_D2_V3 VM with the name of simple-vm:

“metadata”: {

“description”: “The Windows version for the VM. This will pick a fully patched image of this given Windows version.”

}

},

“vmSize”: {

“type”: “string”,

“defaultValue”: “Standard_D2_v3”,

“metadata”: {

“description”: “Size of the virtual machine.”

}

},

“location”: {

“type”: “string”,

“defaultValue”: “[resourceGroup().location]”,

“metadata”: {

“description”: “Location for all resources.”

}

},

“vmName”: {

“type”: “string”,

“defaultValue”: “simple-vm”,

“metadata”: {

“description”: “Name of the virtual machine.”

}

}

The following code section indicates the variables for the virtual network called MyVNET with an address range of 10.0.0.0/16, a subnet with a range of 10.0.0.0/24, and a default NSG:

},

“functions”: [],

“variables”: {

“storageAccountName”: “[format(‘bootdiags{0}’, uniqueString(resourceGroup().id))]”,

“nicName”: “myVMNic”,

“addressPrefix”: “10.0.0.0/16”,

“subnetName”: “Subnet”,

“subnetPrefix”: “10.0.0.0/24”,

“virtualNetworkName”: “MyVNET”,

“networkSecurityGroupName”: “default-NSG”

},

The following code section indicates the creation of a Standard_LRS storage account where the public IP address will reside:

“resources”: [

{

“type”: “Microsoft.Storage/storageAccounts”,

“apiVersion”: “2021-04-01”,

“name”: “[variables(‘storageAccountName’)]”,

“location”: “[parameters(‘location’)]”,

“sku”: {

“name”: “Standard_LRS”

},

“kind”: “Storage”

},

{

“type”: “Microsoft.Network/publicIPAddresses”,

“apiVersion”: “2021-02-01”,

“name”: “[parameters(‘publicIpName’)]”,

“location”: “[parameters(‘location’)]”,

“sku”: {

“name”: “[parameters(‘publicIpSku’)]”

},

The following code section indicates the creation of the NSG with a basic inbound rule that will allow the remote desktop protocol on port 3389 from any source address. It is a security risk to do this with production VMs; it is recommended to rather use VPN access and local IP ranges instead:

“properties”: {

“publicIPAllocationMethod”:

“[parameters(‘publicIPAllocationMethod’)]”, “dnsSettings”: {

“domainNameLabel”: “[parameters(‘dnsLabelPrefix’)]”

}

}

},

{

“type”: “Microsoft.Network/networkSecurityGroups”,

“apiVersion”: “2021-02-01”,

“name”: “[variables(‘networkSecurityGroupName’)]”,

“location”: “[parameters(‘location’)]”,

“properties”: {

“securityRules”: [

{

“name”: “default-allow-3389”,

“properties”: {

“priority”: 1000,

“access”: “Allow”,

“direction”: “Inbound”,

“destinationPortRange”: “3389”,

“protocol”: “Tcp”,

“sourcePortRange”: “*”,

“sourceAddressPrefix”: “*”,

“destinationAddressPrefix”: “*”

}

}

]

}

Leave a Reply

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

Related Post