Skip to content

Commit 32aa1f0

Browse files
quota auto validation
1 parent 449e6b2 commit 32aa1f0

File tree

3 files changed

+131
-74
lines changed

3 files changed

+131
-74
lines changed

infra/main.parameters.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@
22
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
33
"contentVersion": "1.0.0.0",
44
"parameters": {
5+
"aiModelDeployments": {
6+
"value": [
7+
{
8+
"name": "gpt",
9+
"model": {
10+
"name": "gpt-4o",
11+
"version": "2024-08-06",
12+
"format": "OpenAI"
13+
},
14+
"sku": {
15+
"name": "GlobalStandard",
16+
"capacity": 140
17+
}
18+
}
19+
]
20+
},
521
"environmentName": {
622
"value": "${AZURE_ENV_NAME}"
723
},

infra/scripts/validate_model_quota.ps1

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

8-
# Verify all required parameters are provided
8+
# Verify required parameters
99
$MissingParams = @()
10-
11-
if (-not $Location) {
12-
$MissingParams += "location"
13-
}
14-
15-
if (-not $Model) {
16-
$MissingParams += "model"
17-
}
18-
19-
if (-not $Capacity) {
20-
$MissingParams += "capacity"
21-
}
22-
23-
if (-not $DeploymentType) {
24-
$MissingParams += "deployment-type"
25-
}
10+
if (-not $Location) { $MissingParams += "location" }
11+
if (-not $Model) { $MissingParams += "model" }
12+
if (-not $Capacity) { $MissingParams += "capacity" }
13+
if (-not $DeploymentType) { $MissingParams += "deployment-type" }
2614

2715
if ($MissingParams.Count -gt 0) {
2816
Write-Error "❌ ERROR: Missing required parameters: $($MissingParams -join ', ')"
@@ -37,30 +25,70 @@ if ($DeploymentType -ne "Standard" -and $DeploymentType -ne "GlobalStandard") {
3725

3826
$ModelType = "OpenAI.$DeploymentType.$Model"
3927

40-
Write-Host "🔍 Checking quota for $ModelType in $Location ..."
28+
function Check-Quota {
29+
param (
30+
[string]$Region
31+
)
4132

42-
# Get model quota information
43-
$ModelInfo = az cognitiveservices usage list --location $Location --query "[?name.value=='$ModelType']" --output json | ConvertFrom-Json
33+
Write-Host "`n🔍 Checking quota for $ModelType in $Region ..."
4434

45-
if (-not $ModelInfo) {
46-
Write-Error "❌ ERROR: No quota information found for model: $Model in location: $Location for model type: $ModelType."
47-
exit 1
48-
}
35+
$ModelInfoRaw = az cognitiveservices usage list --location $Region --query "[?name.value=='$ModelType']" --output json
36+
$ModelInfo = $null
37+
38+
try {
39+
$ModelInfo = $ModelInfoRaw | ConvertFrom-Json
40+
} catch {
41+
Write-Warning "⚠️ Failed to parse quota info for region: $Region"
42+
return $false
43+
}
44+
45+
if (-not $ModelInfo) {
46+
Write-Host "⚠️ No quota information found for $ModelType in $Region"
47+
return $false
48+
}
4949

50-
if ($ModelInfo) {
5150
$CurrentValue = ($ModelInfo | Where-Object { $_.name.value -eq $ModelType }).currentValue
5251
$Limit = ($ModelInfo | Where-Object { $_.name.value -eq $ModelType }).limit
5352

5453
$CurrentValue = [int]($CurrentValue -replace '\.0+$', '') # Remove decimals
5554
$Limit = [int]($Limit -replace '\.0+$', '') # Remove decimals
5655

5756
$Available = $Limit - $CurrentValue
58-
Write-Host "✅ Model available - Model: $ModelType | Used: $CurrentValue | Limit: $Limit | Available: $Available"
57+
Write-Host "🔎 Model: $ModelType | Used: $CurrentValue | Limit: $Limit | Available: $Available"
5958

60-
if ($Available -lt $Capacity) {
61-
Write-Error "❌ ERROR: Insufficient quota for model: $Model in location: $Location. Available: $Available, Requested: $Capacity."
62-
exit 1
59+
if ($Available -ge $Capacity) {
60+
Write-Host "✅ Sufficient quota in $Region"
61+
return $true
6362
} else {
64-
Write-Host "✅ Sufficient quota for model: $Model in location: $Location. Available: $Available, Requested: $Capacity."
63+
Write-Host "❌ Insufficient quota in $Region (Available: $Available, Required: $Capacity)"
64+
return $false
65+
}
66+
}
67+
68+
# List of fallback regions (excluding the one already tried)
69+
$PreferredRegions = @('australiaeast', 'eastus2', 'francecentral', 'japaneast', 'norwayeast', 'swedencentral', 'uksouth', 'westus') | Where-Object { $_ -ne $Location }
70+
71+
# Try original location first
72+
if (Check-Quota -Region $Location) {
73+
exit 0
74+
}
75+
76+
Write-Host "`n🔁 Trying fallback regions for available quota..."
77+
78+
foreach ($region in $PreferredRegions) {
79+
if (Check-Quota -Region $region) {
80+
Write-Host "🚫 Deployment cannot proceed because the original region '$Location' lacks sufficient quota."
81+
Write-Host "➡️ You can retry using the available region: '$region'"
82+
Write-Host "🔧 To proceed, update the 'AZURE_OPENAI_LOCATION' value in the 'main.bicepparam' file, then run the following command:"
83+
Write-Host " azd env set AZURE_OPENAI_LOCATION '$region'"
84+
85+
# Optional: update `.azure/env` (uncomment if needed)
86+
# Add-Content ".azure/env" "`nAZURE_OPENAI_LOCATION=$region"
87+
88+
# Exit with non-zero code to halt deployment
89+
exit 2
6590
}
66-
}
91+
}
92+
93+
Write-Error "❌ ERROR: No available quota found in any region."
94+
exit 1

infra/scripts/validate_model_quota.sh

Lines changed: 56 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ MODEL=""
55
DEPLOYMENT_TYPE="Standard"
66
CAPACITY=0
77

8+
ALL_REGIONS=('australiaeast' 'eastus2' 'francecentral' 'japaneast' 'norwayeast' 'swedencentral' 'uksouth' 'westus')
9+
810
while [[ $# -gt 0 ]]; do
911
case "$1" in
1012
--model)
@@ -30,64 +32,75 @@ while [[ $# -gt 0 ]]; do
3032
esac
3133
done
3234

33-
# Verify all required parameters are provided and echo missing ones
35+
# Validate required params
3436
MISSING_PARAMS=()
37+
[[ -z "$LOCATION" ]] && MISSING_PARAMS+=("location")
38+
[[ -z "$MODEL" ]] && MISSING_PARAMS+=("model")
39+
[[ -z "$CAPACITY" ]] && MISSING_PARAMS+=("capacity")
3540

36-
if [[ -z "$LOCATION" ]]; then
37-
MISSING_PARAMS+=("location")
41+
if [[ ${#MISSING_PARAMS[@]} -ne 0 ]]; then
42+
echo "❌ ERROR: Missing required parameters: ${MISSING_PARAMS[*]}"
43+
echo "Usage: $0 --location <LOCATION> --model <MODEL> --capacity <CAPACITY> [--deployment-type <DEPLOYMENT_TYPE>]"
44+
exit 1
3845
fi
3946

40-
if [[ -z "$MODEL" ]]; then
41-
MISSING_PARAMS+=("model")
47+
if [[ "$DEPLOYMENT_TYPE" != "Standard" && "$DEPLOYMENT_TYPE" != "GlobalStandard" ]]; then
48+
echo "❌ ERROR: Invalid deployment type: $DEPLOYMENT_TYPE. Allowed values are 'Standard' or 'GlobalStandard'."
49+
exit 1
4250
fi
4351

44-
if [[ -z "$CAPACITY" ]]; then
45-
MISSING_PARAMS+=("capacity")
46-
fi
52+
MODEL_TYPE="OpenAI.$DEPLOYMENT_TYPE.$MODEL"
4753

48-
if [[ -z "$DEPLOYMENT_TYPE" ]]; then
49-
MISSING_PARAMS+=("deployment-type")
50-
fi
54+
check_quota() {
55+
local region="$1"
56+
echo "🔍 Checking quota for $MODEL_TYPE in $region ..."
5157

52-
if [[ ${#MISSING_PARAMS[@]} -ne 0 ]]; then
53-
echo "❌ ERROR: Missing required parameters: ${MISSING_PARAMS[*]}"
54-
echo "Usage: $0 --location <LOCATION> --model <MODEL> --capacity <CAPACITY> [--deployment-type <DEPLOYMENT_TYPE>]"
55-
exit 1
56-
fi
58+
MODEL_INFO=$(az cognitiveservices usage list --location "$region" --query "[?name.value=='$MODEL_TYPE']" --output json 2>/dev/null)
5759

58-
if [[ "$DEPLOYMENT_TYPE" != "Standard" && "$DEPLOYMENT_TYPE" != "GlobalStandard" ]]; then
59-
echo "❌ ERROR: Invalid deployment type: $DEPLOYMENT_TYPE. Allowed values are 'Standard' or 'GlobalStandard'."
60-
exit 1
61-
fi
60+
if [[ -z "$MODEL_INFO" || "$MODEL_INFO" == "[]" ]]; then
61+
echo "⚠️ No quota info found for $MODEL_TYPE in $region"
62+
return 1
63+
fi
6264

63-
MODEL_TYPE="OpenAI.$DEPLOYMENT_TYPE.$MODEL"
65+
CURRENT_VALUE=$(echo "$MODEL_INFO" | jq -r '.[0].currentValue // 0' | cut -d'.' -f1)
66+
LIMIT=$(echo "$MODEL_INFO" | jq -r '.[0].limit // 0' | cut -d'.' -f1)
67+
AVAILABLE=$((LIMIT - CURRENT_VALUE))
6468

65-
echo "🔍 Checking quota for $MODEL_TYPE in $LOCATION ..."
69+
echo "🔎 Model: $MODEL_TYPE | Used: $CURRENT_VALUE | Limit: $LIMIT | Available: $AVAILABLE"
6670

67-
MODEL_INFO=$(az cognitiveservices usage list --location "$LOCATION" --query "[?name.value=='$MODEL_TYPE']" --output json | tr '[:upper:]' '[:lower:]')
71+
if (( AVAILABLE >= CAPACITY )); then
72+
echo "✅ Sufficient quota in $region"
73+
return 0
74+
else
75+
echo "❌ Insufficient quota in $region (Available: $AVAILABLE, Required: $CAPACITY)"
76+
return 1
77+
fi
78+
}
6879

69-
if [ -z "$MODEL_INFO" ]; then
70-
echo "❌ ERROR: No quota information found for model: $MODEL in location: $LOCATION for model type: $MODEL_TYPE."
71-
exit 1
80+
# Try user-provided region
81+
if check_quota "$LOCATION"; then
82+
exit 0
7283
fi
7384

74-
if [ -n "$MODEL_INFO" ]; then
75-
CURRENT_VALUE=$(echo "$MODEL_INFO" | awk -F': ' '/"currentvalue"/ {print $2}' | tr -d ',' | tr -d ' ')
76-
LIMIT=$(echo "$MODEL_INFO" | awk -F': ' '/"limit"/ {print $2}' | tr -d ',' | tr -d ' ')
77-
78-
CURRENT_VALUE=${CURRENT_VALUE:-0}
79-
LIMIT=${LIMIT:-0}
85+
# Try fallback regions
86+
REMAINING_REGIONS=()
87+
for region in "${ALL_REGIONS[@]}"; do
88+
if [[ "$region" != "$LOCATION" ]]; then
89+
REMAINING_REGIONS+=("$region")
90+
fi
91+
done
8092

81-
CURRENT_VALUE=$(echo "$CURRENT_VALUE" | cut -d'.' -f1)
82-
LIMIT=$(echo "$LIMIT" | cut -d'.' -f1)
93+
echo "🔁 Trying fallback regions for available quota..."
8394

84-
AVAILABLE=$((LIMIT - CURRENT_VALUE))
85-
echo "✅ Model available - Model: $MODEL_TYPE | Used: $CURRENT_VALUE | Limit: $LIMIT | Available: $AVAILABLE"
95+
for region in "${REMAINING_REGIONS[@]}"; do
96+
if check_quota "$region"; then
97+
echo "🚫 Deployment cannot proceed because the original region '$LOCATION' lacks sufficient quota."
98+
echo "➡️ You can retry using the available region: '$region'"
99+
echo "🔧 To proceed, update the 'AZURE_OPENAI_LOCATION' value in the 'main.bicepparam' file, then run:"
100+
echo " azd env set AZURE_OPENAI_LOCATION '$region'"
101+
exit 1
102+
fi
103+
done
86104

87-
if [ "$AVAILABLE" -lt "$CAPACITY" ]; then
88-
echo "❌ ERROR: Insufficient quota for model: $MODEL in location: $LOCATION. Available: $AVAILABLE, Requested: $CAPACITY."
89-
exit 1
90-
else
91-
echo "✅ Sufficient quota for model: $MODEL in location: $LOCATION. Available: $AVAILABLE, Requested: $CAPACITY."
92-
fi
93-
fi
105+
echo "❌ ERROR: No available quota found in any of the fallback regions."
106+
exit 1

0 commit comments

Comments
 (0)