Monday, July 22, 2019

Explaining ARM templates







In Azure and Azure Stack, the Azure Resource Manager is the management layer (API) where you connect to for deploying resources. Here we are going to look at the Azure Resource Template and how to use it when deploying resources.When deploying resources with Azure Resource Manager keep in mind the following aspects. It is:

  • Template-driven – Using templates to deploy all resources.
  • Declarative – You declare the resources you want to have instead of imperative where you need to make rules.
  • Idempotent – You can deploy the template over and over again without affecting the current state of resources.
  • Multi-service – All services can be deployed using Azure Resource Manager, Website, Storage, VMs etc.
  • Multi region- You can choose in which region you would like to deploy the resources.
  • Extensible – Azure Resource Manager is extensible with more resource providers and thus resources.
We can deploy resource templates using azure portal, power shell and azure CLI. But before deploying the resources we have to create the "resource group" first because we have to mention the resource group first while starting the deployment .

Basically ARM template is a jason file and its structure is given below 










Element name Required Description
$schema Yes Location of the JSON schema file that describes the version of the template language.
version yes version of the templete for deplyment for reference purpose 
parameters No Values that are provided when deployment is executed to customize resource deployment.
variables No Values that are used as JSON fragments in the template to simplify template language expressions.
resources Yes Types of services that are deployed or updated in a resource group.
outputs No Values that are returned after deployment.

Parameters:

When you start a new deployment and you have parameters defined in your resource template then these needs to be entered in before the deployment can start. It are values used for that specific deployment. These parameters are then used in other sections of the template. When we look at a parameter in the parameters section it can be for example a value to select a specific Operating System version when deploying a Virtual Machine:

For example definition of parameters for a linux VM is given below 

*************************************************************

    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "location": {
            "type": "string"
        },
        "networkInterfaceName": {
            "type": "string"
        },
        "networkSecurityGroupName": {
            "type": "string"
        },
        "networkSecurityGroupRules": {
            "type": "array"
        },
        "subnetName": {
            "type": "string"
        },
        "virtualNetworkName": {
            "type": "string"
        },
        "addressPrefixes": {
            "type": "array"
        },
        "subnets": {
            "type": "array"
        },
        "publicIpAddressName": {
            "type": "string"
        },
        "publicIpAddressType": {
            "type": "string"
        },
        "publicIpAddressSku": {
            "type": "string"
        },
        "virtualMachineName": {
            "type": "string"
        },
        "virtualMachineRG": {
            "type": "string"
        },
        "osDiskType": {
            "type": "string"
        },
        "virtualMachineSize": {
            "type": "string"
        },
        "adminUsername": {
            "type": "string"
        },
        "adminPassword": {
            "type": "secureString"
        },
        "diagnosticsStorageAccountName": {
            "type": "string"
        },
        "diagnosticsStorageAccountId": {
            "type": "string"
        },
        "diagnosticsStorageAccountType": {
            "type": "string"
        },
        "diagnosticsStorageAccountKind": {
            "type": "string"
        }
    },
***************************************************************

Here the name of the parameter is must have entity and same should be valid javascript identifier . Also type of the parameter also required , type can be string, intiger,array, object all are in a valid JASON format.

While deployment either we can mention the parameters when it is prompted or we can mention the parameters in a separate file called parameters.json


New-AzureResourceGroupDeployment -Name Testdeployment -ResourceGroupName unixchips -TemplateParameterFile .\templatename.params.json -TemplateFile .\templatename.json

Variables:

variables are the values  that can be constructed for example from parameters to create a variable and use that in other sections of your deployment template. Also a single value across multiple resources .

in our case for linux vm below are the variables defined 

