Deploying a switchless 3 Node Cluster using ARM Templates
- alynpeden
- Jun 9
- 4 min read
There are many different ways you can deploy Azure Local and each comes with its own unique considerations. Recently I was updating our 3 Node cluster from a Switched Storage configuration to a Switchless one and noticed that this cannot be done natively within the Azure deployment GUI. This process was relevant for version 2503 which I used for this.
I would recommend using ARM if you are going to be deploying multiple clusters however when you are only just deploying one it can be a bit of a pain especially if you have never deployed a cluster before. In this post I will walk through the setup of a 3 node switchless cluster.
This post assumes that you have installed Azure Local on your Nodes and they are ready for cluster creation and you have also done the AD prep step. You can look at my previous post about Installing Azure Local and connecting to ARC here
Pay attention to the diagram below and ensure your nodes RDMA NICs are set up as per below.

Below is an example of my own nodes and the NIC names, its really important you get this correct the 1st time to avoid deployment issues.

1st step is getting the object ID from the Microsoft.AzureStackHCI resource provider. You can get this by going to EntraID and searching for the Resource Provider.
Copy the ObjectID.

Create a template deployment in Azure. You can use the Azure search bar as shown below.

Use a Quickstart template and search for quickstarts/microsoft.azurestackhci/create-cluster-3Nodes-Switchless-SingleLink and select template .

This will now take you to the custom deployment, you can fill out manually in the form to populate the Parameters most of which is self explanatory.

