Skip to content

Commit 90f97be

Browse files
Merge pull request #130 from microsoft/fix/quota-validation-update
fix: quota validation script update
2 parents 900ba0e + 5c5dfbc commit 90f97be

2 files changed

Lines changed: 299 additions & 154 deletions

File tree

scripts/validate_model_quota.ps1

Lines changed: 131 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,49 +5,59 @@ param (
55
[int]$Capacity
66
)
77

8-
# Validate parameters
8+
$RECOMMENDED_TOKENS = 200
9+
$BicepParamsFile = "main.bicepparams"
10+
$ParametersJsonFile = "./infra/main.parameters.json"
11+
$PreferredRegions = @('australiaeast', 'eastus', 'eastus2', 'francecentral', 'japaneast', 'norwayeast', 'southindia', 'swedencentral', 'uksouth', 'westus', 'westus3')
12+
$AllResults = @()
13+
$RecommendedRegions = @()
14+
$NotRecommendedRegions = @()
15+
$EligibleFallbacks = @()
16+
17+
# ------------------ Validate Inputs ------------------
918
$MissingParams = @()
1019
if (-not $Location) { $MissingParams += "location" }
1120
if (-not $Model) { $MissingParams += "model" }
12-
if (-not $Capacity) { $MissingParams += "capacity" }
21+
if (-not $Capacity -or $Capacity -le 0) { $MissingParams += "capacity" }
1322

1423
if ($MissingParams.Count -gt 0) {
15-
Write-Error "❌ ERROR: Missing required parameters: $($MissingParams -join ', ')"
24+
Write-Error "❌ ERROR: Missing or invalid parameters: $($MissingParams -join ', ')"
1625
Write-Host "Usage: .\validate_model_quota.ps1 -Location <LOCATION> -Model <MODEL> -Capacity <CAPACITY> [-DeploymentType <DEPLOYMENT_TYPE>]"
1726
exit 1
1827
}
1928

2029
if ($DeploymentType -ne "Standard" -and $DeploymentType -ne "GlobalStandard") {
21-
Write-Error "❌ ERROR: Invalid deployment type: $DeploymentType. Allowed values are 'Standard' or 'GlobalStandard'."
30+
Write-Error "❌ ERROR: Invalid deployment type: $DeploymentType. Allowed: 'Standard', 'GlobalStandard'"
2231
exit 1
2332
}
2433

2534
$ModelType = "OpenAI.$DeploymentType.$Model"
26-
$PreferredRegions = @('australiaeast', 'eastus', 'eastus2', 'francecentral', 'japaneast', 'norwayeast', 'southindia', 'swedencentral', 'uksouth', 'westus', 'westus3')
27-
$AllResults = @()
2835

