Click here to Skip to main content
14,972,394 members
Articles / DevOps / Deployment
Article
Posted 29 Dec 2016

Tagged as

Stats

4.9K views

Azure Environment Config. using ARM and PowerShell

Rate me:
Please Sign up or sign in to vote.
2.87/5 (7 votes)
31 Dec 2016CPOL3 min read
Azure Environment Config. using ARM and PowerShell

Introduction

In a scenario of cloud migration of existing applications or deployment of newly developed applications into Azure we come up with a deployment architecture that includes considerable number resources (VM,Websites,DBs etc..) to be  created and deployed in to the cloud environment. Creating the resources manually one by one is not only time consuming but also add to manpower utilization cost. We can think of an alternate approach so as to optimize the process and reduce the cost. This article describes how to deploy azure resources and configure Azure Environment, manage azure resources using Azure Resource Manager and PowerShell.

Background

Azure Resource Manager

This article walks you through the deployment of a resource in Azure using Azure Resource manager Template and PowerShell commandlets. We'll start with creating a ARM template to create and deploy Virtual Machine. Then, we'll walk you through how to view and delete the resources in Azure Environment.

What is Azure Resource Manager?

ARM is a Rest API that enables to deploy, manage, and monitor all the resources as a group using different tools and allows automating the deployment and configuration of hybrid infrastructure in Azure. It can repeatedly deploy the solution throughout the development lifecycle and ensure that resources are deployed in a consistent state.  ARM Provides security, auditing, and tagging features to help you manage your resources after deployment. It apply access control to all services in your resource group because Role-Based Access Control (RBAC) is natively integrated into the management platform .We use a template for deployment and that template can work for different environments such as testing, staging, and production.

ARM provides a consistent management layer for the tasks you perform through Azure using tools like PowerShell, Azure CLI, Azure portal, REST API, and Visual Studio .Using ARM template we can deploy the complete dev, test or prod environment as a group or solution and manage the resources.ARM supports the creation of the automation account, runbooks, credentials and variables the same way as for example VMs. Each-time you run your template these resources are created or modified.

Using the code

Create ARM Template:

  1. VM Creation Template : VirtualMachineTemplate.json
{

  "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "newStorageAccountName": {
      "type": "string",
      "metadata": {
        "Description": "The name of the storage account where the VM disk is stored."
      }
    },
    "adminUsername": {
      "type": "string",
      "metadata": {
        "Description": "The name of the administrator account on the VM."
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "Description": "The administrator account password on the VM."
      }
      },

      "dnsNameForPublicIP": {
        "type": "string",
        "metadata": {
          "Description": "The name of the public IP address used to access the VM."
        }
      }    
    },
    "variables": {
      "location": "Central US",
      "imagePublisher": "MicrosoftWindowsServer",
      "imageOffer": "WindowsServer",
      "windowsOSVersion": "2012-R2-Datacenter",
      "OSDiskName": "osdisk1",
      "nicName": "myvmnic",
      "addressPrefix": "10.0.0.0/16",
      "subnetName": "sn1",
      "subnetPrefix": "10.0.0.0/24",
      "storageAccountType": "Standard_LRS",
      "publicIPAddressName": "mypublicip",
      "publicIPAddressType": "Dynamic",
      "vmStorageAccountContainerName": "vhds",
      "vmName": "MyWindowsVM",
      "vmSize": "Standard_A0",
      "virtualNetworkName": "myvnet",
      "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
      "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]"
    },
    "resources": [
      {
        "type": "Microsoft.Storage/storageAccounts",
        "name": "[parameters('newStorageAccountName')]",
        "apiVersion": "2015-06-15",
        "location": "[variables('location')]",
        "properties": {
          "accountType": "[variables('storageAccountType')]"
        }
      },      {

        "apiVersion": "2016-03-30",
        "type": "Microsoft.Network/publicIPAddresses",
        "name": "[variables('publicIPAddressName')]",
        "location": "[variables('location')]",
        "properties": {
          "publicIPAllocationMethod": "[variables('publicIPAddressType')]",
          "dnsSettings": {
            "domainNameLabel": "[parameters('dnsNameForPublicIP')]"
          }}},
      {
        "apiVersion": "2016-03-30",
        "type": "Microsoft.Network/virtualNetworks",
        "name": "[variables('virtualNetworkName')]",
        "location": "[variables('location')]",
        "properties": {
          "addressSpace": {
            "addressPrefixes": [
              "[variables('addressPrefix')]"
            ]},
          "subnets": [
            {
              "name": "[variables('subnetName')]",
              "properties": {
                "addressPrefix": "[variables('subnetPrefix')]"
              } } ] }
      },
      {
        "apiVersion": "2016-03-30",
        "type": "Microsoft.Network/networkInterfaces",
        "name": "[variables('nicName')]",
        "location": "[variables('location')]",
        "dependsOn": [
          "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]",
          "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"
        ],
        "properties": {
          "ipConfigurations": [
            {
              "name": "ipconfig1",
              "properties": {
                "privateIPAllocationMethod": "Dynamic",
                "publicIPAddress": {
                  "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]"
                },
                "subnet": {
                  "id": "[variables('subnetRef')]"
                } } } ] }
      },
      {
        "apiVersion": "2015-06-15",
        "type": "Microsoft.Compute/virtualMachines",
        "name": "[variables('vmName')]",
        "location": "[variables('location')]",
        "dependsOn": [
          "[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'))]",
          "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
        ],
        "properties": {
          "hardwareProfile": {
            "vmSize": "[variables('vmSize')]"
          },
          "osProfile": {
            "computername": "[variables('vmName')]",
            "adminUsername": "[parameters('adminUsername')]",
            "adminPassword": "[parameters('adminPassword')]"
          },
          "storageProfile": {
            "imageReference": {
              "publisher": "[variables('imagePublisher')]",
              "offer": "[variables('imageOffer')]",
              "sku": "[variables('windowsOSVersion')]",
              "version": "latest"
            },
            "osDisk": {
              "name": "osdisk",
              "vhd": {
                "uri": "[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'),'.vhd')]"
              },
              "caching": "ReadWrite",
              "createOption": "FromImage"
            }
          },
          "networkProfile": {
            "networkInterfaces": [
              {
                "id": "[resourceId('Microsoft.Network/networkInterfaces',variables('nicName'))]"
              } ] } } } ]}

    2.VM Parameter Template: Parameter.json

