Learn how to define and deploy your Azure infrastructure using ARM templates.
Azure Resource Manager (ARM) templates are JSON files that declaratively define the infrastructure and configuration for your Azure solution. You can use templates to deploy resources consistently and repeatedly. An ARM template is a set of JSON files that defines the deployment, including:
This tutorial will guide you through the process of creating and deploying a simple ARM template to set up a virtual machine in Azure.
An ARM template has a structured JSON format. The main sections include:
$schema
: Specifies the API version of the template language.contentVersion
: A version for the template.parameters
: Values you can provide when deploying the template to customize it.variables
: Define values that are used multiple times in the template.resources
: The core of the template, defining the Azure resources to deploy.outputs
: Values returned after the deployment is complete.Here's a basic structure:
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": {}, "variables": {}, "resources": [], "outputs": {} }
Before deploying any resources, you need a resource group to contain them. You can create one using the Azure portal, Azure CLI, or PowerShell.
az group create --name myResourceGroup --location eastus
This command creates a resource group named myResourceGroup
in the eastus
region.
Let's create a simple ARM template that deploys a Storage Account.
Create a file named storageAccountTemplate.json
and add the following content:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"type": "string",
"metadata": {
"description": "Name for the storage account. Must be globally unique."
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for the storage account."
}
},
"skuName": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS",
"Standard_ZRS",
"Premium_LRS",
"Premium_ZRS"
],
"metadata": {
"description": "Specifies the SKU name for the storage account."
}
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2021-09-01",
"name": "[parameters('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('skuName')]"
},
"kind": "StorageV2",
"properties": {}
}
],
"outputs": {
"storageAccountNameOutput": {
"type": "string",
"value": "[reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-09-01').primaryEndpoints.blob]"
}
}
}
Now, deploy the template using the Azure CLI. You'll need to provide a unique name for your storage account.
az deployment group create \
--resource-group myResourceGroup \
--template-file storageAccountTemplate.json \
--parameters storageAccountName=mystorageaccount$(openssl rand -hex 4) \
skuName=Standard_LRS
$(openssl rand -hex 4)
is a simple way to generate a random suffix for the storage account name, making it more likely to be unique.
This command deploys the template to the myResourceGroup
resource group. The output will include the primary blob endpoint of the newly created storage account.
Parameters allow you to provide input values when deploying a template. They make your templates reusable and flexible.
type
: The data type of the parameter (e.g., string
, int
, bool
, array
, object
).defaultValue
: A value provided if no parameter value is specified during deployment.allowedValues
: Restricts the parameter values to a specific list.metadata
: Provides descriptions and display names for parameters.In our example, storageAccountName
, location
, and skuName
are parameters.
Variables are used to define values that are used multiple times within your template. They simplify your template and make it more readable.
For example, you could define a variable for a common network configuration:
"variables": {
"virtualNetworkName": "myVNet",
"subnetName": "mySubnet",
"vmSize": "Standard_DS1_v2"
}
Then, use them in the resources
section:
"resources": [
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2020-11-01",
"name": "[variables('virtualNetworkName')]",
// ... other properties
}
]
Outputs allow you to return values from your deployment. This is useful for retrieving information about the deployed resources, such as connection strings, IP addresses, or resource IDs.
In our template, we output the primary blob endpoint of the storage account:
"outputs": {
"storageAccountNameOutput": {
"type": "string",
"value": "[reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2021-09-01').primaryEndpoints.blob]"
}
}
The reference()
function is used to get information about an existing resource.
dependsOn
property when resources rely on each other. Although ARM often infers dependencies, explicit declaration can prevent issues.az group deployment validate
command to check for syntax errors before deployment.concat()
, uniqueString()
, and listKeys()
to build dynamic resource names and retrieve resource properties.
Congratulations on completing this basic ARM template tutorial! Here are some suggestions for further learning: