3. Deploy Azure Local with LocalBox
3. Deploy Azure Local: separate production from LocalBox
Read the media stop condition before creating resources. The recorded lab encountered HTTP 409 while obtaining the prepared 2608 VHDX. Its later ISO-to-Generation-2 recovery was custom work, not an unmodified, repeatable LocalBox deployment. A public Git commit does not guarantee that publisher-hosted images remain downloadable.
Path A — physical deployment, a separate scope
- Select validated hardware and a supported network reference pattern with your OEM. Complete the deployment checklist: firmware, drives, cabling, outbound endpoints, permissions, DNS, time, and reserved IPs.
- For the AD-based path, prepare the dedicated organizational unit and deployment account using Microsoft's AD preparation procedure. Keep identity and recovery dependencies independent of the new cluster.
- Use the OEM-supported image where supplied. Otherwise download the correct release through Azure Local's portal software-download workflow, personally review its license/privacy terms, and install the OS on each machine. Configure management networking, DNS, and time; follow the release-specific update restrictions rather than applying arbitrary Windows updates.
- Assign the documented deployment roles and register each machine with Azure Arc through the appropriate gateway or direct-connect workflow.
- In Azure Local → Create instance, select the machines and identity provider, install required extensions, and validate the machines. Supply Key Vault, network intents, infrastructure IP pool, deployment credentials, storage, and security settings. Complete validation before deployment; monitor instance deployment steps to completion.
- Verify node, storage, bridge, and custom-location health. Then design workload protection and maintenance. Do not run LocalBox's nested-host or storage-bootstrap scripts on physical production machines.
Path B — pinned LocalBox learning deployment
The following commands are instructions for an authorized reader, not deployments performed while writing this guide. Use a dedicated disposable resource group and PowerShell 7. Install approved Git, Azure CLI, Bicep CLI, and Az PowerShell first. Do not record credential-entry sessions or publish raw terminal output.
-
Authenticate and check regional capacity
Enter your own identifiers at runtime. Verify policy and role-assignment permissions with your administrator; Contributor alone cannot grant all roles used by the template. Confirm at least 32 available regional and ESv6-family vCPUs, SKU availability, and nested-virtualization capability. Quota is not a capacity reservation.
$ErrorActionPreference = 'Stop' $subscription = Read-Host 'Subscription ID' $tenant = Read-Host 'Tenant ID' $rg = Read-Host 'Dedicated lab resource-group name' $location = 'australiaeast' az version az bicep version az login --tenant $tenant --output none if ($LASTEXITCODE -ne 0) { throw 'Azure CLI login failed.' } az account set --subscription $subscription if ($LASTEXITCODE -ne 0) { throw 'Subscription selection failed.' } Connect-AzAccount -Tenant $tenant -Subscription $subscription | Out-Null Set-AzContext -Tenant $tenant -Subscription $subscription | Out-Null az vm list-usage --location $location --output table az vm list-skus --location $location --size Standard_E32s_v6 ` --all --query "[].{Name:name,Restrictions:restrictions}" --output json -
Register providers and resolve the provider identity
These registration commands change subscription state. Run only with approval, and stop on failures. The required
spnProviderIdis the existing Microsoft.AzureStackHCI resource provider's directory object ID, not a new application secret. If lookup is denied or ambiguous, obtain the correct object ID from the tenant administrator; do not select an arbitrary match.$providers = @( 'Microsoft.HybridCompute','Microsoft.GuestConfiguration', 'Microsoft.HybridConnectivity','Microsoft.AzureStackHCI', 'Microsoft.Kubernetes','Microsoft.KubernetesConfiguration', 'Microsoft.ExtendedLocation','Microsoft.ResourceConnector', 'Microsoft.HybridContainerService','Microsoft.Attestation', 'Microsoft.Storage','Microsoft.Insights','Microsoft.KeyVault', 'Microsoft.Compute','Microsoft.Network','Microsoft.OperationalInsights', 'Microsoft.OperationsManagement','Microsoft.Authorization' ) foreach ($provider in $providers) { az provider register --namespace $provider --wait --output none if ($LASTEXITCODE -ne 0) { throw "Provider registration failed: $provider" } } $providerIds = @(az ad sp list ` --display-name 'Microsoft.AzureStackHCI Resource Provider' ` --query "[].id" --output tsv) if ($LASTEXITCODE -ne 0 -or $providerIds.Count -ne 1) { throw 'Ask the tenant administrator to resolve the HCI provider object ID.' } $providerId = $providerIds[0] -
Clone the exact public source and preflight image access
Run from a new working directory. At this revision the real entry point is
azure_jumpstart_localbox\bicep\main.bicep. Do not blindly follow a newer documentation example or reuse its example password. Pin both the checkout and the runtime artifact reference.$revision = 'e2c114eed98d18105dcf3a718bef965d5112781b' git clone https://github.com/microsoft/azure_arc.git .\azure_arc if ($LASTEXITCODE -ne 0) { throw 'Clone failed.' } git -C .\azure_arc checkout --detach $revision if ($LASTEXITCODE -ne 0) { throw 'Checkout failed.' } $actual = git -C .\azure_arc rev-parse HEAD if ($actual -ne $revision) { throw 'Unexpected source revision.' } $base = '.\azure_arc\azure_jumpstart_localbox' $script = "$base\artifacts\PowerShell\New-LocalBoxCluster.ps1" $media = @(Select-String -Path $script -Pattern '^\s*azcopy cp ' | ForEach-Object { [regex]::Match($_.Line, 'https://[^''"\s]+').Value }) if ($media.Count -eq 0) { throw 'Review upstream media acquisition manually.' } foreach ($uri in $media) { try { Invoke-WebRequest -Uri $uri -Method Head -TimeoutSec 30 | Select-Object StatusCode } catch { throw 'Publisher media preflight failed. Stop; follow the media boundary below.' } }Media boundary: on 409, denied public access, missing media, or a checksum mismatch, stop. Do not bypass access controls, substitute an unofficial image, or rerun storage initialization. Use the official ISO download and manual OS installation guidance only after the user approves applicable terms. Preparing a compatible nested Generation 2 image and recovery plan is separate engineering, not a guaranteed fallback command here. A newer ISO may also require a different deployment workflow.
-
Build, validate, preview, then create the foundation
Pass the password as a SecureString in memory, not a CLI argument or plaintext parameter file. Choose a unique disposable local administrator credential meeting the upstream restrictions; official guidance calls for at least 14 characters and complexity, and LocalBox warns against the dollar symbol. The example disables autologon, automatic cluster deployment, and automatic upgrades so each stage can be inspected.
$admin = Get-Credential -Message 'Unique disposable LocalBox local administrator' if ($admin.Password.Length -lt 14) { throw 'Use at least 14 characters.' } $parameters = @{ tenantId = $tenant spnProviderId = $providerId windowsAdminUsername = $admin.UserName windowsAdminPassword = $admin.Password githubAccount = 'microsoft' githubBranch = $revision location = $location azureLocalInstanceLocation = 'australiaeast' vmSize = 'Standard_E32s_v6' deployBastion = $true vmAutologon = $false autoDeployClusterResource = $false autoUpgradeClusterResource = $false governResourceTags = $false enableAzureSpotPricing = $false } az bicep build --file "$base\bicep\main.bicep" ` --outfile .\localbox.compiled.json if ($LASTEXITCODE -ne 0) { throw 'Bicep build failed.' } New-AzResourceGroup -Name $rg -Location $location | Out-Null $deployment = @{ ResourceGroupName = $rg TemplateFile = (Resolve-Path .\localbox.compiled.json).Path TemplateParameterObject = $parameters Mode = 'Incremental' ErrorAction = 'Stop' } $errors = @(Test-AzResourceGroupDeployment @deployment) if ($errors.Count -gt 0) { $errors; throw 'Resolve validation errors first.' } New-AzResourceGroupDeployment @deployment -Name 'localbox-plan' -WhatIf # STOP and review the proposed resources, access, and cost before continuing. New-AzResourceGroupDeployment @deployment -Name 'localbox-foundation' | Select-Object DeploymentName, ProvisioningStateThe public template supports the parameters above.
governResourceTags=falseavoids tenant-specific governance-bypass tags; follow your organization's actual policy. The compiled JSON contains template definitions, not the supplied password. However, upstream guest automation still materializes credentials in guest configuration/parameter artifacts, and base64 is not encryption. This is a disposable lab, not a hardened secret-management pattern. Restrict access, never commit generated guest files or log bundles, and rotate/discard credentials after use. Pinning the repository does not pin every external installer or image. -
Connect through Bastion and let guest setup finish once
In the portal open LocalBox-Client → Connect → Bastion and enter the credential privately. No public RDP opening is required. The first interactive sign-in triggers the upstream logon automation: outer storage, nested management and nodes, router/domain services, Arc onboarding, and generated cluster configuration. Budget several hours, not minutes.
# Elevated PowerShell on LocalBox-Client; inspect, do not rerun bootstrap. Get-ScheduledTask -TaskName 'LocalBoxLogonScript' -ErrorAction SilentlyContinue | Select-Object TaskName, State Get-VM | Select-Object Name, State Get-ChildItem 'C:\LocalBox\Logs' -Filter '*.log' | Select-Object Name, LastWriteTimeInspect logs privately for the first failure. Do not run LocalBoxLogonScript again merely because a later stage failed: its storage-pool, virtual-disk, and partition operations are not a safe general-purpose retry mechanism. Confirm both AzLHOST nodes appear as connected Arc machines and that generated parameters contain no staging placeholders before cluster validation.
-
Validate the instance, then explicitly deploy it
Follow the official manual LocalBox workflow after prerequisites succeed. Its ARM
deploymentMode=Validatestarts real environment validation; it is different from template-only validation and what-if. Review the generated configuration privately, use the documented secure credential fields, then wait for successful validation before selecting Deploy now. Monitor the instance's Settings → Deployments until every stage succeeds. Do not publish or store an additional plaintext copy of the generated secret-bearing parameters.Template validation / what-if → outer Azure resources → nested setup and Arc onboarding → Azure Local deploymentMode: Validate → Azure Local deploymentMode: Deploy → platform readiness checks → workload provisioning and guest checksDistinct readiness gates: outer ARM success is not Azure Local deployment success, and platform success is not application success. -
Verify the platform before proceeding
On LocalBox-Client, use PowerShell Direct with the appropriate node administrator credential. Expect both nodes Up, healthy storage, available CSVs, and an operational bridge/custom location in Azure. Investigate unhealthy results instead of proceeding to workload creation.
$nodeCredential = Get-Credential -Message 'Azure Local node administrator' Invoke-Command -VMName 'AzLHOST1' -Credential $nodeCredential -ScriptBlock { Get-ClusterNode | Select-Object Name, State Get-StoragePool -IsPrimordial $false | Select-Object FriendlyName, HealthStatus, OperationalStatus Get-VirtualDisk | Select-Object FriendlyName, HealthStatus, OperationalStatus Get-ClusterSharedVolume | Select-Object Name, State }
| Statement | Evidence boundary |
|---|---|
| Recorded lab outcomes | Deployment evidence from 16 October; update Installed, both nodes Up, and Ubuntu on AzLHOST1 recorded 17 October 2026. These are not live 18 October health guarantees. |
| Unmodified reproduction | Not established: prepared-image access failed and recovery required custom ISO/Generation 2 preparation. |
| Migration | Instructions and target readiness do not establish that a manual VM migration completed. |
3.1 Execute deployment as a controlled platform change
Inputs and owners: require chapter 2's accepted address/capacity plan, approved AD OU/deployment account, supported release/media provenance, endpoint allowlist, reserved infrastructure pool, and a recovery contact independent of the new cluster. The AD-based LocalBox flow is the path actually described; do not mix local-identity/Key Vault instructions into its domain configuration. The platform owner approves the change, identity/network owners attest dependencies, and an authorized Azure operator supplies the correct tenant/subscription context. Directory lookup, Azure resource writes, role assignment, local administrative execution, and AD delegation are separate privileges; neither Microsoft Entra ID tenant administration nor Domain Admin is a blanket prerequisite to grant.
Map resource organization to the proposed ALZ Local Azure Local Clusters subscription; identity to scoped deployment and local cluster rights; connectivity to node/bridge endpoint tests; security/governance to compatible policies and protected credentials; management to readiness/update/recovery; automation to source pinning and gated replay; and tenant/billing to the approved disposable scope. The architecture target is not implemented by this lab's one resource group. Central Security, Management, Identity and Connectivity subscriptions remain proposed shared services, not deployment outputs.
| Context and action | Output / success gate | Failure and safe response |
|---|---|---|
| Management workstation: template compilation, ARM validation and what-if over HTTPS 443. | Reviewed template, providers, scope, proposed changes, and no unexpected privilege/network expansion. | Policy/authorization/region errors: fix the approved input; template success does not test node networking. |
| Outer Windows guest: first-logon nested bootstrap with local administrator rights. | Expected nested machines and logs, no unresolved media/bootstrap error, Arc onboarding complete. | 409 or failed storage preparation: preserve first error and halt; do not rerun destructive initialization. |
| Azure deployment orchestration → nodes and bridge. | Real environment validation passes, then deployment steps complete and bridge/custom location are healthy. | Accepted/Running or client timeout: inspect the same operation/deployment; do not race it with another create. |
| Authorized node/cluster console: read-only platform inspection. | Both nodes Up, CSVs Online, healthy pools/virtual disks, consistent network intents, available capacity. | Storage repair, failed intent, or node degradation: stop progressing to new workload deployment and resolve the platform condition with its owner. Do not automatically stop existing workloads. |
Cloud control-plane HTTPS, local management/AD communication, and SMB storage traffic are different failure paths. Test DNS/time and documented destinations from nodes and the bridge/proxy context, not solely your laptop. Follow the official firewall requirements: infrastructure Arc Private Link Scopes and HTTPS inspection are not supported. An ARM resource's region or management-group placement provides neither physical connectivity nor private routing.
3.2 Preserve supportability, rollback boundaries and handoff evidence
During validation, compare every host's Network ATC intent and resulting switch configuration. Do not “fix” one converged switch or migration-network order with a standalone Hyper-V setting; use the supported Network ATC workflow. Begin policy rollout in Audit against the actual provider/API versions and exercise bridge creation, upgrades and guest provisioning before enforcement. A universal Deny requiring public network access disabled is not a valid substitute for a tested Azure Local baseline.
Separate resume from rollback. Resume only a documented failed step after its dependency is repaired and no competing operation remains. Before workload data exists, an approved disposable-lab rebuild may be the safest recovery, but it is a new deployment with explicit resource/cost cleanup, not an in-place storage reset. After workloads exist, preserve configuration/data and follow supported repair or restore procedures with the platform/OEM support owner. Never delete the resource group as an automatic error handler, detach managed disks locally, or assume an incremental ARM deployment undoes guest-side changes.
For handoff, retain redacted operation timestamps/IDs, release and update identity, per-node/CSV health, bridge/extension/custom-location results, network-intent consistency, free capacity, and outstanding exceptions. Record the historical 17 October Installed/Up observations as observed then; require fresh checks before the reader's next stage. Monitoring delivery, alert ownership, privileged audit collection, application-consistent backup and a restore-tested RPO/RTO are separate acceptance items. Unless demonstrated, label them unverified; successful deployment does not establish recovery or a configured security service.
Sources
- Microsoft Learn: physical deployment sequence; portal deployment; providers and permissions.
- Pinned public LocalBox source: Bicep parameters, image acquisition and Validate/Deploy stages, and storage-bootstrap retry risk.
- Microsoft Learn: parameter objects and Azure PowerShell deployments; what-if; LocalBox Bicep deployment.