Skip to content

Commit 449e6b2

Browse files
quota auto validation
1 parent 2952b2a commit 449e6b2

File tree

5 files changed

+329
-2
lines changed

5 files changed

+329
-2
lines changed

azure.yaml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
1-
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
21
name: multi-agent-custom-automation-engine-solution-accelerator
32
metadata:
4-
3+
4+
5+
hooks:
6+
preprovision:
7+
posix:
8+
shell: sh
9+
run: >
10+
./infra/scripts/validate_model_deployment_quota.sh --subscription "$AZURE_SUBSCRIPTION_ID" --location "${AZURE_OPENAI_LOCATION:-swedencentral}" --models-parameter "aiModelDeployments"
11+
interactive: false
12+
continueOnError: false
13+
14+
windows:
15+
shell: pwsh
16+
run: >
17+
$location = if ($env:AZURE_OPENAI_LOCATION) { $env:AZURE_OPENAI_LOCATION } else { "swedencentral" };
18+
./infra/scripts/validate_model_deployment_quotas.ps1 -SubscriptionId $env:AZURE_SUBSCRIPTION_ID -Location $location -ModelsParameter "aiModelDeployments"
19+
interactive: false
20+
continueOnError: false
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/bin/bash
2+
3+
SUBSCRIPTION_ID=""
4+
LOCATION=""
5+
MODELS_PARAMETER=""
6+
7+
while [[ $# -gt 0 ]]; do
8+
case "$1" in
9+
--subscription)
10+
SUBSCRIPTION_ID="$2"
11+
shift 2
12+
;;
13+
--location)
14+
LOCATION="$2"
15+
shift 2
16+
;;
17+
--models-parameter)
18+
MODELS_PARAMETER="$2"
19+
shift 2
20+
;;
21+
*)
22+
echo "Unknown option: $1"
23+
exit 1
24+
;;
25+
esac
26+
done
27+
28+
# Verify all required parameters are provided and echo missing ones
29+
MISSING_PARAMS=()
30+
31+
if [[ -z "$SUBSCRIPTION_ID" ]]; then
32+
MISSING_PARAMS+=("subscription")
33+
fi
34+
35+
if [[ -z "$LOCATION" ]]; then
36+
MISSING_PARAMS+=("location")
37+
fi
38+
39+
if [[ -z "$MODELS_PARAMETER" ]]; then
40+
MISSING_PARAMS+=("models-parameter")
41+
fi
42+
43+
if [[ ${#MISSING_PARAMS[@]} -ne 0 ]]; then
44+
echo "❌ ERROR: Missing required parameters: ${MISSING_PARAMS[*]}"
45+
echo "Usage: $0 --subscription <SUBSCRIPTION_ID> --location <LOCATION> --models-parameter <MODELS_PARAMETER>"
46+
exit 1
47+
fi
48+
49+
aiModelDeployments=$(jq -c ".parameters.$MODELS_PARAMETER.value[]" ./infra/main.parameters.json)
50+
51+
if [ $? -ne 0 ]; then
52+
echo "Error: Failed to parse main.parameters.json. Ensure jq is installed and the JSON file is valid."
53+
exit 1
54+
fi
55+
56+
az account set --subscription "$SUBSCRIPTION_ID"
57+
echo "🎯 Active Subscription: $(az account show --query '[name, id]' --output tsv)"
58+
59+
quotaAvailable=true
60+
61+
while IFS= read -r deployment; do
62+
name=$(echo "$deployment" | jq -r '.name')
63+
model=$(echo "$deployment" | jq -r '.model.name')
64+
type=$(echo "$deployment" | jq -r '.sku.name')
65+
capacity=$(echo "$deployment" | jq -r '.sku.capacity')
66+
67+
echo "🔍 Validating model deployment: $name ..."
68+
./infra/scripts/validate_model_quota.sh --location "$LOCATION" --model "$model" --capacity $capacity --deployment-type $type
69+
70+
# Check if the script failed
71+
if [ $? -ne 0 ]; then
72+
echo "❌ ERROR: Quota validation failed for model deployment: $name"
73+
quotaAvailable=false
74+
fi
75+
done <<< "$(echo "$aiModelDeployments")"
76+
77+
if [ "$quotaAvailable" = false ]; then
78+
echo "❌ ERROR: One or more model deployments failed validation."
79+
exit 1
80+
else
81+
echo "✅ All model deployments passed quota validation successfully."
82+
exit 0
83+
fi
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
param (
2+
[string]$SubscriptionId,
3+
[string]$Location,
4+
[string]$ModelsParameter
5+
)
6+
7+
# Verify all required parameters are provided
8+
$MissingParams = @()
9+
10+
if (-not $SubscriptionId) {
11+
$MissingParams += "subscription"
12+
}
13+
14+
if (-not $Location) {
15+
$MissingParams += "location"
16+
}
17+
18+
if (-not $ModelsParameter) {
19+
$MissingParams += "models-parameter"
20+
}
21+
22+
if ($MissingParams.Count -gt 0) {
23+
Write-Error "❌ ERROR: Missing required parameters: $($MissingParams -join ', ')"
24+
Write-Host "Usage: .\validate_model_deployment_quotas.ps1 -SubscriptionId <SUBSCRIPTION_ID> -Location <LOCATION> -ModelsParameter <MODELS_PARAMETER>"
25+
exit 1
26+
}
27+
28+
$JsonContent = Get-Content -Path "./infra/main.parameters.json" -Raw | ConvertFrom-Json
29+
30+
if (-not $JsonContent) {
31+
Write-Error "❌ ERROR: Failed to parse main.parameters.json. Ensure the JSON file is valid."
32+
exit 1
33+
}
34+
35+
$aiModelDeployments = $JsonContent.parameters.$ModelsParameter.value
36+
37+
if (-not $aiModelDeployments -or -not ($aiModelDeployments -is [System.Collections.IEnumerable])) {
38+
Write-Error "❌ ERROR: The specified property $ModelsParameter does not exist or is not an array."
39+
exit 1
40+
}
41+
42+
az account set --subscription $SubscriptionId
43+
Write-Host "🎯 Active Subscription: $(az account show --query '[name, id]' --output tsv)"
44+
45+
$QuotaAvailable = $true
46+
47+
foreach ($deployment in $aiModelDeployments) {
48+
$name = $deployment.name
49+
$model = $deployment.model.name
50+
$type = $deployment.sku.name
51+
$capacity = $deployment.sku.capacity
52+
53+
Write-Host "🔍 Validating model deployment: $name ..."
54+
& .\infra\scripts\validate_model_quota.ps1 -Location $Location -Model $model -Capacity $capacity -DeploymentType $type
55+
56+
# Check if the script failed
57+
if ($LASTEXITCODE -ne 0) {
58+
Write-Error "❌ ERROR: Quota validation failed for model deployment: $name"
59+
$QuotaAvailable = $false
60+
}
61+
}
62+
63+
if (-not $QuotaAvailable) {
64+
Write-Error "❌ ERROR: One or more model deployments failed validation."
65+
exit 1
66+
} else {
67+
Write-Host "✅ All model deployments passed quota validation successfully."
68+
exit 0
69+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
param (
2+
[string]$Location,
3+
[string]$Model,
4+
[string]$DeploymentType = "Standard",
5+
[int]$Capacity
6+
)
7+
8+
# Verify all required parameters are provided
9+
$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+
}
26+
27+
if ($MissingParams.Count -gt 0) {
28+
Write-Error "❌ ERROR: Missing required parameters: $($MissingParams -join ', ')"
29+
Write-Host "Usage: .\validate_model_quota.ps1 -Location <LOCATION> -Model <MODEL> -Capacity <CAPACITY> [-DeploymentType <DEPLOYMENT_TYPE>]"
30+
exit 1
31+
}
32+
33+
if ($DeploymentType -ne "Standard" -and $DeploymentType -ne "GlobalStandard") {
34+
Write-Error "❌ ERROR: Invalid deployment type: $DeploymentType. Allowed values are 'Standard' or 'GlobalStandard'."
35+
exit 1
36+
}
37+
38+
$ModelType = "OpenAI.$DeploymentType.$Model"
39+
40+
Write-Host "🔍 Checking quota for $ModelType in $Location ..."
41+
42+
# Get model quota information
43+
$ModelInfo = az cognitiveservices usage list --location $Location --query "[?name.value=='$ModelType']" --output json | ConvertFrom-Json
44+
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+
}
49+
50+
if ($ModelInfo) {
51+
$CurrentValue = ($ModelInfo | Where-Object { $_.name.value -eq $ModelType }).currentValue
52+
$Limit = ($ModelInfo | Where-Object { $_.name.value -eq $ModelType }).limit
53+
54+
$CurrentValue = [int]($CurrentValue -replace '\.0+$', '') # Remove decimals
55+
$Limit = [int]($Limit -replace '\.0+$', '') # Remove decimals
56+
57+
$Available = $Limit - $CurrentValue
58+
Write-Host "✅ Model available - Model: $ModelType | Used: $CurrentValue | Limit: $Limit | Available: $Available"
59+
60+
if ($Available -lt $Capacity) {
61+
Write-Error "❌ ERROR: Insufficient quota for model: $Model in location: $Location. Available: $Available, Requested: $Capacity."
62+
exit 1
63+
} else {
64+
Write-Host "✅ Sufficient quota for model: $Model in location: $Location. Available: $Available, Requested: $Capacity."
65+
}
66+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/bin/bash
2+
3+
LOCATION=""
4+
MODEL=""
5+
DEPLOYMENT_TYPE="Standard"
6+
CAPACITY=0
7+
8+
while [[ $# -gt 0 ]]; do
9+
case "$1" in
10+
--model)
11+
MODEL="$2"
12+
shift 2
13+
;;
14+
--capacity)
15+
CAPACITY="$2"
16+
shift 2
17+
;;
18+
--deployment-type)
19+
DEPLOYMENT_TYPE="$2"
20+
shift 2
21+
;;
22+
--location)
23+
LOCATION="$2"
24+
shift 2
25+
;;
26+
*)
27+
echo "Unknown option: $1"
28+
exit 1
29+
;;
30+
esac
31+
done
32+
33+
# Verify all required parameters are provided and echo missing ones
34+
MISSING_PARAMS=()
35+
36+
if [[ -z "$LOCATION" ]]; then
37+
MISSING_PARAMS+=("location")
38+
fi
39+
40+
if [[ -z "$MODEL" ]]; then
41+
MISSING_PARAMS+=("model")
42+
fi
43+
44+
if [[ -z "$CAPACITY" ]]; then
45+
MISSING_PARAMS+=("capacity")
46+
fi
47+
48+
if [[ -z "$DEPLOYMENT_TYPE" ]]; then
49+
MISSING_PARAMS+=("deployment-type")
50+
fi
51+
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
57+
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
62+
63+
MODEL_TYPE="OpenAI.$DEPLOYMENT_TYPE.$MODEL"
64+
65+
echo "🔍 Checking quota for $MODEL_TYPE in $LOCATION ..."
66+
67+
MODEL_INFO=$(az cognitiveservices usage list --location "$LOCATION" --query "[?name.value=='$MODEL_TYPE']" --output json | tr '[:upper:]' '[:lower:]')
68+
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
72+
fi
73+
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}
80+
81+
CURRENT_VALUE=$(echo "$CURRENT_VALUE" | cut -d'.' -f1)
82+
LIMIT=$(echo "$LIMIT" | cut -d'.' -f1)
83+
84+
AVAILABLE=$((LIMIT - CURRENT_VALUE))
85+
echo "✅ Model available - Model: $MODEL_TYPE | Used: $CURRENT_VALUE | Limit: $LIMIT | Available: $AVAILABLE"
86+
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

0 commit comments

Comments
 (0)