@@ -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 = @ ()
1019if (-not $Location ) { $MissingParams += " location" }
1120if (-not $Model ) { $MissingParams += " model" }
12- if (-not $Capacity ) { $MissingParams += " capacity" }
21+ if (-not $Capacity -or $Capacity -le 0 ) { $MissingParams += " capacity" }
1322
1423if ($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
2029if ($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
2936function 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
5868function 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 ------------------
71103Write-Host " `n 🔍 Checking quota in the requested region '$Location '..."
72104$PrimaryResult = Check- Quota - Region $Location
73105
74106if ($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 }
102152Show-Table
103153
104- # ----------- If eligible fallback regions found, ask user -----------
105154if ($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 " `n Please 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 " `n Please 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