After following ARM Template 101 and AZ-104-MS Azure Administrator 101 quick ref
We are ready for some labs, all labs has a template and a parameters file
Remember also the quick starts
https://azure.microsoft.com/en-us/resources/templates/
Any way we will start at 0, many of the parameters may change but we need to look at prices first, since we we deploy and destroy over and over again. The goal is just to learn IAC/ ARM and not spend money….
So lets recap bit and think about this!
If we look back at the free services the cost/ configuration for (is free for 12m) B1s is:
Ubuntu
Basic:
- Resource group boose-rg
- Region West Europe
- Availability options Availability zone
- Availability zone 1
- Image Ubuntu Server 18.04 LTS – Gen1
- Size Standard B1s (1 vcpu, 1 GiB memory)
Disks
- OS disk type Standard HDD 32gib
Azure calculator
Pricing Calculator | Microsoft Azure
Lets look at some prices for virtual machines and storage accounts
Virtual machines
If we select region WE, OS Linux, type Ubuntu, Tier, Disk?
There is an option with TIER and Disk
- Low priority, is the cheapest, you get just unused capacity
- Basic, for development testing (but no LB or auto scale and slow IOPS)
- Standard, default, better CPU/Higher max disk IOPS
The price heavily depends on region and offers available in that region, it is a jungle for now. If we use the above input and check availability in tiers, the SKU (stock keeping unit) instance and disk changes a lot.
Tier
- Basic, development or testing or small scale
- General purpose, Most business workloads, web/mobile apps/enterprise apps
- Memory optimized, High performance db workloads in memory, real time data high per. transaction
So in order to create the “free” BS1 1 vCPU, 1 GB RAM, 4 GB Temp storage we need to set the following
- Region West Europe
- OS Linux
- Type Ubuntu
- Tier Standard
- Instance BS1 1 vCPU, 1 GB RAM, 4 GB Temp storage NOK 0.0974/hour
- VM’s = 1 x 730 (hours running)
- Managed disk
- Tier Standard HDD
- Disk size 1 x S4: 32GiB, NOK 12.463/month
- Storage transaction 100 x NOK 0.0041
Gives the total price of NOK 83.95 monthly cost if it runs for 730 hh.
Gives the total price of NOK 15.21 monthly cost if it runs for 24 hh.
Windows VM
If we swap the OS to Windows but keep the same settings but add:
- OS Windows License included
Gives the total price of NOK 107.64 monthly cost if it runs for 730 hh.
Gives the total price of 15.98 monthly cost if it runs for 24 hh
Storage Account
- Region WE
- Redundancy LRS
- Type Block Blob Storage
- Access Tier Hot
- Performance tier Standard
- Storage Account Type General Purpose V2
- Capacity 250 GB
- […] Default write operations:
- 100000 x NOK 0.438, Per 10,000 operations
- List and create operations 100000 x NOK 0.438, Per 10,000 operations
- Read operations 100000 x NOK 0.035, Per 10,000 operations
- All other operations 1 x NOK 0.035, Per 10,000 operations
- Data retrieval + write = 1000gb NOK 0.000 per GB
Gives the total price of NOK 48.87 monthly cost
Ok now we are ready
1 Create and deploy your first ARM template
Install Azure Power shell module (as admin if all users need it)
As built, it takes some minutes, when it is done, type New-Az something to see if the cmd appear.
To start working with Azure PowerShell/Azure CLI, sign in with your Azure credentials.
Connect-AzAccount
If you have multiple Azure subscriptions, select the subscription you want to use:
Set-AzContext [SubscriptionID/SubscriptionName]
Your account, subscription name , tenant id and environment will be listed
Now lets create a rg, deploy template and verify it, then clean up
All code is stored here
https://github.com/spawnmarvel/powershell-cmd-bash/tree/master/arm
# New rg
New-AzResourceGroup -Name boose-rg -Location "West Europe"
# Deploy template
$templateFile = "C:\giti\powershell-cmd-bash\arm\beginners_template\azuredeploy.json"
New-AzResourceGroupDeployment -Name blanktemplate -ResourceGroupName boose-rg -TemplateFile $templateFile
# clean it
Get-AzResourceGroup -Name ‘boose*’ | Remove-AzResourceGroup -Force -AsJob
Check if succeeded, default is incremental
Verify in portal, in the rg check deployments to the right and press it, to get the history.
Now we are removing it, this can take some time….
2 Add a resource to your ARM template
We updated the json with the following to create a storage account, then we deployed the script with a new rg and a new template again
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "boosestorage",
"location": "westeurope",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2",
"properties": {
"supportsHttpsTrafficOnly": true
}
}
]
Verify it in portal
Files for now
3 Add parameters to your ARM template
So lets add a parameters and make the template reusable and use not the hard coded boosestorage name
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "boosestorage",
"location": "westeurope",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2",
"properties": {
"supportsHttpsTrafficOnly": true
}
}
]
}
With parameter
[...]
"contentVersion": "1.0.0.0",
"parameters": {
"storageName": {
"type": "string",
"minLength": 3,
"maxLength": 24
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "[parameters('storageName')]",
[...]
Lets deploy it (“If the resource already exists and no change is detected in the properties, no action is taken. If the resource already exists and a property has changed, the resource is updated. If the resource doesn’t exist, it’s created.“)
And the the storage account
“Parameters enable you to customize the deployment by providing values that are tailored for a particular environment“
The template always deploys a Standard_LRS storage account, you could use a parameter and a default value for adding different SKU’s.
[...]
"storageSKU": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS",
"Standard_ZRS",
"Premium_LRS",
"Premium_ZRS",
"Standard_GZRS",
"Standard_RAGZRS"
]
}
},
[..]
"sku": {
"name": "[parameters('storageSKU')]"
},
If we now run Test-AzResourceGroupDeployment, we can test with a storage name and without and also with a change in the storage account to one of the allowed values for SKU.
Here we see that the name provide is taken, so we must supply a new one and test again, until it works.
Ok lets check it before we deploy it, it is Locally-redundant storage (LRS) now. Lets redeploy and change the SKU.
$resourceGr = "boose-rg"
# New rg
New-AzResourceGroup -Name $resourceGr -Location "West Europe"
# Deploy template
$templateFile = "C:\giti\powershell-cmd-bash\arm\beginners_template\azuredeploy.json"
New-AzResourceGroupDeployment -Name addName -ResourceGroupName $resourceGr -TemplateFile $templateFile -storageName "boosestorage1" -storageSKU Standard_GRS
It is now GRS
lets swap it back with a redeploy and yea!
If you add the ARM tools on VSC you get a good tool, with highlights and more
4 Add template functions
Dynamically construct values, system-provided func and USD func.
From the previous JSON file the locations was hard coded.
If we were to change this we could create parameter for the location, but there is also a another option.
Now we will use a GET func of the location of the rg
"location": "westeurope" # this is not good for flexibility.
[...] # to this->
"location": {
"type": "string",
"defaultValue":"[resourceGroup().location]"
}
[...]
"location": "[parameters('location')]",
Now we will use the location of of the rg to deploy the storage.
We now have boose-rg1 in east us, lets deploy
$resourceGr1 = "boose-rg1"
# add template functions
New-AzResourceGroupDeployment -Name DeployToRgZone2 -ResourceGroupName $resourceGr1 -TemplateFile $templateFile -storageName "boosestorage2" -storageSKU Standard_LRS
Lets check the deploy and then move it back to the main rg
And the storage is now in the rg location
And move it back to boose-rg in west europe
# https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/move-resource-group-and-subscription
$resourceNew = "boose-rg"
$resourceOld = "boose-rg1"
$storageToMove = Get-AzResource -ResourceGroupName $resourceOld -ResourceName "boosestorage2"
Write-Host $storageToMove.ResourceName+ " " + $storageToMove.Sku.Name
# our plan
$plan = Get-AzResource -ResourceGroupName $resourceOld -ResourceName "boosestorage2"
# execute the move
$result = Move-AzResource -DestinationResourceGroupName $resourceNew -ResourceId $plan.ResourceId
Write-Host $result
Move yes
And we are done with the moving
5 Add variables
Enabling you to write an expression once and reuse it throughout the template
Tired of guessing a unique name for the storage account name?
# New template
"parameters": {
"storagePrefix": {
"type": "string",
"minLength": 3,
"maxLength": 11
},
"storageSKU": {
[...]
"variables": {
"uniqueStorageName": "[concat(parameters('storagePrefix'), uniqueString(resourceGroup().id))]"
},
"apiVersion": "2019-04-01",
"name": "[variables('uniqueStorageName')]",
# Vs old
"parameters": {
"storageName": {
"type": "string",
"minLength": 3,
"maxLength": 30
},
"storageSKU": {
[...]
"apiVersion": "2019-04-01",
"name": "[parameters('storageName')]",
The uniqueString function creates a 13 character hash value, return val is built with the parameters.
Here we use the resource group ID as the input for the hash value.
So we can deploy to a different rg and get a unique name, if we deploy to the same rg, we get the same name.
Our storage name is now set to a variable and not a parameter.
Verbose switch to get information about the resources or Debug to get more information.
Here we are using the debug (we can continue one, all, H (stop) , S (pause pip, type exit to resume it, ? (is what we just said)
New-AzResourceGroupDeployment -Name addnameVariable -ResourceGroupName $resourceGr -TemplateFile $templateFile -storagePrefix "boose" -storageSKU Standard_LRS -Debug
Some flashes on progress, then done
Lets check it, and there it is.
Lets clean it and test with Verbose (we just get more information and the deploy continues)
Lets remove just the resource and not the rg, check for the cmd in language reference
Side note, typical properties for a resource is:
Get what we have now
6 Add outputs
We have just deployed some storage account without returning any information.
Lets do return some output.
Important:
Return value is obj (JSON), and the reference func to get runtime state of the storage account.
Get runtime, pass the name/ID of resource, here it is the same var as for creating the name of the stor.acc.
It returns the endpoint
Add the , “output” section to the template
[...]
"kind": "StorageV2",
"properties": {
"supportsHttpsTrafficOnly": true
}
}
],
"outputs": {
"storageEndpoint": {
"type": "object",
"value": "[reference(variables('uniqueStorageName')).primaryEndpoints]"
}
}
}
Now run the same deploy cmd as the last time, and you get a similar output
Outputs :
Name Type Value
================= ========================= ==========
storageEndpoint Object {
"dfs": "https://boosec4ybsmchbhppi.dfs.core.windows.net/",
"web": "https://boosec4ybsmchbhppi.z6.web.core.windows.net/",
"blob": "https://boosec4ybsmchbhppi.blob.core.windows.net/",
"queue": "https://boosec4ybsmchbhppi.queue.core.windows.net/",
"table": "https://boosec4ybsmchbhppi.table.core.windows.net/",
"file": "https://boosec4ybsmchbhppi.file.core.windows.net/"
}
7 Use exported templates
Here the focus is to export templates and customize it.
The template we ended with is ok for stor.acc, but we could add or in the future you need more resources in the template.
Here is how to export and get the JSON.
Lets follow the tutorial and create:
In App Service (Web Apps, API Apps, or Mobile Apps), an app always runs in an App Service plan.
Azure Functions also has the option of running in an App Service plan. An App Service plan defines a set of compute resources for a web app to run. These compute resources are analogous to the server farm in conventional web hosting.
ref
https://docs.microsoft.com/en-us/azure/app-service/overview-hosting-plans
After it is created go the resource and export template. You can use this function to quickly export the base of a template, the parameters is just to change. Here the SKU has five parameters, all those are not necessary. Name is sufficient, but the planing is key to know what you want.
Now you have most of the JSON, so it is time to change it.
The changes we will do is:
Name to match our, use location parameter for app and remove some props.
Just for the fun of it we will the type in all, learning is doing.
This is a valid empty template, we will start with that and do the hard work…yea.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters":{},
"variables":{},
"resources": [],
"outputs":{}
}
Using the extension it it giving hints to you, when you are getting into the syntax..
Parameters not used yet.
Ok, when do run first with -WhatIf, then -Debug to check if the template is valid before typing 5*yes to deply
So now we deployed a stor.acc (with prefix) and App service plan.
For : 8 Use quick start template, 9 Add tags, 10 Use parameter file go to ARM Lab 103