****************************************************
"variables": {
        "nsgId": "[resourceId(resourceGroup().name, 'Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroupName'))]",
        "vnetId": "[resourceId(resourceGroup().name,'Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
        "subnetRef": "[concat(variables('vnetId'), '/subnets/', parameters('subnetName'))]"

Resources:

The resources session is the actual parameters which we are going to deploy or update. This can be collection of resources and its configuration settings . We can define them directly in to the resource or we can populate through parameter file.

***************************************************

    "resources": [
        {
            "name": "[parameters('networkInterfaceName')]",
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2018-10-01",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[concat('Microsoft.Network/networkSecurityGroups/', parameters('networkSecurityGroupName'))]",
                "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
                "[concat('Microsoft.Network/publicIpAddresses/', parameters('publicIpAddressName'))]"
            ],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipconfig1",
                        "properties": {
                            "subnet": {
                                "id": "[variables('subnetRef')]"
                            },
                            "privateIPAllocationMethod": "Dynamic",
                            "publicIpAddress": {
                                "id": "[resourceId(resourceGroup().name, 'Microsoft.Network/publicIpAddresses', parameters('publicIpAddressName'))]"
                            }
                        }
                    }
                ],
                "networkSecurityGroup": {
                    "id": "[variables('nsgId')]"
                }
            }
        },
        {
            "name": "[parameters('networkSecurityGroupName')]",
            "type": "Microsoft.Network/networkSecurityGroups",
            "apiVersion": "2019-02-01",
            "location": "[parameters('location')]",
            "properties": {
                "securityRules": "[parameters('networkSecurityGroupRules')]"
            }
        },
        {
            "name": "[parameters('virtualNetworkName')]",
            "type": "Microsoft.Network/virtualNetworks",
            "apiVersion": "2019-04-01",
            "location": "[parameters('location')]",
            "properties": {
                "addressSpace": {
                    "addressPrefixes": "[parameters('addressPrefixes')]"
                },
                "subnets": "[parameters('subnets')]"
            }
        },
        {
            "name": "[parameters('publicIpAddressName')]",
            "type": "Microsoft.Network/publicIpAddresses",
            "apiVersion": "2019-02-01",
            "location": "[parameters('location')]",
            "properties": {
                "publicIpAllocationMethod": "[parameters('publicIpAddressType')]"
            },
            "sku": {
                "name": "[parameters('publicIpAddressSku')]"
            }
        },
        {
            "name": "[parameters('virtualMachineName')]",
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2018-10-01",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[concat('Microsoft.Network/networkInterfaces/', parameters('networkInterfaceName'))]",
                "[concat('Microsoft.Storage/storageAccounts/', parameters('diagnosticsStorageAccountName'))]"
            ],
            "properties": {
                "hardwareProfile": {
                    "vmSize": "[parameters('virtualMachineSize')]"
                },
                "storageProfile": {
                    "osDisk": {
                        "createOption": "fromImage",
                        "managedDisk": {
                            "storageAccountType": "[parameters('osDiskType')]"
                        }
                    },
                    "imageReference": {
                        "publisher": "Canonical",
                        "offer": "UbuntuServer",
                        "sku": "18.04-LTS",
                        "version": "latest"
                    }
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('networkInterfaceName'))]"
                        }
                    ]
                },
                "osProfile": {
                    "computerName": "[parameters('virtualMachineName')]",
                    "adminUsername": "[parameters('adminUsername')]",
                    "adminPassword": "[parameters('adminPassword')]"
                },
                "diagnosticsProfile": {
                    "bootDiagnostics": {
                        "enabled": true,
                        "storageUri": "[concat('https://', parameters('diagnosticsStorageAccountName'), '.blob.core.windows.net/')]"
                    }
                }
            }
        },
        {
            "name": "[parameters('diagnosticsStorageAccountName')]",
            "type": "Microsoft.Storage/storageAccounts",
            "apiVersion": "2018-07-01",
            "location": "[parameters('location')]",
            "properties": {},
            "kind": "[parameters('diagnosticsStorageAccountKind')]",
            "sku": {
                "name": "[parameters('diagnosticsStorageAccountType')]"
            }
        }
    ],
******************************************************************

Main elements of resources are below ...

apiVersion: - This is a must have value which is the version of the API supports resources.

Type: Type of the resource. This value is a combination of the namespace of the resource provider and the resource type that the resource provider supports.

Name: Name of the resource 

Location: Supported geo-locations of the provided resource.

Tags: Tags that are associated with the resource.

Depends on: Resources that the resource being depends on . The dependencies between resources are evaluated and resources are deployed in their dependent order

Properties: Resource specific configuration settings

Outputs:

In this session we can define the output of the deployment template.These values can be for example a connection string from a deployment of a database. This can then be passed into another deployment to use for example as connection string for a website you are going to deploy.