2936
function Check-Quota {
30-
param (
31-
[string]$Region
32-
)
37+
param ([string]$Region)
3338

3439
try {
35-
$ModelInfoRaw = az cognitiveservices usage list --location $Region --query "[?name.value=='$ModelType']" --output json
40+
$ModelInfoRaw = az cognitiveservices usage list --location $Region --query "[?name.value=='$ModelType']" --output json 2>$null
3641
$ModelInfo = $ModelInfoRaw | ConvertFrom-Json
37-
if (-not $ModelInfo) { return $null }
42+
if (-not $ModelInfo -or $ModelInfo.Count -eq 0) {
43+
return $null
44+
}
3845

39-
$CurrentValue = ($ModelInfo | Where-Object { $_.name.value -eq $ModelType }).currentValue
40-
$Limit = ($ModelInfo | Where-Object { $_.name.value -eq $ModelType }).limit
46+
$Current = [int]$ModelInfo[0].currentValue
47+
$Limit = [int]$ModelInfo[0].limit
48+
$Available = $Limit - $Current
4149

42-
$CurrentValue = [int]($CurrentValue -replace '\.0+$', '')
43-
$Limit = [int]($Limit -replace '\.0+$', '')
44-
$Available = $Limit - $CurrentValue
50+
if ($Available -ge $RECOMMENDED_TOKENS) {
51+
$script:RecommendedRegions += $Region
52+
} else {
53+
$script:NotRecommendedRegions += $Region
54+
}
4555

4656
return [PSCustomObject]@{
4757
Region = $Region
4858
Model = $ModelType
4959
Limit = $Limit
50-
Used = $CurrentValue
60+
Used = $Current
5161
Available = $Available
5262
}
5363
} catch {
@@ -56,81 +66,138 @@ function Check-Quota {
5666
}
5767

5868
function Show-Table {
59-
Write-Host "`n--------------------------------------------------------------------------------------------"
60-
Write-Host "| No. | Region | Model Name | Limit | Used | Available |"
61-
Write-Host "--------------------------------------------------------------------------------------------"
62-
$count = 1
63-
foreach ($entry in $AllResults) {
64-
Write-Host ("| {0,-3} | {1,-14} | {2,-35} | {3,-5} | {4,-5} | {5,-9} |" -f $count, $entry.Region, $entry.Model, $entry.Limit, $entry.Used, $entry.Available)
65-
$count++
69+
Write-Host "`n--------------------------------------------------------------------------------------------------"
70+
Write-Host "| No. | Region | Model Name | Limit | Used | Available |"
71+
Write-Host "--------------------------------------------------------------------------------------------------"
72+
$i = 1
73+
foreach ($entry in $AllResults | Where-Object { $_.Available -gt 50 }) {
74+
Write-Host ("| {0,-3} | {1,-15} | {2,-35} | {3,-5} | {4,-5} | {5,-9} |" -f $i, $entry.Region, $entry.Model, $entry.Limit, $entry.Used, $entry.Available)
75+
$i++
6676
}
67-
Write-Host "--------------------------------------------------------------------------------------------"
77+
Write-Host "--------------------------------------------------------------------------------------------------"
6878
}
6979

70-
# ----------- First check the user-specified region -----------
80+
function Set-DeploymentValues($Region, $Capacity) {
81+
azd env set AZURE_AISERVICE_LOCATION "$Region" | Out-Null
82+
azd env set AZURE_ENV_MODEL_CAPACITY "$Capacity" | Out-Null
83+
84+
if (Test-Path $ParametersJsonFile) {
85+
try {
86+
$json = Get-Content $ParametersJsonFile -Raw | ConvertFrom-Json
87+
if ($json.parameters.aiModelDeployments.value.Count -gt 0) {
88+
$json.parameters.aiModelDeployments.value[0].sku.capacity = $Capacity
89+
$json | ConvertTo-Json -Depth 20 | Set-Content $ParametersJsonFile -Force
90+
Write-Host "✅ Updated '$ParametersJsonFile' with capacity $Capacity."
91+
} else {
92+
Write-Host "⚠️ 'aiModelDeployments.value' array is empty. No changes made."
93+
}
94+
} catch {
95+
Write-Host "❌ Failed to update '$ParametersJsonFile': $_"
96+
}
97+
} else {
98+
Write-Host "⚠️ '$ParametersJsonFile' not found. Skipping update."
99+
}
100+
}
101+
102+
# ------------------ Check Primary Region ------------------
71103
Write-Host "`n🔍 Checking quota in the requested region '$Location'..."
72104
$PrimaryResult = Check-Quota -Region $Location
73105

74106
if ($PrimaryResult) {
75107
$AllResults += $PrimaryResult
76108
if ($PrimaryResult.Available -ge $Capacity) {
77-
Write-Host "`n✅ Sufficient quota found in original region '$Location'."
78-
exit 0
109+
if ($RecommendedRegions -notcontains $Location -and $RecommendedRegions.Count -gt 0) {
110+
Write-Host "`n⚠️ Selected region '$Location' has sufficient quota but is not among the recommended regions (≥ $RECOMMENDED_TOKENS tokens)."
111+
Write-Host "🚨 Your application may not work as expected due to limited quota."
112+
Write-Host "`nℹ️ Recommended regions: $($RecommendedRegions -join ', ')"
113+
Write-Host "👉 It's advisable to deploy in one of these regions for optimal app performance."
114+
$choice = Read-Host "❓ Do you want to choose a recommended region instead? (y/n)"
115+
if ($choice -match "^[Yy]$") {
116+
Show-Table
117+
break
118+
} else {
119+
if ($Capacity -gt 200) {
120+
Write-Host "`n⚠️ Reducing capacity to 200 in '$BicepParamsFile' for safer deployment..."
121+
(Get-Content $BicepParamsFile) -replace "capacity\s*:\s*\d+", "capacity: 200" | Set-Content $BicepParamsFile
122+
Write-Host "✅ Updated '$BicepParamsFile' with capacity 200."
123+
}
124+
Set-DeploymentValues $Location $Capacity
125+
Write-Host "✅ Proceeding with '$Location' as selected."
126+
exit 0
127+
}
128+
} else {
129+
Write-Host "`n✅ Sufficient quota found in original region '$Location'."
130+
Set-DeploymentValues $Location $Capacity
131+
exit 0
132+
}
79133
} else {
80-
Write-Host "`n⚠️ Insufficient quota in '$Location' (Available: $($PrimaryResult.Available), Required: $Capacity). Checking fallback regions..."
134+
Write-Host "`n⚠️ Insufficient quota in '$Location'. Checking fallback regions..."
81135
}
82136
} else {
83-
Write-Host "`n⚠️ Could not retrieve quota info for region '$Location'. Checking fallback regions..."
137+
Write-Host "`n⚠️ Could not retrieve quota info for region '$Location'."
84138
}
85139

86-
# ----------- Check all other fallback regions -----------
87-
$FallbackRegions = $PreferredRegions | Where-Object { $_ -ne $Location }
88-
$EligibleFallbacks = @()
89-
90-
foreach ($region in $FallbackRegions) {
140+
# ------------------ Check Fallback Regions ------------------
141+
foreach ($region in $PreferredRegions) {
142+
if ($region -eq $Location) { continue }
91143
$result = Check-Quota -Region $region
92144
if ($result) {
93145
$AllResults += $result
94146
if ($result.Available -ge $Capacity) {
95-
$EligibleFallbacks += $result
147+
$EligibleFallbacks += $region
96148
}
97149
}
98150
}
99151

100-
# ----------- Show Table of All Regions Checked -----------
101-
$AllResults = $AllResults | Where-Object { $_.Available -gt 50 }
102152
Show-Table
103153

104-
# ----------- If eligible fallback regions found, ask user -----------
105154
if ($EligibleFallbacks.Count -gt 0) {
106-
Write-Host "`n❌ Deployment cannot proceed in '$Location'."
107-
Write-Host "➡️ Found fallback regions with sufficient quota."
108-
109-
while ($true) {
110-
Write-Host "`nPlease enter a fallback region from the list above to proceed:"
111-
$NewLocation = Read-Host "Enter region"
112-
113-
if (-not $NewLocation) {
114-
Write-Host "❌ No location entered. Exiting."
115-
exit 1
155+
Write-Host "`n➡️ Found fallback regions with sufficient quota."
156+
if ($RecommendedRegions.Count -gt 0) {
157+
Write-Host "`nℹ️ Recommended regions (≥ $RECOMMENDED_TOKENS tokens available):"
158+
foreach ($region in $RecommendedRegions) {
159+
Write-Host " - $region"
116160
}
161+
}
162+
}
117163

118-
$UserResult = Check-Quota -Region $NewLocation
119-
if (-not $UserResult) {
120-
Write-Host "⚠️ Could not retrieve quota info for region '$NewLocation'. Try again."
121-
continue
122-
}
164+
# ------------------ Manual Prompt if No Quota Found ------------------
165+
Write-Host "`n❌ ERROR: No region has sufficient quota."
123166

124-
if ($UserResult.Available -ge $Capacity) {
125-
Write-Host "✅ Sufficient quota found in '$NewLocation'. Proceeding with deployment."
126-
azd env set AZURE_AISERVICE_LOCATION "$NewLocation" | Out-Null
127-
Write-Host "➡️ Set AZURE_AISERVICE_LOCATION to '$NewLocation'."
128-
exit 0
129-
} else {
130-
Write-Host "❌ Insufficient quota in '$NewLocation'. Try another."
167+
while ($true) {
168+
$ManualRegion = Read-Host "`nPlease enter a region you want to try manually"
169+
if (-not $ManualRegion) {
170+
Write-Host "❌ ERROR: No region entered. Exiting."
171+
exit 1
172+
}
173+
174+
$ManualCapacityStr = Read-Host "Enter the capacity you want to use (numeric value)"
175+
if (-not ($ManualCapacityStr -as [int]) -or [int]$ManualCapacityStr -le 0) {
176+
Write-Host "❌ Invalid capacity value. Try again."
177+
continue
178+
}
179+
180+
$ManualCapacity = [int]$ManualCapacityStr
181+
$ManualResult = Check-Quota -Region $ManualRegion
182+
183+
if (-not $ManualResult) {
184+
Write-Host "⚠️ Could not retrieve quota info for region '$ManualRegion'. Try again."
185+
continue
186+
}
187+
188+
if ($ManualResult.Available -ge $ManualCapacity) {
189+
if ($ManualResult.Available -lt $RECOMMENDED_TOKENS) {
190+
Write-Host "`n⚠️ Region '$ManualRegion' has less than recommended ($RECOMMENDED_TOKENS) tokens."
191+
$proceed = Read-Host "❓ Proceed anyway? (y/n)"
192+
if ($proceed -notmatch "^[Yy]$") {
193+
continue
194+
}
131195
}
196+
197+
Set-DeploymentValues $ManualRegion $ManualCapacity
198+
Write-Host "✅ Deployment values set. Exiting."
199+
exit 0
200+
} else {
201+
Write-Host "❌ Quota in region '$ManualRegion' is insufficient. Available: $($ManualResult.Available), Required: $ManualCapacity"
132202
}
133203
}
134-
135-
Write-Error "`n❌ ERROR: No available quota found in any region."
136-
exit 1

0 commit comments

Comments
 (0)