param(
    {
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "newStorageAccountName": {
      "value": "xxxxxxxxxxx"
    },
    "adminUserName": {
      "value": "xxxxxxxxx"
    },
    "adminPassword": {
      "value": "xxxxxxxxxxx"
    },
    "dnsNameForPublicIP": {
      "value": "xxxxxxxxxxx"
    }
  }
} 

3.Save theses templates to locale path which needs to be passed as parameter to the PowerShell cmdlet.

Prerequisites to Execute PowerShell Cmdlets:

To execute ARM PowerShell cmdlets below are the system pre-requisites

  1. DotNet Framework version 4.5 and above
  2. PowerShell version 4.0 and above

Azure Power Shell

Deploy Azure Resources Using  PowerShell

  1. LogIn To Azure : Open “Windows PowerShell” command prompt and login to Azure platform using the below cmdlet.
LogIn-AzureRmAccount or Add-AzureRmAccount

   On enter the above command will prompt login screen to authenticate the end user.We need to provide Azure Subscription ID and Password.

 

2.Create a Resource Group: A Azure Resource Group is a Logical Container that holds resources that you want to manage as a group.

New-AzureRmResourceGroup -Name TestRG1 -Location "South Central US"

The output is in the following format:

ResourceGroupName : TestRG1
Location          : southcentralus
ProvisioningState : Succeeded
Tags              :
ResourceId        : /subscriptions/{guid}/resourceGroups/TestRG1

3.Deploy Resource in Azure Portal:

The below cmdlet is used to deploy the resource in Azure

New-AzureRmResourceGroupDeployment –ResourceGroupName ‘NameOfResourceGroup’ –TemplateFile ‘PathOfVMTemplateFile’ –TemplateParameterFile ‘PathOfVmParametersTemplateFile’

Once deployed successfully the below message will be displayed in PowerShell screen.

We can modify the json template to extend the no of resource and can deploy multiple resources by executing a single cmdlet.

When we login to azure environment we could see the resources up and running.

4.Create multiple resources using single ARM Template :

The below ARM Template can be re-used to create multiple VM  Azure at one go.

{
  "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "newStorageAccountName": {
      "type": "string",
      "defaultValue": "newstorageacfortest",
      "metadata": {
        "Description": "The name of the storage account where the VM disk is stored."
      }
    },
    "adminUsername": {
      "type": "string",
      "defaultValue": "TestAdminUser",
      "metadata": {
        "Description": "The name of the administrator account on the VM."
      }
    },
    "adminPassword": {
      "type": "securestring",
      "defaultValue": "Priyadarshini12#",
      "metadata": {
        "Description": "The administrator account password on the VM."
      }
    },
    "numberOfInstances": {
      "type": "int",
      "defaultValue": 3,
      "metadata": {
        "description": "Number of VMs to deploy"
      }
    },
    "multipleVMNames": {
      "type": "array",
      "defaultValue": [
        "27WindowsVM",
        "WebSite",
        "TestApi"
      ],
      "metadata": {
        "description": "Multiple VM Names array"
      }
    },
    "dnsNameForPublicIP": {
      "type": "string",
      "defaultValue": "dnsnameforiptest",
      "metadata": {
        "Description": "The name of the public IP address used to access the VM."
      }
   }
  },
  "variables": {
    "location": "Japan East",
    "imagePublisher": "MicrosoftWindowsServer",
    "imageOffer": "WindowsServer",
    "windowsOSVersion": "2012-R2-Datacenter",
    "OSDiskName": "osdisk1",
    "nicName": "8myvmnic",
    "addressPrefix": "10.0.0.0/16",
    "subnetName": "sn1",
    "subnetPrefix": "10.0.0.0/24",
    "storageAccountType": "Standard_LRS",
    "publicIPAddressName": "8mypublicip",
    "publicIPAddressType": "Dynamic",
    "vmStorageAccountContainerName": "vhds",
    "vmName": "27WindowsVM,WebSite,TestApi",
    "vmSize": "Standard_A0",
    "virtualNetworkName": "myvnet8",
    "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
    "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "name": "[parameters('newStorageAccountName')]",
      "apiVersion": "2015-06-15",
      "location": "[variables('location')]",
      "properties": {
        "accountType": "[variables('storageAccountType')]"
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/publicIPAddresses",
      "name": "[concat(variables('publicIPAddressName'), copyindex())]",
      "location": "[variables('location')]",
      "copy": {
        "name": "ipLoop",
        "count": "[parameters('numberOfInstances')]"
      },
      "properties": {
        "publicIPAllocationMethod": "[variables('publicIPAddressType')]",
        "dnsSettings": {
          "domainNameLabel": "[concat(parameters('dnsNameForPublicIP'),copyindex())]"
        }
      }
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/virtualNetworks",
      "name": "[variables('virtualNetworkName')]",
      "location": "[variables('location')]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[variables('addressPrefix')]"
          ]
        },
        "subnets": [
          {
            "name": "[variables('subnetName')]",
            "properties": {
              "addressPrefix": "[variables('subnetPrefix')]"
            } } ]}
    },
    {
      "apiVersion": "2016-03-30",
      "type": "Microsoft.Network/networkInterfaces",
      "name": "[concat(variables('nicName'), copyindex())]",
      "location": "[variables('location')]",
      "copy": {
        "name": "nicLoop",
        "count": "[parameters('numberOfInstances')]"
      },
      "dependsOn": [
        "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "subnet": {
                "id": "[variables('subnetRef')]"
              } }} ]}
    },
    {
      "apiVersion": "2015-06-15",
      "type": "Microsoft.Compute/virtualMachines",
      "name": "[parameters('multipleVMNames')[copyIndex()]]",
      "location": "[variables('location')]",
      "copy": {
        "name": "vmLoop",
        "count": "[parameters('numberOfInstances')]"
      },
      "dependsOn": [
        "[concat('Microsoft.Storage/storageAccounts/', parameters('newStorageAccountName'))]",
        "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'), copyindex())]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[variables('vmSize')]"
        },
        "osProfile": {
          "computerName": "[parameters('multipleVMNames')[copyIndex()]]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "[variables('imagePublisher')]",
            "offer": "[variables('imageOffer')]",
            "sku": "[variables('windowsOSVersion')]",
            "version": "latest"
          },
          "osDisk": {
            "name": "osdisk",
            "vhd": {
              "uri": "[concat('http://',parameters('newStorageAccountName'),'.blob.core.windows.net/',variables('vmStorageAccountContainerName'),'/',variables('OSDiskName'), copyIndex() ,'.vhd')]"
            },
            "caching": "ReadWrite",
            "createOption": "FromImage"
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces',concat(variables('nicName'), copyindex()))]"
            }] } } } ]
}

Find Resources in Resource Group:

Cmdlet to find resources in a Resource Group :

Find-AzureRmResource –ResourceGroupNameContains ‘XXXXXXXX’

Delete Resources using PowerShell

Cmdlet to delete resources from azure:

Remove-AzureRmResource –Name ‘XXXXXXXXX’ –ResourceGroupName ‘XXXXXXXX’ –ResourceType ‘XXXXXXXXXXXXX’

We can Check the status of delete operation in Azure portal.

Conclusion: ARM is a very effective API to deploy and manage resources. We can configure and manage resources of our Azure Environment using the ARM templates and PowerShell cmdlets. We can not only execute them repetitively in different phases of SDLC but also deploy azure resources in different environments like Dev,Test,Production thereby reducing cost and time.

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Swapna Patnaik
Architect
India India
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pin
Swapna Patnaik31-Dec-16 0:37
MemberSwapna Patnaik31-Dec-16 0:37 
QuestionFew things to fix Pin
Wendelius29-Dec-16 7:47
mveWendelius29-Dec-16 7:47 
AnswerRe: Few things to fix Pin
Member 129306583-Jan-17 5:46
MemberMember 129306583-Jan-17 5:46 
GeneralRe: Few things to fix Pin
Wendelius3-Jan-17 7:32
mveWendelius3-Jan-17 7:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.