************************************************************
"outputs": {
        "adminUsername": {
            "type": "string",
            "value": "[parameters('adminUsername')]"
        }


Output name: Name of the output value, must be a java script identifier 
Type:   Type of the output value, which is same as template input parameters
Value: Template language expression .

Deploying the ARM template using azure portal 

1. First we have to create a sample template file for the resource creation ( here the linux VM) . The best method is to fill the required fields needed to create the vm and download the template as below . Click on the download the template for automation.












2. This will create a zipped folder named "template", and it includes below contents in general . deploy (powershell script) , deploy (shell script), deployer.rb (ruby script),DeploymentHelper.cs, parameters.json (parameter file used for deployment) and Template.json ( common template file) 








3. Now go to create resource and select Template deployment  and click on the edit custom template option . You can upload the down loaded template.json file in the portal and upload the parameter file in the edit parameter option


































4. Once you uploaded the required template.json and parameter.json we can select the agree option and click the purchase button. This will validate all the data and deployment starts after the validation.













5. Once the deployment is succeeded if we check the virtual machine option we can see the VM is created successfully with all the data passed through parameter.json.












In next session i will explain how to deploy the ARM using power shell...

Login to the cloudshell from your portal.

1. First create the resource group named unixchips1

PS Azure:\> New-AzResourceGroup -Name unixchips1 -Location centralus

output
***********
ResourceGroupName : unixchips1
Location          : centralus
ProvisioningState : Succeeded
Tags              :
ResourceId        : /subscriptions/3878c3d5-8450-4eec-9a0f-183f6c4e569e/resourceGroups/unixchips1


Azure:/


2. Now deploy the template and parameters file using below command


PS /home/unixchips> New-AzResourceGroupDeployment -ResourceGroupName unixchips1 -TemplateFile /home/unixchips/template.json -TemplateParameterFile /home/unixchips/parameters.json

output
*****************************************************
DeploymentName          : template
ResourceGroupName       : unixchips1
ProvisioningState       : Succeeded
Timestamp               : 7/23/19 7:46:23 AM
Mode                    : Incremental
TemplateLink            :
Parameters              :
                          Name                             Type                       Value
                          ===============================  =========================  ==========
                          location                         String                     eastus
                          networkInterfaceName             String                     unixchipstest1766
                          networkSecurityGroupName         String                     unixchipstest1-nsg
                          networkSecurityGroupRules        Array                      [
                            {
                              "name": "SSH",
                              "properties": {
                                "priority": 300,
                                "protocol": "TCP",
                                "access": "Allow",
                                "direction": "Inbound",
                                "sourceAddressPrefix": "*",
                                "sourcePortRange": "*",
                                "destinationAddressPrefix": "*",
                                "destinationPortRange": "22"
                              }
                            },
                            {
                              "name": "HTTP",
                              "properties": {
                                "priority": 320,
                                "protocol": "TCP",
                                "access": "Allow",
                                "direction": "Inbound",
                                "sourceAddressPrefix": "*",
                                "sourcePortRange": "*",
                                "destinationAddressPrefix": "*",
                                "destinationPortRange": "80"
                              }
                            }
                          ]
                          subnetName                       String                     default
                          virtualNetworkName               String                     unixchips-vnet
                          addressPrefixes                  Array                      [
                            "10.0.0.0/24"
                          ]
                          subnets                          Array                      [
                            {
                              "name": "default",
                              "properties": {
                                "addressPrefix": "10.0.0.0/24"
                              }
                            }
                          publicIpAddressName              String                     unixchipstest1-ip
                          publicIpAddressType              String                     Dynamic
                          publicIpAddressSku               String                     Basic
                          virtualMachineName               String                     unixchipstest1
                          virtualMachineRG                 String                     unixchips
                          osDiskType                       String                     Premium_LRS
                          virtualMachineSize               String                     Standard_D2s_v3
                          adminUsername                    String                     unixchips
                          adminPassword                    SecureString
                          diagnosticsStorageAccountName    String                     unixchipsdiag
                          diagnosticsStorageAccountId      String                     Microsoft.Storage/storageAccounts/unixchipsdiag
                          diagnosticsStorageAccountType    String                     Standard_LRS
                          diagnosticsStorageAccountKind    String                     Storage

Outputs                 :
                          Name             Type                       Value
                          ===============  =========================  ==========
                          adminUsername    String                     unixchips

DeploymentDebugLogLevel :



Thank you for reading 

No comments:

Post a Comment