Skip to main content
Version: 2411

Task 05 — Storage Configuration

DOCUMENT CATEGORY: Implementation Guide SCOPE: Azure Local Cluster — Post-Deployment Storage PURPOSE: Create Storage Spaces Direct (S2D) Cluster Shared Volumes (CSVs) on the cluster MASTER REFERENCE: Azure Local Storage Spaces Direct and register the corresponding storage paths in Azure so they appear as placement targets for virtual machines deployed through Azure Local.

Status: Active

Section 1 — Volume Sizing & YAML Verification​

This step should already be complete

Volume sizing and the cluster_shared_volumes YAML block should have been completed during the Discovery & Planning phase. If those values are not in your variables.yml, stop here and complete sizing before proceeding — all scripts in Sections 2 and 3 read exclusively from the YAML. Nothing is hardcoded in the scripts.

If sizing was not completed, use the S2D Capacity Calculator:

tools/planning/S2D_Capacity_Calculator_6.xlsx

The calculator requires:

  • Number of cluster nodes
  • Number and size of capacity drives per node
  • Resiliency type (Two-way Mirror / Three-way Mirror)
  • Target usable capacity per volume

Once you have the outputs, populate the following keys in your variables.yml before running any scripts in this task:

YAML PathExample (IIC)Description
cluster_shared_volumes.enabledtrueEnable CSV creation
cluster_shared_volumes.volumes[].volume_namecsv-iic01-clus01-m2-vmstore-prd-01CSV friendly name → becomes C:\ClusterStorage\<name>
cluster_shared_volumes.volumes[].size_gb2000Volume size in GB
cluster_shared_volumes.volumes[].filesystemReFSFilesystem — ReFS strongly recommended
cluster_shared_volumes.volumes[].resiliencyMirrorS2D resiliency class
cluster_shared_volumes.volumes[].pathC:\ClusterStorage\csv-...-01Full local mount path
cluster_shared_volumes.storage_paths.<key>.namesp-iic01-clus01-m2-vmstore-prd-01Azure storage path resource name
cluster_shared_volumes.storage_paths.<key>.pathC:\ClusterStorage\csv-...-01\VMsSubdirectory inside CSV for VM placement
compute.azure_local.cluster_nameiic-clus01Cluster name (storage pool is S2D on <cluster_name>)
azure_platform.resource_groups.cluster.namerg-iic01-azl-eus-01Resource group for storage path resources
compute.azure_local.custom_locationcl-iic01Azure custom location for storage path registration
Volume naming convention

Convention: csv-<site-prefix>-<cluster-id>-<resiliency-short>-<purpose>-<seq>

  • m2 = two-way mirror, m3 = three-way mirror
  • Storage path names mirror this with sp- prefix
  • Azure resource names must be lowercase, hyphens only (no underscores)

If your YAML is not yet populated, use the interactive helper script Set-StorageVolumesConfig.ps1 from the toolkit. It walks through each value from the calculator output and writes the cluster_shared_volumes block directly into your variables.yml. Skip if the YAML is already populated.

Script location:

scripts/deploy/04-cluster-deployment/phase-06-post-deployment/
task-05-storage-configuration/powershell/Set-StorageVolumesConfig.ps1

What it does:

  • Reads your existing variables.yml and pre-fills any values already present
  • Prompts for volume count, name, size (GB from the Calculator usable capacity output), resiliency (Mirror / Parity / MirrorAcceleratedParity), and filesystem (ReFS / NTFS)
  • Auto-derives storage path names (sp- prefix) and paths (C:\ClusterStorage\<vol>\VMs) from each volume name
  • Prompts for CSV cache settings (enabled, per-node RAM size in MB)
  • Writes the completed cluster_shared_volumes block back into the YAML file

Prerequisites: powershell-yaml module (Install-Module powershell-yaml -Scope CurrentUser)

Run from the toolkit repo root:

Run from the toolkit repo root
.\scripts\deploy\04-cluster-deployment\phase-06-post-deployment\task-05-storage-configuration\powershell\Set-StorageVolumesConfig.ps1

# Specify a config path explicitly if needed:
.\scripts\...\Set-StorageVolumesConfig.ps1 -ConfigPath configs\infrastructure-iic01.yml
Review before proceeding

Open variables.yml after the script completes and verify the cluster_shared_volumes block before running any Section 2 scripts. The script does not validate volume names against the naming convention — confirm they follow csv-<cluster>-<res>-<purpose>-<seq>.


Section 2 — Create CSV Volumes​

When to use: Ad-hoc volume creation on a single cluster, GUI preference, or verifying existing volume state.

Prerequisites: Windows Admin Center connected to the cluster. The S2D storage pool must be Online and Healthy (confirmed automatically during cluster deployment).

