How to deploy a Virtual machine using ARM Template
ARM Template Overview
What is ARM Template
ARM Template is means of specifying the orchestration/configuration of deployments to an Azure resource group
ARM Template is based on JSON
It Allows us to declare the resources we intend to apply to a particular solution.
Through ARM Template we can do single grouping of explicit instructions vs a series of commands.
- It Enforces dependencies
- It eliminates misconfigurations
- No real support for conditionals
- It runs in parallel where ever possible
Configuration can be made in the template or through parameters password to the template via command line or a parameter file
ARM Template runs in Powershell, CLI, REST API,portal as a visual studio project or via VS Code
ARM Template Features
-------------------------------
Current resources can be exported to the ARM template from the portal
Template can be linked, allowing you to repeat parts of a deployment task among several deployment template
e.g. a linked, default virtual network template
You can pass state between templates
Templates can run functions(e.g do math) and set dynamic variables at runtime
Templates can accept secrets from key Vault
Resources can be moved from one group to another
Output parameters
ARM Template deployment Modes
--------------------------------------------
1. Increment
Default mode
Does not remove or modify existing resources not mentioned in the template
Provides Support for versioning and rolling back deployments
2. Complete
Deletes any resource not mentioned in the template
It is best for "starting fresh"or refactoring a solution
There are various elements in an ARM Template
1.schema -- Required
2.contentversion -- Required
3.parameters
4.variables
5.resources --> Required
6.outputs
Q. What is New-AzureRmResourcegroupDeployment
Ans:-
The New-AzureRmResourceGroupDeployment cmdlet adds a deployment to an existing resource group. This includes the resources that the deployment requires.
An Azure resource is a user-managed Azure entity, such as a database server, database, website, virtual machine, or Storage account.
An Azure resource group is a collection of Azure resources that are deployed as a unit, such as the website, database server, and databases that are required for a financial website.
A resource group deployment uses a template to add resources to a resource group and publishes them so that they are available in Azure. To add resources to a resource group without using a template, use the New-AzureRmResource cmdlet.
To add a resource group deployment, specify the name of an existing resource group and a resource group template.
A resource group template is a JSON string that represents a resource group for a complex cloud-based service, such as a web portal.
The template includes parameter placeholders for required resources and configurable property values, such as names and sizes. You can find many templates in the Azure template gallery or you can create your own templates. You can use the Get-AzureRmResourceGroupGalleryTemplate cmdlet to find a template in the gallery.
To use a custom template to create a resource group, specify the TemplateFile parameter or TemplateUri parameter.
Each template has parameters for configurable properties.
To specify values for the template parameters, specify the TemplateParameterFile parameter or the TemplateParameterObject parameter.
Example:-
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
Now our objective is to deploy one Virtual machine using ARM Template!
So lets start
1. open a notepad file and save file as parameters.json in C:\temp folder
copy below content in the file.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"value": "southcentralus"
},
"virtualMachineName": {
"value": "win2k1602"
},
"virtualMachineSize": {
"value": "Standard_D2s_v3"
},
"adminUsername": {
"value": "admin"
},
"virtualNetworkName": {
"value": "devrg1-vnet"
},
"networkInterfaceName": {
"value": "win2k1601473"
},
"networkSecurityGroupName": {
"value": "win2k1601-nsg"
},
"adminPassword": {
"value": "P@$$word!@123"
},
"storageAccountName": {
"value": "win2k16osstor"
},
"storageAccountType": {
"value": "Standard_LRS"
},
"addressPrefix": {
"value": "10.1.0.0/16"
},
"subnetName": {
"value": "dbsubnet"
},
"subnetPrefix": {
"value": "10.1.0.0/24"
},
"publicIpAddressName": {
"value": "win2k1602-ip"
},
"publicIpAddressType": {
"value": "Dynamic"
},
"publicIpAddressSku": {
"value": "Basic"
},
"autoShutdownStatus": {
"value": "Enabled"
},
"autoShutdownTime": {
"value": "19:00"
},
"autoShutdownTimeZone": {
"value": "UTC"
},
"autoShutdownNotificationStatus": {
"value": "Disabled"
},
"sqlConnectivityType": {
"value": "Private"
},
"sqlPortNumber": {
"value": 1433
},
"sqlStorageDisksCount": {
"value": 1
},
"sqlStorageWorkloadType": {
"value": "GENERAL"
},
"sqlStorageDisksConfigurationType": {
"value": "NEW"
},
"sqlStorageStartingDeviceId": {
"value": 2
},
"sqlStorageDeploymentToken": {
"value": 51206
},
"sqlAutopatchingDayOfWeek": {
"value": "Sunday"
},
"sqlAutopatchingStartHour": {
"value": "2"
},
"sqlAutopatchingWindowDuration": {
"value": "60"
},
"sqlAuthenticationLogin": {
"value": "admina"
},
"sqlAuthenticationPassword": {
"value": "P@$$word!@123"
},
"rServicesEnabled": {
"value": "false"
}
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2.open a notepad file and save file as Template.json in C:\temp folder
copy below content in the file.
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string"
},
"virtualMachineName": {
"type": "string"
},
"virtualMachineSize": {
"type": "string"
},
"adminUsername": {
"type": "string"
},
"virtualNetworkName": {
"type": "string"
},
"networkInterfaceName": {
"type": "string"
},
"networkSecurityGroupName": {
"type": "string"
},
"adminPassword": {
"type": "securestring"
},
"storageAccountName": {
"type": "string"
},
"storageAccountType": {
"type": "string"
},
"addressPrefix": {
"type": "string"
},
"subnetName": {
"type": "string"
},
"subnetPrefix": {
"type": "string"
},
"publicIpAddressName": {
"type": "string"
},
"publicIpAddressType": {
"type": "string"
},
"publicIpAddressSku": {
"type": "string"
},
"autoShutdownStatus": {
"type": "string"
},
"autoShutdownTime": {
"type": "string"
},
"autoShutdownTimeZone": {
"type": "string"
},
"autoShutdownNotificationStatus": {
"type": "string"
},
"sqlConnectivityType": {
"type": "string"
},
"sqlPortNumber": {
"type": "int"
},
"sqlStorageDisksCount": {
"type": "int"
},
"sqlStorageWorkloadType": {
"type": "string"
},
"sqlStorageDisksConfigurationType": {
"type": "string"
},
"sqlStorageStartingDeviceId": {
"type": "int"
},
"sqlStorageDeploymentToken": {
"type": "int"
},
"sqlAutopatchingDayOfWeek": {
"type": "string"
},
"sqlAutopatchingStartHour": {
"type": "string"
},
"sqlAutopatchingWindowDuration": {
"type": "string"
},
"sqlAuthenticationLogin": {
"type": "string"
},
"sqlAuthenticationPassword": {
"type": "securestring"
},
"rServicesEnabled": {
"type": "string"
}
},
"variables": {
"vnetId": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetId'), '/subnets/', parameters('subnetName'))]"
},
"resources": [
{
"name": "[parameters('virtualMachineName')]",
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2017-03-30",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/networkInterfaces/', parameters('networkInterfaceName'))]",
"[concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountName'))]"
],
"properties": {
"osProfile": {
"computerName": "[parameters('virtualMachineName')]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]",
"windowsConfiguration": {
"provisionVmAgent": "true"
}
},
"hardwareProfile": {
"vmSize": "[parameters('virtualMachineSize')]"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftSQLServer",
"offer": "SQL2017-WS2016",
"sku": "SQLDEV",
"version": "latest"
},
"osDisk": {
"createOption": "fromImage",
"vhd": {
"uri": "[concat(concat(reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2015-06-15').primaryEndpoints['blob'], 'vhds/'), parameters('virtualMachineName'), '20180405142317.vhd')]"
},
"name": "[parameters('virtualMachineName')]"
},
"dataDisks": [
{
"createOption": "empty",
"lun": 0,
"diskSizeGB": "1023",
"caching": "ReadOnly",
"name": "[concat(parameters('virtualMachineName'), '-disk-1')]",
"vhd": {
"uri": "[concat(concat(reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2015-06-15').primaryEndpoints['blob'], 'vhds/'), parameters('virtualMachineName'), '-disk-1-20180405142317', '.vhd')]"
}
}
]
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('networkInterfaceName'))]"
}
]
}
}
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Compute/virtualMachines/extensions",
"name": "[concat(parameters('virtualMachineName'), '/SqlIaasExtension')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/', parameters('virtualMachineName'))]",
"[concat('Microsoft.Compute/virtualMachines/', parameters('virtualMachineName'))]"
],
"properties": {
"type": "SqlIaaSAgent",
"publisher": "Microsoft.SqlServer.Management",
"typeHandlerVersion": "1.2",
"autoUpgradeMinorVersion": "true",
"settings": {
"AutoTelemetrySettings": {
"Region": "[parameters('location')]"
},
"AutoPatchingSettings": {
"PatchCategory": "WindowsMandatoryUpdates",
"Enable": true,
"DayOfWeek": "[parameters('sqlAutopatchingDayOfWeek')]",
"MaintenanceWindowStartingHour": "[parameters('sqlAutopatchingStartHour')]",
"MaintenanceWindowDuration": "[parameters('sqlAutopatchingWindowDuration')]"
},
"KeyVaultCredentialSettings": {
"Enable": false,
"CredentialName": ""
},
"ServerConfigurationsManagementSettings": {
"SQLConnectivityUpdateSettings": {
"ConnectivityType": "[parameters('sqlConnectivityType')]",
"Port": "[parameters('sqlPortNumber')]"
},
"SQLWorkloadTypeUpdateSettings": {
"SQLWorkloadType": "[parameters('sqlStorageWorkloadType')]"
},
"SQLStorageUpdateSettings": {
"DiskCount": "[parameters('sqlStorageDisksCount')]",
"NumberOfColumns": "[parameters('sqlStorageDisksCount')]",
"StartingDeviceID": "[parameters('sqlStorageStartingDeviceId')]",
"DiskConfigurationType": "[parameters('sqlStorageDisksConfigurationType')]"
},
"AdditionalFeaturesServerConfigurations": {
"IsRServicesEnabled": "[parameters('rServicesEnabled')]"
}
}
},
"protectedSettings": {
"SQLAuthUpdateUserName": "[parameters('sqlAuthenticationLogin')]",
"SQLAuthUpdatePassword": "[parameters('sqlAuthenticationPassword')]"
}
}
},
{
"name": "[concat('shutdown-computevm-', parameters('virtualMachineName'))]",
"type": "Microsoft.DevTestLab/schedules",
"apiVersion": "2017-04-26-preview",
"location": "[parameters('location')]",
"properties": {
"status": "[parameters('autoShutdownStatus')]",
"taskType": "ComputeVmShutdownTask",
"dailyRecurrence": {
"time": "[parameters('autoShutdownTime')]"
},
"timeZoneId": "[parameters('autoShutdownTimeZone')]",
"targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]",
"notificationSettings": {
"status": "[parameters('autoShutdownNotificationStatus')]",
"timeInMinutes": "30"
}
},
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/', parameters('virtualMachineName'))]"
]
},
{
"name": "[parameters('storageAccountName')]",
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2015-06-15",
"location": "[parameters('location')]",
"properties": {
"accountType": "[parameters('storageAccountType')]"
}
},
{
"name": "[parameters('virtualNetworkName')]",
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2017-08-01",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('addressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"addressPrefix": "[parameters('subnetPrefix')]"
}
}
]
}
},
{
"name": "[parameters('networkInterfaceName')]",
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2016-09-01",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
"[concat('Microsoft.Network/publicIpAddresses/', parameters('publicIpAddressName'))]",
"[concat('Microsoft.Network/networkSecurityGroups/', parameters('networkSecurityGroupName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
},
"privateIPAllocationMethod": "Dynamic",
"publicIpAddress": {
"id": "[resourceId('Microsoft.Network/publicIpAddresses', parameters('publicIpAddressName'))]"
}
}
}
],
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]"
}
}
},
{
"name": "[parameters('publicIpAddressName')]",
"type": "Microsoft.Network/publicIpAddresses",
"apiVersion": "2017-08-01",
"location": "[parameters('location')]",
"properties": {
"publicIpAllocationMethod": "[parameters('publicIpAddressType')]"
},
"sku": {
"name": "[parameters('publicIpAddressSku')]"
}
},
{
"name": "[parameters('networkSecurityGroupName')]",
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2017-06-01",
"location": "[parameters('location')]",
"properties": {
"securityRules": [
{
"name": "default-allow-rdp",
"properties": {
"priority": 1000,
"protocol": "TCP",
"access": "Allow",
"direction": "Inbound",
"sourceAddressPrefix": "*",
"sourcePortRange": "*",
"destinationAddressPrefix": "*",
"destinationPortRange": "3389"
}
}
]
}
}
],
"outputs": {
"adminUsername": {
"type": "string",
"value": "[parameters('adminUsername')]"
}
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3. Go to Powershell Windows PowerShell ISE Console
copy and paste below scripts to the console
Script will ask 5 inputs
1. SubscriptionId --> This will be your Subscription ID
2. ResourceGroupName --> This will be name of your resourcegroup, you can give any string value
3. DeploymentName --> Here you can pass mydeployment01
4. Then it will ask for your azure credentail
5. Then it will ask for location : <kindly put your location which has less latency from your location>
<#
.SYNOPSIS
Deploys a template to Azure
.DESCRIPTION
Deploys an Azure Resource Manager template
.PARAMETER subscriptionId
The subscription id where the template will be deployed.
.PARAMETER resourceGroupName
The resource group where the template will be deployed. Can be the name of an existing or a new resource group.
.PARAMETER resourceGroupLocation
Optional, a resource group location. If specified, will try to create a new resource group in this location. If not specified, assumes resource group is existing.
.PARAMETER deploymentName
The deployment name.
.PARAMETER templateFilePath
Optional, path to the template file. Defaults to template.json.
.PARAMETER parametersFilePath
Optional, path to the parameters file. Defaults to parameters.json. If file is not found, will prompt for parameter values based on template.
#>
param(
[Parameter(Mandatory=$True)]
[string]
$subscriptionId,
[Parameter(Mandatory=$True)]
[string]
$resourceGroupName,
[string]
$resourceGroupLocation,
[Parameter(Mandatory=$True)]
[string]
$deploymentName,
[string]
$templateFilePath = "C:\Temp\template.json",
[string]
$parametersFilePath = "C:\Temp\parameters.json"
)
<#
.SYNOPSIS
Registers RPs
#>
Function RegisterRP {
Param(
[string]$ResourceProviderNamespace
)
Write-Host "Registering resource provider '$ResourceProviderNamespace'";
Register-AzureRmResourceProvider -ProviderNamespace $ResourceProviderNamespace;
}
#******************************************************************************
# Script body
# Execution begins here
#******************************************************************************
$ErrorActionPreference = "Stop"
# sign in
Write-Host "Logging in...";
Login-AzureRmAccount;
# select subscription
Write-Host "Selecting subscription '$subscriptionId'";
Select-AzureRmSubscription -SubscriptionID $subscriptionId;
# Register RPs
$resourceProviders = @("microsoft.compute","microsoft.devtestlab","microsoft.storage","microsoft.network");
if($resourceProviders.length) {
Write-Host "Registering resource providers"
foreach($resourceProvider in $resourceProviders) {
RegisterRP($resourceProvider);
}
}
#Create or check for existing resource group
$resourceGroup = Get-AzureRmResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue
if(!$resourceGroup)
{
Write-Host "Resource group '$resourceGroupName' does not exist. To create a new resource group, please enter a location.";
if(!$resourceGroupLocation) {
$resourceGroupLocation = Read-Host "resourceGroupLocation";
}
Write-Host "Creating resource group '$resourceGroupName' in location '$resourceGroupLocation'";
New-AzureRmResourceGroup -Name $resourceGroupName -Location $resourceGroupLocation
}
else{
Write-Host "Using existing resource group '$resourceGroupName'";
}
# Start the deployment
Write-Host "Starting deployment...";
if(Test-Path $parametersFilePath) {
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath -TemplateParameterFile $parametersFilePath;
} else {
New-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateFile $templateFilePath;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This will create a normal a Normal -- Standard_D2s_v3 machine. if you want to change the machine virtualMachineSize
execute below powershell script the get another machine size.
If you want to configure similar machine in existing resource group and in same subnet, then you need to make 3 changes in parameter.json file.
1. Virtual Machine Name
"virtualMachineName": {
"value": "win2k1603"
},
2. Network InterfaceName
"networkInterfaceName": {
"value": "win2k1601474"
},
3. PublicIpAddressName
"publicIpAddressName": {
"value": "win2k1602-ip"
},
and then execute powershell script which i provided in step -3.
Now you are done. In this way you can install many servers in Azure portal at a time..
Now you can Monitor and update a Windows Virtual Machine with Azure PowerShell
- Enable boot diagnostics on a VM
- View boot diagnostics
- View VM host metrics
- Install the diagnostics extension
- View VM metrics
- Create an alert
- Manage Windows updates
- Monitor changes and inventory
- Set up advanced monitoring
Refer this link for doing all these tasks
Thanks for Reading..