The following output is my Parameters with some elements missing however the key area is the network intent ensuring that it matches. I have left my configuration in place so you can review against the diagrams above, this is just meant to be a helpful guide you will need to make sure it matches your own requirements.
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"deploymentMode": {
"value": "Validate"
},
"keyVaultName": {
"value": "<KeyVaultName>"
},
"createNewKeyVault": {
"value": true
},
"softDeleteRetentionDays": {
"value": 30
},
"diagnosticStorageAccountName": {
"value": "<Storage Account Name>"
},
"logsRetentionInDays": {
"value": 30
},
"storageAccountType": {
"value": "<Storage Type i.e Standard_ZRS>"
},
"clusterName": {
"value": "<Cluster Name>"
},
"location": {
"value": "westeurope"
},
"tenantId": {
"value": "<TenantId>"
},
"witnessType": {
"value": "No Witness"
},
"clusterWitnessStorageAccountName": {
"value": "notrequiredforthis"
},
"localAdminUserName": {
"value": "Administrator"
},
"localAdminPassword": {
"value": null
},
"azureStackLCMAdminUsername": {
"value": "azlocalv2"
},
"azureStackLCMAdminPasssword": {
"value": null
},
"hciResourceProviderObjectID": {
"value": "<Object ID you copied Earlier>"
},
"arcNodeResourceIds": {
"value": [ "/subscriptions/<SubscriptionID>/resourceGroups/<RGNAME>/providers/Microsoft.HybridCompute/machines/<NodeName>",
"/subscriptions/<SubscriptionID>/resourceGroups/<RGNAME>/providers/Microsoft.HybridCompute/machines/<NodeName>",
"/subscriptions/<SubscriptionID>/resourceGroups/<RGNAME>/providers/Microsoft.HybridCompute/machines/<NodeName>"
]
},
"domainFqdn": {
"value": "<FQDN>"
},
"namingPrefix": {
"value": "hci"
},
"adouPath": {
"value": "<Distinguished Name of your OU created at perpare ad step i.e OU=,DC=,DC=>"
},
"securityLevel": {
"value": "Customized"
},
"driftControlEnforced": {
"value": true
},
"credentialGuardEnforced": {
"value": true
},
"smbSigningEnforced": {
"value": false
},
"smbClusterEncryption": {
"value": false
},
"bitlockerBootVolume": {
"value": true
},
"bitlockerDataVolumes": {
"value": true
},
"wdacEnforced": {
"value": true
},
"streamingDataClient": {
"value": true
},
"euLocation": {
"value": false
},
"episodicDataUpload": {
"value": true
},
"configurationMode": {
"value": "Express"
},
"subnetMask": {
"value": "255.255.255.0"
},
"defaultGateway": {
"value": "192.168.1.1"
},
"startingIPAddress": {
"value": "192.168.1.100"
},
"endingIPAddress": {
"value": "192.168.1.110"
},
"dnsServers": {
"value": [
"192.168.1.2"
]
},
"useDhcp": {
"value": false
},
"physicalNodesSettings": {
"value": [
{
"name": "ALNodeA",
"ipv4Address": "192.168.1.20"
},
{
"name": "ALNodeB",
"ipv4Address": "192.168.1.21"
},
{
"name": "ALNodeC",
"ipv4Address": "192.168.1.22"
}
]
},
"networkingType": {
"value": "switchlessMultiServerDeployment"
},
"networkingPattern": {
"value": "hyperConverged"
},
"intentList": {
"value": [
{
"name": "Compute_Management",
"trafficType": [
"Management",
"Compute"
],
"adapter": [
"Port5"
],
"overrideVirtualSwitchConfiguration": false,
"virtualSwitchConfigurationOverrides": {
"enableIov": "",
"loadBalancingAlgorithm": ""
},
"overrideQosPolicy": false,
"qosPolicyOverrides": {
"priorityValue8021Action_Cluster": "7",
"priorityValue8021Action_SMB": "3",
"bandwidthPercentage_SMB": "50"
},
"overrideAdapterProperty": false,
"adapterPropertyOverrides": {
"jumboPacket": "9014",
"networkDirect": "Enabled",
"networkDirectTechnology": "RoCEv2"
}
},
{
"name": "Storage",
"trafficType": [
"Storage"
],
"adapter": [
"Port6",
"Port7"
],
"overrideVirtualSwitchConfiguration": false,
"virtualSwitchConfigurationOverrides": {
"enableIov": "",
"loadBalancingAlgorithm": ""
},
"overrideQosPolicy": false,
"qosPolicyOverrides": {
"priorityValue8021Action_Cluster": "7",
"priorityValue8021Action_SMB": "3",
"bandwidthPercentage_SMB": "50"
},
"overrideAdapterProperty": false,
"adapterPropertyOverrides": {
"jumboPacket": "9014",
"networkDirect": "Enabled",
"networkDirectTechnology": "RoCEv2"
}
}
]
},
"storageNetworkList": {
"value": [
{
"name": "StorageNetwork1",
"networkAdapterName": "Port6",
"vlanId": "711",
"storageAdapterIPInfo": [
{
"physicalNode": "ALNodeA",
"ipv4Address": "10.0.1.1",
"subnetMask": "255.255.255.0"
},
{
"physicalNode": "ALNodeB",
"ipv4Address": "10.0.1.2",
"subnetMask": "255.255.255.0"
},
{
"physicalNode": "ALNodeC",
"ipv4Address": "10.0.2.1",
"subnetMask": "255.255.255.0"
}
]
},
{
"name": "StorageNetwork2",
"networkAdapterName": "Port7",
"vlanId": "711",
"storageAdapterIPInfo": [
{
"physicalNode": "ALNodeA",
"ipv4Address": "10.0.2.2",
"subnetMask": "255.255.255.0"
},
{
"physicalNode": "ALNodeB",
"ipv4Address": "10.0.3.1",
"subnetMask": "255.255.255.0"
},
{
"physicalNode": "ALNodeC",
"ipv4Address": "10.0.3.2",
"subnetMask": "255.255.255.0"
}
]
}
]
},
"storageConnectivitySwitchless": {
"value": true
},
"enableStorageAutoIp": {
"value": false
},
"customLocation": {
"value": ""
},
"sbeVersion": {
"value": ""
},
"sbeFamily": {
"value": ""
},
"sbePublisher": {
"value": ""
},
"sbeManifestSource": {
"value": ""
},
"sbeManifestCreationDate": {
"value": ""
},
"partnerProperties": {
"value": []
},
"partnerCredentiallist": {
"value": []
}
}
}
When you are happy you have all the right configuration in place make sure your deployment mode is set to Validate then select Review + Create and begin the validation steps. You may initially get some errors that you need to work through, I got the following errors:
Resource Deployment Error - This was because I had attempted it in the GUI 1st before learning I had to use ARM templates and my RG had already been assigned the Microsoft.AzureStackHCI Resource provider permissions, if this happens just remove the permissions.
Typos - I made a few of these and got ambiguous errors so just pay attention to them and check then check again.
Key Vault Error - I had to manually set permissions on the Key Vault.
Validation should look something like this.

Once Validation has been successful you will need to select "redeploy" and change from "validated" to "deploy" and enter the credentials again.

Then select Review + Create and begin the build process of your cluster. you can monitor the overall process in Azure ARC > Azure Local and select your cluster then within settings > Deployments and it should look like this

From here expect deployment to take a couple of hours. Hope this post has been helpful.
Comentários