Overview
In this series of blog posts I will create ARM templates used to provision Azure resources. I will kick things off by creating a template that shows you have to create multiple storage accounts. It also shows:
- How to use parameters of type arrays
- How to use length operator to iterate over elements of array
- How to use copy
- How to use output section of the template to display information about newly created resources.
- How you can use parameter files to provision resources in your dev, test and production environment.
Show me my template
Parameters: Lines 4-11
Like any other ARM template this template starts with a parameters section. Line 5 declares a parameter of type storageAccountList. It is of type array. This parameter will pass in an array of objects which will provide all the required details to provision a storage account.
Resources: Lines 12-26
This is the section where we iterate through the list of objects in the storageAccountList and provision storage accounts in a resource loop.
Line 14: Sets the name property of the storage account being provisioned
Line 17: Sets the Location property of the storage account being provisioned
Line 20: Uses length function to determine the number of elements in the storageAccountList
Line 23: Sets the accountType property of the storage account being provisioned
Outputs: Lines 27-40
This section displays details about the storage accounts that were provisioned.
Lines 30, 34 and 38 reference the storage accounts that were provisioned.
1: {
2: "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
3: "contentVersion": "1.0.0.0",
4: "parameters": {
5: "storageAccountList": {
6: "type": "array",
7: "metadata": {
8: "description": "List of storage accounts that need to be created"
9: }
10: }
11: },
12: "resources": [
13: {
14: "name": "[parameters('storageAccountList')[copyIndex()].name]",
15: "type": "Microsoft.Storage/storageAccounts",
16: "apiVersion": "2015-05-01-preview",
17: "location": "[parameters('storageAccountList')[copyIndex()].location]",
18: "copy": {
19: "name": "storageAccountLoop",
20: "count": "[length(parameters('storageAccountList'))]"
21: },
22: "properties": {
23: "accountType": "[parameters('storageAccountList')[copyIndex()].storageAccountType]"
24: }
25: }
26: ],
27: "outputs": {
28: "stgobject1": {
29: "type": "object",
30: "value": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountList')[0].name),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0])]"
31: },
32: "stgobject2": {
33: "type": "object",
34: "value": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountList')[1].name),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0])]"
35: },
36: "stgobject3": {
37: "type": "object",
38: "value": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountList')[2].name),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0])]"
39: }
40: }
41: }
Parameter Files
You created one template which is parameterized. After the template has been tested you can use different parameter files with the same template to provision resources in different environments.
Dev Parameters File
This parameter file defines a storage account list. It defines name, location and storageAccountType properties for each storage account. It can be used to provision storage account in a dev environment.
1: {
2: "storageAccountList": {
3: "value": [
4: { "name": "rajappdev", "location": "Central US", "storageAccountType": "Standard_LRS" },
5: { "name": "rajdbdev", "location": "Central US", "storageAccountType": "Standard_GRS" },
6: { "name": "rajwebdev", "location": "Central US", "storageAccountType": "Standard_ZRS" },
7: { "name": "rajarchdev", "location": "West US", "storageAccountType": "Premium_LRS" }
8: ]
9: }
10: }
Test Parameters File
This parameter file defines a storage account list. It defines name, location and storageAccountType properties for each storage account. It can be used to provision storage account in a test environment.
1: {
2: "storageAccountList": {
3: "value": [
4: { "name": "rajapptest", "location": "Central US", "storageAccountType": "Standard_LRS" },
5: { "name": "rajdbtest", "location": "Central US", "storageAccountType": "Standard_GRS" },
6: { "name": "rajwebtest", "location": "Central US", "storageAccountType": "Standard_ZRS" },
7: { "name": "rajarchtest", "location": "West US", "storageAccountType": "Premium_LRS" }
8: ]
9: }
10: }
Prod Parameters File
This parameter file defines a storage account list. It defines name, location and storageAccountType properties for each storage account. It can be used to provision storage account in a prod environment.
1: {
2: "storageAccountList": {
3: "value": [
4: { "name": "rajappprod", "location": "Central US", "storageAccountType": "Standard_LRS" },
5: { "name": "rajdbprod", "location": "Central US", "storageAccountType": "Standard_GRS" },
6: { "name": "rajwebprod", "location": "Central US", "storageAccountType": "Standard_ZRS" },
7: { "name": "rajarchprod", "location": "West US", "storageAccountType": "Premium_LRS" }
8: ]
9: }
10: }
Ship It (Make it so Number 2)
Now that our templates are ready we are ready to execute them to provision resources.
Here is a short script that is used to provision resources.
Lines 16-30: Create the resource group if it does not already exist
Line 40: Uses the template and a parameters file to provision storage accounts.
1: Param
2: (
3: [Parameter (Mandatory = $true)]
4: [string] $ResourceGroupName,
5:
6: [Parameter (Mandatory = $true)]
7: [string] $Location,
8:
9: [Parameter (Mandatory = $true)]
10: [string] $ParametersFile
11: )
12:
13: #publish version of the the powershell cmdlets we are using
14: (Get-Module Azure).Version
15:
16: $rg = Get-AzureResourceGroup -Name $ResourceGroupName -ErrorAction SilentlyContinue
17:
18: if (!$rg)
19: {
20: # Create a new storage account
21: Write-Output "";
22: Write-Output "Creating Resource Group [$ResourceGroupName] in location [$Location]"
23:
24:
25: New-AzureResourceGroup -Name "$ResourceGroupName" -Force -Location $Location -ErrorVariable errorVariable -ErrorAction SilentlyContinue | Out-Null
26:
27: if (!($?))
28: {
29: throw "Cannot create new Resource Group [$ResourceGroupName] in region [$Location]. Error Detail: $errorVariable"
30: }
31:
32: Write-Output "Resource Group [$ResourceGroupName] was created"
33:
34: }
35: else
36: {
37: Write-Output "Resource Group [$ResourceGroupName] already exists"
38: }
39:
40: New-AzureResourceGroupDeployment -Name stgdeployment -ResourceGroupName $ResourceGroupName -TemplateFile .\createstorageaccts.json -TemplateParameterFile $ParametersFile
Trust but Verify
Line 1: It calls deploy.ps1 script and passes in resource group name, location and parameters file.
Line 54-92: Show the details of the storage accounts that were provisioned.
1: PS C:\git\ArmExamples\CreateStorageAccounts> .\deploy.ps1 -ResourceGroupName ARM-Dev -Location "West US" -ParametersFile
2: .\storageaccts-dev.json
3:
4: Creating Resource Group [ARM-Dev] in location [West US]
5: VERBOSE: 3:54:11 PM - Created resource group 'ARM-Dev' in location 'westus'
6: Resource Group [ARM-Dev] was created
7: VERBOSE: 3:54:13 PM - Template is valid.
8: VERBOSE: 3:54:14 PM - Create template deployment 'stgdeployment'.
9: VERBOSE: 3:54:22 PM - Resource Microsoft.Storage/storageAccounts 'rajarchdev' provisioning status is running
10: VERBOSE: 3:54:22 PM - Resource Microsoft.Storage/storageAccounts 'rajwebdev' provisioning status is running
11: VERBOSE: 3:54:24 PM - Resource Microsoft.Storage/storageAccounts 'rajappdev' provisioning status is running
12: VERBOSE: 3:54:24 PM - Resource Microsoft.Storage/storageAccounts 'rajdbdev' provisioning status is running
13: VERBOSE: 4:04:03 PM - Resource Microsoft.Storage/storageAccounts 'rajappdev' provisioning status is succeeded
14: VERBOSE: 4:04:03 PM - Resource Microsoft.Storage/storageAccounts 'rajarchdev' provisioning status is succeeded
15: VERBOSE: 4:04:05 PM - Resource Microsoft.Storage/storageAccounts 'rajappdev' provisioning status is succeeded
16: VERBOSE: 4:04:13 PM - Resource Microsoft.Storage/storageAccounts 'rajdbdev' provisioning status is succeeded
17: VERBOSE: 4:04:13 PM - Resource Microsoft.Storage/storageAccounts 'rajwebdev' provisioning status is succeeded
18: VERBOSE: 4:04:13 PM - Resource Microsoft.Storage/storageAccounts 'rajdbdev' provisioning status is succeeded
19: VERBOSE: 4:04:13 PM - Resource Microsoft.Storage/storageAccounts 'rajwebdev' provisioning status is succeeded
20:
21:
22: DeploymentName : stgdeployment
23: ResourceGroupName : ARM-Dev
24: ProvisioningState : Succeeded
25: Timestamp : 8/14/2015 9:04:25 PM
26: Mode : Incremental
27: TemplateLink :
28: Parameters :
29: Name Type Value
30: =============== ========================= ==========
31: storageAccountList Array [
32: {
33: "name": "rajappdev",
34: "location": "Central US",
35: "storageAccountType": "Standard_LRS"
36: },
37: {
38: "name": "rajdbdev",
39: "location": "Central US",
40: "storageAccountType": "Standard_GRS"
41: },
42: {
43: "name": "rajwebdev",
44: "location": "Central US",
45: "storageAccountType": "Standard_ZRS"
46: },
47: {
48: "name": "rajarchdev",
49: "location": "West US",
50: "storageAccountType": "Premium_LRS"
51: }
52: ]
53:
54: Outputs :
55: Name Type Value
56: =============== ========================= ==========
57: stgobject1 Object {
58: "provisioningState": "Succeeded",
59: "accountType": "Standard_LRS",
60: "primaryEndpoints": {
61: "blob": "https://rajappdev.blob.core.windows.net/",
62: "queue": "https://rajappdev.queue.core.windows.net/",
63: "table": "https://rajappdev.table.core.windows.net/"
64: },
65: "primaryLocation": "Central US",
66: "statusOfPrimary": "Available",
67: "creationTime": "2015-08-14T20:54:32.9062387Z"
68: }
69: stgobject2 Object {
70: "provisioningState": "Succeeded",
71: "accountType": "Standard_GRS",
72: "primaryEndpoints": {
73: "blob": "https://rajdbdev.blob.core.windows.net/",
74: "queue": "https://rajdbdev.queue.core.windows.net/",
75: "table": "https://rajdbdev.table.core.windows.net/"
76: },
77: "primaryLocation": "Central US",
78: "statusOfPrimary": "Available",
79: "secondaryLocation": "East US 2",
80: "statusOfSecondary": "Available",
81: "creationTime": "2015-08-14T20:54:32.0468124Z"
82: }
83: stgobject3 Object {
84: "provisioningState": "Succeeded",
85: "accountType": "Standard_ZRS",
86: "primaryEndpoints": {
87: "blob": "https://rajwebdev.blob.core.windows.net/"
88: },
89: "primaryLocation": "Central US",
90: "statusOfPrimary": "Available",
91: "creationTime": "2015-08-14T20:54:29.9062389Z"
92: }
Cleanup
To remove all the resources you provisioned you can use the Remove-AzureResoureGroup cmdlet as shown below
Remove-AzureResourceGroup -Name ARM-Dev
Doggy Bag Please
You can access all the samples from my GitHub Repository here: https://github.com/rajinders/ArmExamples
Summary
I hope you found this sample helpful. I will post more samples on a regular basis.