For those who don’t know ARM, this is Azure Resource Manager. It is used for everything in Azure to submit changes, additions and deletions to Azure infrastructure. These are all made via a common API which takes the changes, validates, queues and reports on any change. Regardless of if you use the Azure Portal, Cloud Shell, API, PowerShell or other tools they all use ARM.
Lets take a look.
First of all visit portal.azure.com and authenticate to your subscription. Next click in the master search box at the top and type ‘Activity’ and select the Activity Log
You may then need to change your filter applied to see jobs or tasks that have occured.
Each item can be examined an a JSON representation of the job and actions can be seen.
For any deployment a set of files are required for deployment. When using the Azure Portal, these are created by the web pages and then used to deploy as a Job by Azure Resource Manager.
You can see this just before you hit deploy
Then at the bottom select the ‘download template and parameters’ link
This will display a template page (ill do another post on this) however for now select download.
This will download a ZIP file to your local machine. Save and Open it. From an example I deployed the following files were created
The key files are the parameters.json and template.json files. These are mandatory. The others are scripts and helpers to run the deployment task. (.PS1 for PowerShell/CloudShell, .sh for Bash, .rb for Ruby deployments etc.
All of the settings for the deployment are contained within the parameters.json file. Open it up with a suitable editor such as vsCode or Notepad++
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "vmName": { "value": "azlab2000-fw-asa" }, "softwareVersion": { "value": "910.1.11" }, "adminUsername": { "value": "fwadmin" }, "adminPassword": { "value": null }, "authenticationType": { "value": "password" }, "vmSize": { "value": "Standard_D3_v2" }, "location": { "value": "centralus" }, "storageAccountName": { "value": "azlab2000fwasa" }, "storageAccountType": { "value": "Standard_LRS" }, "storageAccountNewOrExisting": { "value": "new" }, "storageAccountRG": { "value": "rg-firewalltest-asa" }, "publicIPAddressName": { "value": "azlab2000fwasa" }, "publicIPDnsLabel": { "value": "azlab2000fwasa" }, "publicIPNewOrExisting": { "value": "new" }, "publicIPRG": { "value": "rg-firewalltest-asa" }, "publicIPAllocationMethod": { "value": "Dynamic" }, "publicIPsku": { "value": "Basic" }, "virtualNetworkName": { "value": "vn-firewalltest" }, "virtualNetworkAddressPrefixes": { "value": [ "172.16.32.0/20" ] }, "virtualNetworkNewOrExisting": { "value": "existing" }, "virtualNetworkRG": { "value": "rg-firewalltest-common" }, "Subnet1Name": { "value": "sn-172.16.32.0_MGT" }, "Subnet1Prefix": { "value": "172.16.32.0/24" }, "Subnet2Name": { "value": "sn-172.16.33.0_WAN" }, "Subnet2Prefix": { "value": "172.16.33.0/24" }, "Subnet3Name": { "value": "sn-172.16.34.0_LAN" }, "Subnet3Prefix": { "value": "172.16.34.0/24" }, "Subnet4Name": { "value": "sn-172.16.35.0_DMZ" }, "Subnet4Prefix": { "value": "172.16.35.0/24" }, "subnet1StartAddress": { "value": "172.16.32.4" }, "subnet2StartAddress": { "value": "172.16.33.4" }, "subnet3StartAddress": { "value": "172.16.34.4" }, "subnet4StartAddress": { "value": "172.16.35.4" } } }
As you can see, variables are well named and obvious and being is JSON format its easy to check its well formatted. Values can be changed and as long as they validate against your exisiting constructs (for instance subnets and vNets) then it should be OK
Now open template.json
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "location": { "type": "string", "metadata": { "description": "Deployment location" } }, "virtualNetworkName": { "defaultValue": "ASAv_Network", "type": "string", "metadata": { "description": "Virtual Network name" } }, "virtualNetworkRG": { "defaultValue": "", "type": "string", "metadata": { "description": "Identifies whether to use new or existing Storage Account" } }, "virtualNetworkAddressPrefixes": { "defaultValue": "", "type": "array", "metadata": { "description": "Virtual Network Address prefixes" } }, "virtualNetworkNewOrExisting": { "defaultValue": "", "type": "string", "metadata": { "description": "Identifies whether to use new or existing Virtual Network" } }, "Subnet1Prefix": { "defaultValue": "", "type": "string", "metadata": { "description": "Subnet 1 Prefix" } }, "Subnet1Name": { "defaultValue": "", "type": "string", "metadata": { "description": "Subnet 1 Name" } }, "subnet1StartAddress": { "type": "string", "metadata": { "description": "Subnet 1 Starting IP Address" } }, "Subnet2Prefix": { "defaultValue": "", "type": "string", "metadata": { "description": "Subnet 2 Prefix" } }, "Subnet2Name": { "defaultValue": "", "type": "string", "metadata": { "description": "Subnet 2 Name" } }, "subnet2StartAddress": { "type": "string", "metadata": { "description": "Subnet 2 Starting IP Address" } }, "Subnet3Prefix": { "defaultValue": "", "type": "string", "metadata": { "description": "Subnet 3 Prefix" } }, "Subnet3Name": { "defaultValue": "", "type": "string", "metadata": { "description": "Subnet 3 Name" } }, "subnet3StartAddress": { "type": "string", "metadata": { "description": "Subnet 3 Starting IP Address" } }, "Subnet4Prefix": { "defaultValue": "", "type": "string", "metadata": { "description": "Subnet 4 Prefix" } }, "Subnet4Name": { "defaultValue": "", "type": "string", "metadata": { "description": "Subnet 4 Name" } }, "subnet4StartAddress": { "type": "string", "metadata": { "description": "Subnet 4 Starting IP Address" } }, "adminUsername": { "defaultValue": "", "type": "string", "metadata": { "description": "Username for the Virtual Machine." } }, "adminPassword": { "defaultValue": "", "type": "securestring", "metadata": { "description": "Password for the Virtual Machine." } }, "sshPublicKey": { "defaultValue": "", "type": "string", "metadata": { "description": "SSH Key for the virtual machines" } }, "authenticationType": { "defaultValue": "", "allowedValues": [ "password", "sshPublicKey" ], "type": "string", "metadata": { "description": "Authentication Type to chose for the Virtual Machines" } }, "vmName": { "defaultValue": "ASAv", "type": "string", "metadata": { "description": "Name for the Virtual Machine." } }, "softwareVersion": { "type": "string", "defaultValue": "910.1.11", "allowedValues": [ "910.1.11", "910.1.0", "99.2.18", "99.1.6" ], "metadata": { "description": "Software version to deploy." } }, "storageAccountName": { "type": "string", "metadata": { "description": "Unique Name for Storage Account where the Virtual Machine's disks and/or diagnostic files will be placed." } }, "storageAccountType": { "defaultValue": "Standard_LRS", "allowedValues": [ "Standard_LRS" ], "type": "string", "metadata": { "description": "The type of storage account created." } }, "storageAccountNewOrExisting": { "type": "string", "defaultValue": "new", "allowedValues": [ "new", "existing" ], "metadata": { "description": "Identifies whether to use new or existing Storage Account" } }, "storageAccountRG": { "type": "string", "defaultValue": "[resourceGroup().name]", "metadata": { "description": "Resource Group containing existing storage account" } }, "publicIPAddressName": { "defaultValue": "", "type": "string", "metadata": { "description": "Name of the Public IP Address" } }, "publicIPDnsLabel": { "type": "string", "metadata": { "description": "Unique DNS Prefix for the Public IP used to access the Virtual Machine." } }, "publicIPNewOrExisting": { "defaultValue": "new", "allowedValues": [ "new", "existing" ], "type": "string", "metadata": { "description": "Indicates whether the Public IP is new or existing" } }, "publicIPRG": { "type": "string", "defaultValue": "[resourceGroup().name]", "metadata": { "description": "Resource Group of the public IP" } }, "publicIPAllocationMethod": { "defaultValue": "Static", "type": "string", "allowedValues": [ "Dynamic", "Static" ], "metadata": { "description": "Select Dynamic or Static as the type of public IP." } }, "publicIPsku": { "type": "string", "defaultValue": "Basic", "allowedValues": [ "Basic", "Standard" ], "metadata": { "description": "Indicates whether the public IP will be of Basic SKU or Standard SKU" } }, "vmSize": { "defaultValue": "Standard_D3_v2", "allowedValues": [ "Standard_D3", "Standard_D3_v2" ], "type": "string", "metadata": { "description": "Size of the Virtual Machine" } } }, "variables": { "imagePublisher": "cisco", "imageOffer": "cisco-asav", "imageSKU": "asav-azure-byol", "softwareVersion": "[parameters('softwareVersion')]", "OSDiskName": "[concat(parameters('vmName'),'-disk')]", "vnetID": "[resourceId(parameters('virtualNetworkRG'),'Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]", "subnet1Ref": "[concat(variables('vnetID'),'/subnets/', parameters('Subnet1Name'))]", "subnet2Ref": "[concat(variables('vnetID'),'/subnets/', parameters('Subnet2Name'))]", "subnet3Ref": "[concat(variables('vnetID'),'/subnets/', parameters('Subnet3Name'))]", "subnet4Ref": "[concat(variables('vnetID'),'/subnets/', parameters('Subnet4Name'))]", "routeTable1Name": "[concat(parameters('Subnet1Name'),'-ASAv-RouteTable')]", "routeTable2Name": "[concat(parameters('Subnet2Name'),'-ASAv-RouteTable')]", "routeTable3Name": "[concat(parameters('Subnet3Name'),'-ASAv-RouteTable')]", "routeTable4Name": "[concat(parameters('Subnet4Name'),'-ASAv-RouteTable')]", "routeTable1Id": "[resourceId(parameters('virtualNetworkRG'),'Microsoft.Network/routeTables',variables('routeTable1Name'))]", "routeTable2Id": "[resourceId(parameters('virtualNetworkRG'),'Microsoft.Network/routeTables',variables('routeTable2Name'))]", "routeTable3Id": "[resourceId(parameters('virtualNetworkRG'),'Microsoft.Network/routeTables',variables('routeTable3Name'))]", "routeTable4Id": "[resourceId(parameters('virtualNetworkRG'),'Microsoft.Network/routeTables',variables('routeTable4Name'))]", "nsgname": "[concat(parameters('vmName'),'-SecurityGroup')]", "sshKeyPath": "[concat('/home/',parameters('adminUsername'),'/.ssh/authorized_keys')]", "osProfilesshPublicKey": { "computername": "[parameters('vmName')]", "adminUsername": "[parameters('adminUsername')]", "linuxConfiguration": { "disablePasswordAuthentication": "true", "ssh": { "publicKeys": [ { "path": "[variables('sshKeyPath')]", "keyData": "[parameters('sshPublicKey')]" } ] } } }, "osProfilepassword": { "computername": "[parameters('vmName')]", "adminUsername": "[parameters('adminUsername')]", "adminPassword": "[parameters('adminPassword')]" } }, "resources": [ { "apiVersion": "2018-02-01", "name": "pid-5d91b9f4-27ad-53ca-bd33-de577ae21ef8", "type": "Microsoft.Resources/deployments", "properties": { "mode": "Incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "resources": [] } } }, { "name": "[parameters('storageAccountName')]", "type": "Microsoft.Storage/storageAccounts", "apiVersion": "2018-02-01", "condition": "[equals(parameters('storageAccountNewOrExisting'),'new')]", "sku": { "name": "[parameters('storageAccountType')]" }, "kind": "Storage", "location": "[parameters('location')]", "properties": {} }, { "name": "[parameters('publicIPAddressName')]", "type": "Microsoft.Network/publicIPAddresses", "apiVersion": "2017-10-01", "condition": "[equals(parameters('publicIPNewOrExisting'),'new')]", "location": "[parameters('location')]", "sku": { "name": "[parameters('publicIPsku')]" }, "properties": { "publicIPAllocationMethod": "[parameters('publicIPAllocationMethod')]", "dnsSettings": { "domainNameLabel": "[parameters('publicIPDnsLabel')]" }, "idleTimeoutInMinutes": 30 } }, { "name": "[variables('nsgname')]", "type": "Microsoft.Network/networkSecurityGroups", "apiVersion": "2018-08-01", "location": "[parameters('location')]", "properties": { "securityRules": [ { "name": "SSH-Rule", "properties": { "description": "Allow SSH", "protocol": "Tcp", "sourcePortRange": "*", "destinationPortRange": "22", "sourceAddressPrefix": "*", "destinationAddressPrefix": "*", "access": "Allow", "priority": 100, "direction": "Inbound" } }, { "name": "UDP-Rule1", "properties": { "description": "Allow UDP", "protocol": "Udp", "sourcePortRange": "*", "destinationPortRange": "500", "sourceAddressPrefix": "*", "destinationAddressPrefix": "*", "access": "Allow", "priority": 101, "direction": "Inbound" } }, { "name": "UDP-Rule2", "properties": { "description": "Allow UDP", "protocol": "Udp", "sourcePortRange": "*", "destinationPortRange": "4500", "sourceAddressPrefix": "*", "destinationAddressPrefix": "*", "access": "Allow", "priority": 102, "direction": "Inbound" } } ] } }, { "name": "[variables('routeTable1Name')]", "type": "Microsoft.Network/routeTables", "condition": "[equals(parameters('virtualNetworkNewOrExisting'),'new')]", "apiVersion": "2018-08-01", "location": "[parameters('location')]", "properties": { "routes": [] } }, { "name": "[variables('routeTable2Name')]", "type": "Microsoft.Network/routeTables", "condition": "[equals(parameters('virtualNetworkNewOrExisting'),'new')]", "apiVersion": "2018-08-01", "location": "[parameters('location')]", "properties": { "routes": [] } }, { "name": "[variables('routeTable3Name')]", "type": "Microsoft.Network/routeTables", "condition": "[equals(parameters('virtualNetworkNewOrExisting'),'new')]", "apiVersion": "2018-08-01", "location": "[parameters('location')]", "properties": { "routes": [] } }, { "name": "[variables('routeTable4Name')]", "type": "Microsoft.Network/routeTables", "condition": "[equals(parameters('virtualNetworkNewOrExisting'),'new')]", "apiVersion": "2018-08-01", "location": "[parameters('location')]", "properties": { "routes": [] } }, { "name": "[parameters('virtualNetworkName')]", "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2018-08-01", "condition": "[equals(parameters('virtualNetworkNewOrExisting'),'new')]", "location": "[parameters('location')]", "dependsOn": [ "[concat('Microsoft.Network/routeTables/', variables('routeTable1Name'))]", "[concat('Microsoft.Network/routeTables/', variables('routeTable2Name'))]", "[concat('Microsoft.Network/routeTables/', variables('routeTable3Name'))]", "[concat('Microsoft.Network/routeTables/', variables('routeTable4Name'))]" ], "properties": { "addressSpace": { "addressPrefixes": "[parameters('virtualNetworkAddressPrefixes')]" }, "subnets": [ { "name": "[parameters('Subnet1Name')]", "properties": { "addressPrefix": "[parameters('Subnet1Prefix')]", "routeTable": { "id": "[variables('routeTable1Id')]" } } }, { "name": "[parameters('Subnet2Name')]", "properties": { "addressPrefix": "[parameters('Subnet2Prefix')]", "routeTable": { "id": "[variables('routeTable2Id')]" } } }, { "name": "[parameters('Subnet3Name')]", "properties": { "addressPrefix": "[parameters('Subnet3Prefix')]", "routeTable": { "id": "[variables('routeTable3Id')]" } } }, { "name": "[parameters('Subnet4Name')]", "properties": { "addressPrefix": "[parameters('Subnet4Prefix')]", "routeTable": { "id": "[variables('routeTable4Id')]" } } } ] } }, { "name": "[concat(parameters('vmName'),'-Nic0')]", "type": "Microsoft.Network/networkInterfaces", "apiVersion": "2018-08-01", "location": "[parameters('location')]", "dependsOn": [ "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", "[concat('Microsoft.Network/networkSecurityGroups/',variables('nsgname'))]", "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'))]" ], "properties": { "ipConfigurations": [ { "name": "ipconfig1", "properties": { "privateIPAllocationMethod": "Static", "privateIPAddress": "[parameters('subnet1StartAddress')]", "subnet": { "id": "[variables('subnet1Ref')]" }, "publicIPAddress": { "id": "[resourceId(parameters('publicIPRG'),'Microsoft.Network/publicIPAddresses',parameters('publicIPAddressName'))]" } } } ], "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgname'))]" }, "enableIPForwarding": true } }, { "name": "[concat(parameters('vmName'),'-Nic1')]", "type": "Microsoft.Network/networkInterfaces", "apiVersion": "2018-08-01", "location": "[parameters('location')]", "dependsOn": [ "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" ], "properties": { "ipConfigurations": [ { "name": "ipconfig1", "properties": { "privateIPAllocationMethod": "Static", "privateIPAddress": "[parameters('subnet2StartAddress')]", "subnet": { "id": "[variables('subnet2Ref')]" } } } ], "enableIPForwarding": true } }, { "name": "[concat(parameters('vmName'),'-Nic2')]", "type": "Microsoft.Network/networkInterfaces", "apiVersion": "2018-08-01", "location": "[parameters('location')]", "dependsOn": [ "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" ], "properties": { "ipConfigurations": [ { "name": "ipconfig1", "properties": { "privateIPAllocationMethod": "Static", "privateIPAddress": "[parameters('subnet3StartAddress')]", "subnet": { "id": "[variables('subnet3Ref')]" } } } ], "enableIPForwarding": true } }, { "name": "[concat(parameters('vmName'),'-Nic3')]", "type": "Microsoft.Network/networkInterfaces", "apiVersion": "2018-08-01", "location": "[parameters('location')]", "dependsOn": [ "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]" ], "properties": { "ipConfigurations": [ { "name": "ipconfig1", "properties": { "privateIPAllocationMethod": "Static", "privateIPAddress": "[parameters('subnet4StartAddress')]", "subnet": { "id": "[variables('subnet4Ref')]" } } } ], "enableIPForwarding": true } }, { "name": "[parameters('vmName')]", "type": "Microsoft.Compute/virtualMachines", "apiVersion": "2018-06-01", "location": "[parameters('location')]", "dependsOn": [ "[concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountName'))]", "[concat('Microsoft.Network/networkInterfaces/',parameters('vmName'),'-Nic0')]", "[concat('Microsoft.Network/networkInterfaces/',parameters('vmName'),'-Nic1')]", "[concat('Microsoft.Network/networkInterfaces/',parameters('vmName'),'-Nic2')]", "[concat('Microsoft.Network/networkInterfaces/',parameters('vmName'),'-Nic3')]" ], "plan": { "name": "asav-azure-byol", "publisher": "cisco", "product": "cisco-asav" }, "properties": { "hardwareProfile": { "vmSize": "[parameters('vmSize')]" }, "osProfile": "[if(equals(parameters('authenticationType'),'password'), variables('osProfilepassword'), variables('osProfilesshPublicKey'))]", "storageProfile": { "imageReference": { "publisher": "[variables('imagePublisher')]", "offer": "[variables('imageOffer')]", "sku": "[variables('imageSKU')]", "version": "[variables('softwareVersion')]" }, "osDisk": { "name": "[variables('OSDiskName')]", "vhd": { "uri": "[concat(reference(resourceId(parameters('storageAccountRG'),'Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '2018-02-01').primaryEndpoints.blob,'vhds/', variables('OSDiskName'), '.vhd')]" }, "caching": "ReadWrite", "createOption": "FromImage", "diskSizeGB": 9 } }, "networkProfile": { "networkInterfaces": [ { "properties": { "primary": true }, "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('vmName'),'-Nic0'))]" }, { "properties": { "primary": false }, "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('vmName'),'-Nic1'))]" }, { "properties": { "primary": false }, "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('vmName'),'-Nic2'))]" }, { "properties": { "primary": false }, "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('vmName'),'-Nic3'))]" } ] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, "storageuri": "[reference(resourceId(parameters('storageAccountRG'), 'Microsoft.Storage/storageAccounts/', parameters('storageAccountName')), '2018-02-01').primaryEndpoints.blob]" } } } } ] }
This file takes the parameters.json file’s values and uses them to create Azure components. The parameters.json being the ingredients and the template.json being the cook book if you like !
This can be deployed using an authenticated Powershell session thus:
#Assumes files are in current path New-AzResourceGroupDeployment -Name TestASAdeploy -ResourceGroupName test_ASA01_Deployment -TemplateFile template.json `-TemplateParameterFile parameters.json
This will then deploy to a new Resource Group using the parameters and template file.
Follow my next post in the series about removing Public IP address from Azure deployments.
Recent Comments