Skip to content

Commit 2bbc102

Browse files
BillmanHwilliam_harding
andauthored
Small improvements to process flow and communication (#190)
## Purpose * Fixes a global ACR name collision that caused `External-Configurator.ps1` to silently skip container registry creation for any user who kept the default cluster name (`iot-ops-cluster`). The auto-generated name `iotopsclusteracr` is already taken in Azure; the fix appends a 6-character subscription ID suffix to make the name unique per-subscription while keeping it deterministic across re-runs. * Fixes an indefinite hang in `External-Configurator.ps1` and `grant_entra_id_roles.ps1` when required Azure CLI extensions (`azure-iot-ops`, `connectedk8s`, `k8s-extension`) are not installed. Both scripts now check for all three extensions at startup, print the exact install commands, and exit immediately rather than blocking. ## Does this introduce a breaking change? ``` [ ] Yes [x] No ``` Existing users who already set a custom `container_registry` value are unaffected. Users who relied on the old auto-generated name (`<cluster>acr`) will get a new name on first run — but since the old name was globally taken and ACR creation was silently skipped anyway, there is no working state to break. ## Pull Request Type ``` [x] Bugfix [ ] Feature [ ] Code style update (formatting, local variables) [ ] Refactoring (no functional changes, no api changes) [ ] Documentation content changes [ ] Other... Please describe: ``` ## How to Test * Get the code ``` git clone [repo-address] cd [repo-name] git checkout [branch-name] ``` * Test Issue 1 (ACR name collision): ```powershell # Use the default cluster name so the suffix logic is exercised $env:AKSEDGE_CLUSTER_NAME = "iot-ops-cluster" # Leave AZURE_CONTAINER_REGISTRY unset cd quickstart/external_configuration .\External-Configurator.ps1 -WhatIf # or run normally in a test subscription ``` * Test Issue 2 (extension check): ```powershell # Temporarily rename an extension to simulate it being absent az extension remove --name connectedk8s cd quickstart/external_configuration .\External-Configurator.ps1 # Expect: immediate error listing missing extensions with install commands, no hang .\grant_entra_id_roles.ps1 # Expect: same immediate error # Restore az extension add --upgrade --name connectedk8s ``` ## What to Check * ACR name printed in the yellow notice block includes a 6-character suffix derived from the subscription ID (not the bare `<cluster>acr` form). * Re-running the script with the same subscription produces the same ACR name (idempotent). * Setting `container_registry` in `aio_config.json` or `$env:AZURE_CONTAINER_REGISTRY` bypasses the auto-generation block entirely — the yellow notice does not appear. * With a missing extension, both `External-Configurator.ps1` and `grant_entra_id_roles.ps1` exit within seconds with a red error listing the missing extensions and the `az extension add` commands to fix them. * With all three extensions installed, both scripts proceed normally past the extension check. ## Other Information The subscription ID suffix approach was chosen over a random suffix because it keeps the name stable across re-runs (important for idempotency) while still being unique across different Azure tenants and subscriptions. The first 6 hex characters of a subscription ID provide sufficient entropy for this purpose. --------- Co-authored-by: william_harding <wharding@microsoft.com>
1 parent b52aa96 commit 2bbc102

3 files changed

Lines changed: 55 additions & 15 deletions

File tree

quickstart/external_configuration/External-Configurator.ps1

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -205,17 +205,26 @@ function Test-Prerequisites {
205205
Write-ErrorLog "Azure CLI is not installed or not in PATH" -Fatal
206206
}
207207

208-
# Check for iot-ops extension
208+
# Check for required CLI extensions — missing extensions cause az commands to hang indefinitely
209209
$extensions = az extension list --output json 2>$null | ConvertFrom-Json
210-
$iotOpsExt = $extensions | Where-Object { $_.name -eq 'azure-iot-ops' }
211-
212-
if (-not $iotOpsExt) {
213-
Write-WarnLog "azure-iot-ops extension not found. Install it manually before continuing:"
214-
Write-WarnLog " az extension add --name azure-iot-ops --upgrade"
215-
Write-WarnLog "Then re-run this script."
216-
$allPassed = $false
217-
} else {
218-
Write-Success "azure-iot-ops extension version: $($iotOpsExt.version)"
210+
$requiredCliExtensions = @('azure-iot-ops', 'connectedk8s', 'k8s-extension')
211+
$missingExtensions = @()
212+
213+
foreach ($extName in $requiredCliExtensions) {
214+
$ext = $extensions | Where-Object { $_.name -eq $extName }
215+
if ($ext) {
216+
Write-Success "$extName extension version: $($ext.version)"
217+
} else {
218+
$missingExtensions += $extName
219+
}
220+
}
221+
222+
if ($missingExtensions.Count -gt 0) {
223+
Write-ErrorLog "The following required Azure CLI extensions are not installed:" -Fatal:$false
224+
foreach ($extName in $missingExtensions) {
225+
Write-ErrorLog " az extension add --upgrade --name $extName" -Fatal:$false
226+
}
227+
Write-ErrorLog "Install the missing extensions above and re-run this script." -Fatal
219228
}
220229

221230
# Check ARM templates directory
@@ -661,10 +670,18 @@ function Connect-ToAzure {
661670
}
662671

663672
if (-not $script:ContainerRegistryName) {
664-
# ACR names: 5-50 chars, alphanumeric only, globally unique
665-
$script:ContainerRegistryName = ($clusterNameClean + "acr").Substring(0, [Math]::Min(50, ($clusterNameClean + "acr").Length))
673+
# ACR names: 5-50 chars, alphanumeric only, globally unique.
674+
# Append a 6-char suffix derived from the subscription ID to reduce global name collisions.
675+
$suffix = ($script:SubscriptionId -replace '-', '').Substring(0, 6)
676+
$baseName = $clusterNameClean + "acr" + $suffix
677+
$script:ContainerRegistryName = $baseName.Substring(0, [Math]::Min(50, $baseName.Length))
666678
$script:ContainerRegistryLoginServer = "$($script:ContainerRegistryName).azurecr.io"
667-
Write-InfoLog "Using auto-generated container registry name: $script:ContainerRegistryName"
679+
Write-Host ""
680+
Write-Host " [ACR] No container_registry value was set — auto-generating a name." -ForegroundColor Yellow
681+
Write-Host " [ACR] Container Registry will be created as: $script:ContainerRegistryName" -ForegroundColor Yellow
682+
Write-Host " [ACR] To use your own name, set 'container_registry' in config/aio_config.json" -ForegroundColor Yellow
683+
Write-Host " or set `$env:AZURE_CONTAINER_REGISTRY before running this script." -ForegroundColor Yellow
684+
Write-Host ""
668685
}
669686

670687
if (-not $script:KeyVaultName) {

quickstart/external_configuration/grant_entra_id_roles.ps1

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,28 @@ try {
357357
exit 1
358358
}
359359

360+
# Check for required CLI extensions — missing extensions cause az commands to hang indefinitely
361+
$extensions = az extension list --output json 2>$null | ConvertFrom-Json
362+
$requiredCliExtensions = @('azure-iot-ops', 'connectedk8s', 'k8s-extension')
363+
$missingExtensions = @()
364+
365+
foreach ($extName in $requiredCliExtensions) {
366+
$ext = $extensions | Where-Object { $_.name -eq $extName }
367+
if ($ext) {
368+
Write-Success "$extName extension version: $($ext.version)"
369+
} else {
370+
$missingExtensions += $extName
371+
}
372+
}
373+
374+
if ($missingExtensions.Count -gt 0) {
375+
Write-Host "ERROR: The following required Azure CLI extensions are not installed:" -ForegroundColor Red
376+
$missingExtensions | ForEach-Object { Write-Host " az extension add --upgrade --name $_" -ForegroundColor Yellow }
377+
Write-Host "Install the missing extensions above and re-run this script." -ForegroundColor Red
378+
Stop-Transcript
379+
exit 1
380+
}
381+
360382
# ============================================================================
361383
# AZURE AUTHENTICATION
362384
# ============================================================================

quickstart/readme.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ As the end-goal is an IoT solution, this repo has a preference for installing on
4646

4747

4848
# Quick Start
49-
The goal here is to install IoT Operations on an Ubuntu machine (like a local NUC, PC, or a VM) so that you can get working quickly on your dataflow pipelines and get data into Fabric quickly.
50-
* _if you are in a purely testing or validation phase you can create a quick VM using [this process](quick_vm_build.md)_
49+
The goal of this quickstart is to install IoT Operations on an Ubuntu or Windows machine (like a local NUC, PC, or a VM) so that you can get working quickly on your dataflow pipelines and get data into Fabric quickly. Additionaly there are optional modules that you can use to deploy data simulators in your project.
50+
* _if you are in a purely testing or validation phase you can create a quick VM using [this process]
51+
(quick_vm_build.md)_
5152
* _if you are building on a Windows machine using AKS Edge Essentials, see the [Single Windows Machine (AKS-EE)](#path-b-single-windows-machine-aks-ee) section below._
5253

5354
> **Using AKS Edge Essentials (Windows-based edge)?**

0 commit comments

Comments
 (0)