Steps:

  1. Open Windows Admin Center and connect to the cluster (e.g. iic-clus01)
  2. In the left navigation, select Storage → Volumes
  3. Click + Create
  4. Fill in the volume details:
  • Name: csv-iic01-clus01-m2-vmstore-prd-01
  • Resiliency: Two-way mirror (or Three-way mirror for 5+ node clusters)
  • Size: 2000 GB
  • Filesystem: ReFS
  • Provisioning: Thin
  1. Click Create and wait for provisioning to complete
  2. Repeat for each additional volume defined in cluster_shared_volumes.volumes[]

After creation, confirm each volume shows Status: OK in the Volumes list before proceeding to Section 3.


Section 3 — Register Storage Paths in Azure​

Storage paths are Azure resources that tell Azure Local where to place VM disks on the cluster storage. Each storage path maps an Azure resource name to a local path inside a CSV.

Registration uses the az stack-hci-vm CLI extension and must be run from a machine with az CLI access to the subscription.

When to use: Ad-hoc registration, verifying existing path state, or re-registering after a storage change.

Steps:

  1. Open the Azure portal
  2. Navigate to Azure Local → select your cluster (iic-clus01)
  3. In the left menu under Settings, select Storage paths
  4. Click + Add storage path and fill in:
  • Name: sp-iic01-clus01-m2-vmstore-prd-01
  • Custom location: cl-iic01 (auto-populated if only one exists)
  • Path: C:\ClusterStorage\csv-iic01-clus01-m2-vmstore-prd-01\VMs
  1. Click Add and wait for ProvisioningState: Succeeded
  2. Repeat for each entry in cluster_shared_volumes.storage_paths
CLI is faster for multiple paths

Use the orchestrated or standalone tab to register all paths in one run rather than clicking through the portal for each one.


Validation​

Run all checks from the management server (or a cluster node for pool/volume checks).

1 — Verify storage pool health
# Run on a cluster node or via PS Remoting to the cluster
Invoke-Command -ComputerName "iic-clus01" -ScriptBlock {
Get-StoragePool | Where-Object FriendlyName -like "S2D*" |
Select-Object FriendlyName, HealthStatus, OperationalStatus,
@{N='AllocatedTB'; E={[math]::Round($_.AllocatedSize/1TB, 2)}},
@{N='FreeTB'; E={[math]::Round(($_.Size - $_.AllocatedSize)/1TB, 2)}}
}
2 — Verify CSV volumes are online
Invoke-Command -ComputerName "iic-clus01" -ScriptBlock {
Get-ClusterSharedVolume | Select-Object Name, State,
@{N='Path'; E={ $_.SharedVolumeInfo.FriendlyVolumeName }}
}
3 — Verify virtual disk health
Invoke-Command -ComputerName "iic-clus01" -ScriptBlock {
Get-VirtualDisk | Select-Object FriendlyName, HealthStatus, OperationalStatus,
@{N='SizeGB'; E={[math]::Round($_.Size/1GB, 0)}}
}
4 — Verify Azure storage paths registered
az stack-hci-vm storagepath list `
--resource-group "rg-iic01-azl-eus-01" `
--query "[].{name:name, path:extendedLocation, state:provisioningState}" `
-o table

Expected results:

CheckExpected
Storage pool HealthStatusHealthy
Storage pool OperationalStatusOK
Get-ClusterSharedVolume StateOnline for all volumes
Get-VirtualDisk HealthStatusHealthy for all virtual disks
storagepath list provisioningStateSucceeded for all paths

Variables from variables.yml​

VariableConfig PathExample
Storage Pool Namecluster.storage.pool_nameS2D on azlocal-cluster
Volume Namecluster.storage.volumes[].nameVolume01
Volume Sizecluster.storage.volumes[].size_gb1024
Resiliency Typecluster.storage.volumes[].resiliencyMirror

Troubleshooting​

IssueCauseResolution
Storage pool HealthStatus shows DegradedOne or more physical disks are unhealthy or missingCheck disk health: Get-PhysicalDisk | Where-Object HealthStatus -ne Healthy; replace failed disks and initiate repair: Repair-VirtualDisk
CSV volume shows Offline or RedirectedNode owning the volume is offline or network partitionVerify cluster node status: Get-ClusterNode; move CSV ownership: Move-ClusterSharedVolume -Name <csv> -Node <healthy-node>
Storage path registration fails in AzureArc resource bridge unhealthy or missing permissionsVerify bridge: az arcappliance show; ensure the SPN has Contributor on the resource group


Alternatives​

The procedures in this task use the scripted methods shown in the tabs above. Additional deployment methods including Azure CLI and Bash scripts are available in the azurelocal-toolkit repository under scripts/deploy/.

MethodDescription
Azure CLIPowerShell-based Azure CLI scripts for Azure resource operations
BashLinux/macOS compatible shell scripts for pipeline environments
PreviousUpNext
Task 04: SSH ConnectivityPhase 06 IndexTask 06: Image Downloads

Version Control​

VersionDateAuthorChanges
1.0.02025-03-25Azure Local CloudInitial release