Azure Local’ı Service Principal ile Azure Arc’a Kaydetme
Azure Local’ı Azure Arc’a kaydetmek, önceki sürümlere kıyasla daha kolay hale geldi. Standart yöntemde Azure’da Device Code ile kimlik doğrulaması yapılıyor ve kayıt işlemi başlatılıyor. Ancak bazı kurumların güvenlik politikaları, yönetilmeyen bir sunucudan Device Code ile oturum açılmasına izin vermiyor. Uçtan uca dağıtım otomasyonu hedefleyen ekipler de kullanıcı etkileşimine ihtiyaç duymayan bir yöntem arayabiliyor.
Bu senaryolarda Azure Local’ı bir Service Principal (SPN), yani uygulama kaydı üzerinden Azure Arc’a kaydetmek mümkün. Aşağıdaki örnekler, bu işlemin PowerShell ile nasıl yapılabileceğini ve sonraki adımların nasıl otomatikleştirilebileceğini gösteriyor.
Ön koşullar
İşleme başlamadan önce aşağıdaki gereksinimleri kontrol edin:
- Azure Arc’a bağlanacak Azure Local makineleri 2505 veya sonraki bir sürümü çalıştırmalı.
- Makinelere ilk kurulum için geçici yönetim ağı bağlantısı sağlanmış olmalı.
- Her Azure Local makinesinin hostname’i (Computer Name) belirlenmiş olmalı.
- SPN’e gerekli Azure izinleri atanmalı. Alternatif olarak, gerekli role assignment’ların önceden yapıldığı bir resource group kullanılmalı.
- Kullanılacak Azure region, Azure Local için destekleniyor olmalı.
Gerekli izinleri, resource provider’ları ve desteklenen region’ları işlem öncesinde Microsoft Learn dokümantasyonundan doğrulayın.
Parametreleri tanımlayın
Aşağıdaki örnekte Azure ortamı, region, resource group, subscription, tenant ve uygulama kaydı bilgileri değişkenlere atanıyor. SPN secret ise ekrana açık biçimde yazılmadan SecureString olarak alınıyor.
# Azure Details
$AzureEnvironment = "AzureCloud"
$AzureRegion = "eastus"
$AzureResourceGroup = "<MyAzureResourceGroup>"
$AzureSubscriptionId = "<MyAzureSubscriptionId>"
$AzureTenantId = "<MyAzureTenantId>"
$AzureSPNId = "<MyAzureAppRegistrationId>"
$AzureSPNSecret = Read-Host -Prompt "Azure SPN Secret" -AsSecureString
# Create Credential Objects
$AzureSPNCredential = New-Object System.Management.Automation.PSCredential (
$AzureSPNId,
$AzureSPNSecret
)
<MyAzureResourceGroup>, subscription ve tenant bilgileriyle birlikte <MyAzureAppRegistrationId> değerini kendi ortamınızdaki bilgilerle değiştirin.
Azure’a Service Principal ile bağlanın
Kimlik doğrulaması için Connect-AzAccount komutunu Service Principal parametreleriyle çalıştırın:
Connect-AzAccount `
-ServicePrincipal `
-TenantId $AzureTenantId `
-Environment $AzureEnvironment `
-Credential $AzureSPNCredential `
-InformationAction Ignore
Komut başarıyla tamamlandığında, oturum SPN kimliğiyle Azure’a bağlanır.
Az.Accounts sürümünü ve token biçimini kontrol edin
Azure Local’ın bazı golden image sürümlerinde birden fazla Az.Accounts modülü bulunabilir. Bu nedenle Connect-AzAccount tarafından yüklenen modül sürümünü dikkate almak gerekir.
Az.Accounts 5.3.0 ve sonraki sürümlerinde, Get-AzAccessToken komutunun döndürdüğü Token değeri SecureString biçimindedir. Buna karşılık Invoke-AzStackHciArcInitialization komutu, -ArmAccessToken parametresinde String bekler.
Yüklü modül sürümünü görmek için:
Get-Module -Name "Az.Accounts" |
Select-Object Name, Version, Path
Arc initialization komutunun parametrelerini de inceleyebilirsiniz:
Get-Command -Name "Invoke-AzStackHciArcInitialization" -Syntax
Aşağıdaki örnek, yüklü Az.Accounts sürümünü kontrol eder ve token’ı gerektiğinde String biçimine dönüştürür:
$AzAccountsLoaded = Get-Module -Name "Az.Accounts" |
Select-Object Name, Version, Path
if ([Version]$AzAccountsLoaded.Version -ge [Version]"5.3.0") {
$AzureAccessToken = (
Get-AzAccessToken -WarningAction SilentlyContinue
).Token
Invoke-AzStackHciArcInitialization `
-SubscriptionID $AzureSubscriptionId `
-ResourceGroup $AzureResourceGroup `
-TenantID $AzureTenantId `
-Region $AzureRegion `
-Cloud $AzureEnvironment `
-ArmAccessToken $(
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR(
$AzureAccessToken
)
)
) `
-AccountID ((Get-AzContext).Account.Id)
}
else {
Invoke-AzStackHciArcInitialization `
-SubscriptionID $AzureSubscriptionId `
-ResourceGroup $AzureResourceGroup `
-TenantID $AzureTenantId `
-Region $AzureRegion `
-Cloud $AzureEnvironment `
-ArmAccessToken (
Get-AzAccessToken -WarningAction SilentlyContinue
).Token `
-AccountID ((Get-AzContext).Account.Id)
}
Bu örnekte SecureString, komuta aktarılırken String biçimine dönüştürülüyor. Token hassas bir kimlik doğrulama bilgisi olduğundan script çıktısına, log’lara veya komut geçmişine yazdırılmamalı; kullanım süresi ve erişimi de güvenli biçimde yönetilmelidir.
Arc initialization işleminin yeniden başlatma ihtimalini hesaba katın
Azure Arc kayıt işlemi sırasında makine, golden image ile gelen sürümden daha yeni bir hedef solution version’a geçirilebilir. Böyle bir durumda node yeniden başlayabilir.
Node yeniden başladıktan sonra yerel administrator hesabıyla tekrar oturum açın; Azure bağlantısını ve yukarıdaki Arc initialization komutlarını yeniden çalıştırın.
Arc Bootstrap durumunu izleyin
Azure Local golden image’larında bulunan Get-ArcBootstrapStatus komutu, Arc Bootstrap işleminin durumunu kontrol etmeye yardımcı olur. Durumu doğrudan node üzerinde görmek için:
(Get-ArcBootstrapStatus).Response
İşlemi uzaktan izlemek için aşağıdaki gibi bir döngü kullanılabilir:
# Define variables
$OSCredential = Get-Credential `
-Message "Azure Local Administrator OS Credential"
$NodeIpAddress = "<NodeIpAddress>"
$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
:MonitorArcBootStrapStatus while ($true) {
if ($OSSession.State -ne 'Opened') {
$OSSession = New-PSSession `
-ComputerName $NodeIpAddress `
-Credential $OSCredential
}
$ArcBootStrapResponse = Invoke-Command -Session $OSSession {
return (Get-ArcBootStrapStatus).Response
}
$ArcBootStrapStatus = $ArcBootStrapResponse.Status
switch ($ArcBootStrapStatus) {
'InProgress' {
Write-Host "Arc Bootstrap Status: $($ArcBootStrapStatus) (Sleeping 5 minutes)"
Start-Sleep -Seconds 300
}
'Succeeded' {
Write-Host "Arc Bootstrap Status: $($ArcBootStrapStatus)"
break MonitorArcBootStrapStatus
}
'Failed' {
Write-Host "Arc Bootstrap Status: $($ArcBootStrapStatus)"
throw "Arc Bootstrap Failed - $($ArcBootStrapResponse.Message)"
}
}
if ($Stopwatch.Elapsed.TotalSeconds -gt 1800) {
throw "Timeout Exceeded"
}
}
Döngü, durum InProgress olduğu sürece beş dakikada bir kontrol yapar. İşlem başarılı olduğunda durur; başarısızlık durumunda hata mesajını gösterir. Örnekte 30 dakikalık bir timeout sınırı da bulunur.
Azure Arc machine extension’larını yükleyin
Node’lar Azure Arc’a kaydedildikten sonra, Azure Local dağıtımının gerektirdiği Azure Arc machine extension’larının yüklenmesi gerekir. Bu adım için Az.ConnectedMachine PowerShell modülü kullanılır.
Komutlar, internet erişimi ve gerekli PowerShell modülleri bulunan ayrı bir Windows makinesinden de çalıştırılabilir. Birden fazla node için aynı işlemi bir node listesi ve ForEach döngüsüyle otomatikleştirmek mümkündür.
Aşağıdaki örnek, node üzerindeki başarılı extension sayısını kontrol eder. Dört başarılı extension varsa kurulum adımını atlar; aksi durumda ilgili Azure REST API çağrısını yapar:
# Node Details
$NodeHostname = "<MyNodeHostname>"
$AzConnectedMachineExtensions = (
Get-AzConnectedMachineExtension `
-ResourceGroupName $AzureResourceGroup `
-MachineName $NodeHostname |
Where-Object { $_.ProvisioningState -eq 'Succeeded' } |
Measure-Object
).Count
if ($AzConnectedMachineExtensions -ge 4) {
Write-Host "Machine Extensions Status - Total : $($AzConnectedMachineExtensions) (Skipping Install)"
}
else {
$Response = Invoke-AzRestMethod `
-Method PUT `
-Uri "https://management.azure.com/subscriptions/$AzureSubscriptionId/resourceGroups/$AzureResourceGroup/providers/Microsoft.HybridCompute/machines/$NodeHostname/providers/microsoft.azurestackhci/edgeDevices/default?api-version=2024-09-01-preview" `
-Payload (@{
kind = 'HCI'
} | ConvertTo-Json)
if ($Response.StatusCode -ne 201) {
throw "Response '$($Response.StatusCode)' is not 201 (Created) - Aborting - $($Response.Content)"
}
}
Machine extension kurulumunu izleyin
Kurulumun tamamlandığını doğrulamak için extension’ların toplam sayısı ve başarılı olanların sayısı belirli aralıklarla kontrol edilebilir:
$Stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
while ($true) {
$AzConnectedMachineExtensions = Get-AzConnectedMachineExtension `
-ResourceGroupName $AzureResourceGroup `
-MachineName $NodeHostname
$AzConnectedMachineExtensionsTotal = (
$AzConnectedMachineExtensions | Measure-Object
).Count
$AzConnectedMachineExtensionsSucceeded = (
$AzConnectedMachineExtensions |
Where-Object { $_.ProvisioningState -eq 'Succeeded' } |
Measure-Object
).Count
Write-Host "Machine Extensions Status - Total : $($AzConnectedMachineExtensionsTotal) | Succeeded : $($AzConnectedMachineExtensionsSucceeded)"
if (
$AzConnectedMachineExtensionsTotal -ge 4 -and
$AzConnectedMachineExtensionsTotal -eq $AzConnectedMachineExtensionsSucceeded
) {
break
}
if ($Stopwatch.Elapsed.TotalSeconds -gt 900) {
throw "Timeout Exceeded"
}
Start-Sleep -Seconds 30
}
Bu örnek, en az dört extension’ın listelendiğini ve tamamının Succeeded durumuna geçtiğini doğrulamayı bekler. Kurulum 15 dakika içinde tamamlanmazsa timeout hatası üretir.
Sonraki adım: Azure Local dağıtımını başlatın
Node’lar Azure Arc’a kaydedilip gerekli machine extension’ları yüklendikten sonra Azure Local dağıtımının sonraki aşamalarına geçilebilir. Dağıtımı Azure portal arayüzüyle sürdürebilir veya uygun bir otomasyon senaryosunda ARM template kullanabilirsiniz.
SPN tabanlı kayıt; kullanıcı etkileşimini azaltarak tekrarlanabilir dağıtımları kolaylaştırır. Uygulamadan önce SPN izinlerini, desteklenen region’ı, node hazırlık durumunu ve yüklü PowerShell modülü sürümlerini doğrulamak, sürecin daha sorunsuz ilerlemesine yardımcı olur.







