Skip to content

Commit 5604868

Browse files
multi model check quota script
1 parent 1ec9c09 commit 5604868

File tree

6 files changed

+806
-0
lines changed

6 files changed

+806
-0
lines changed

azure.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ metadata:
77
88

99
hooks:
10+
preprovision:
11+
posix:
12+
shell: sh
13+
run: >
14+
chmod u+r+x ./infra/scripts/validate_model_deployment_quota.sh; chmod u+r+x ./infra/scripts/validate_model_quota.sh; ./infra/scripts/validate_model_deployment_quota.sh --SubscriptionId "$AZURE_SUBSCRIPTION_ID" --Location "${AZURE_ENV_OPENAI_LOCATION:-japaneast}" --ModelsParameter "aiModelDeployments"
15+
interactive: true
16+
continueOnError: false
17+
18+
windows:
19+
shell: pwsh
20+
run: >
21+
$location = if ($env:AZURE_ENV_OPENAI_LOCATION) { $env:AZURE_ENV_OPENAI_LOCATION } else { "uksouth" };
22+
./infra/scripts/validate_model_deployment_quota.ps1 -SubscriptionId $env:AZURE_SUBSCRIPTION_ID -Location $location -ModelsParameter "aiModelDeployments"
23+
interactive: true
24+
continueOnError: false
25+
1026
postprovision:
1127
windows:
1228
run: |

infra/main.parameters.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"aiModelDeployments": {
6+
"value": [
7+
{
8+
"name": "gpt-4o-mini",
9+
"model": {
10+
"name": "gpt-4o-mini",
11+
"version": "2025-01-01-preview",
12+
"format": "OpenAI"
13+
},
14+
"sku": {
15+
"name": "GlobalStandard",
16+
"capacity": 200
17+
}
18+
},
19+
{
20+
"name": "text-embedding-ada-002",
21+
"model": {
22+
"name": "text-embedding-ada-002",
23+
"format": "OpenAI"
24+
},
25+
"sku": {
26+
"name": "Standard",
27+
"capacity": 80
28+
}
29+
}
30+
]
31+
}
32+
}
33+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
param (
2+
[string]$SubscriptionId,
3+
[string]$Location,
4+
[string]$ModelsParameter
5+
)
6+
7+
$AiFoundryName = $env:AZURE_AIFOUNDRY_NAME
8+
$ResourceGroup = $env:AZURE_RESOURCE_GROUP
9+
10+
# Validate required parameters
11+
$MissingParams = @()
12+
if (-not $SubscriptionId) { $MissingParams += "SubscriptionId" }
13+
if (-not $Location) { $MissingParams += "Location" }
14+
if (-not $ModelsParameter) { $MissingParams += "ModelsParameter" }
15+
16+
if ($MissingParams.Count -gt 0) {
17+
Write-Error "❌ ERROR: Missing required parameters: $($MissingParams -join ', ')"
18+
exit 1
19+
}
20+
21+
# Check Azure login
22+
try {
23+
$accountCheck = az account show --output none 2>$null
24+
if ($LASTEXITCODE -ne 0) {
25+
Write-Error "❌ ERROR: You are not logged in to Azure CLI. Please run 'az login'."
26+
exit 1
27+
}
28+
} catch {
29+
Write-Error "❌ ERROR: Failed to verify Azure login."
30+
exit 1
31+
}
32+
33+
# Load model deployments from parameter file
34+
$JsonContent = Get-Content -Path "./infra/main.parameters.json" -Raw | ConvertFrom-Json
35+
$availableKeys = $JsonContent.parameters.PSObject.Properties.Name
36+
37+
if (-not $JsonContent.parameters.$ModelsParameter) {
38+
Write-Error "❌ ERROR: '$ModelsParameter' not found in main.parameters.json"
39+
Write-Host "Available Parameters: $($availableKeys -join ', ')"
40+
exit 1
41+
}
42+
43+
$aiModelDeployments = $JsonContent.parameters.$ModelsParameter.value
44+
45+
if (-not $aiModelDeployments -or $aiModelDeployments.Count -lt 2) {
46+
Write-Error "❌ ERROR: Expected at least 2 model deployments in '$ModelsParameter'"
47+
exit 1
48+
}
49+
50+
Write-Host "ℹ️ Loaded AI model deployments from main.parameters.json"
51+
$aiModelDeployments | ConvertTo-Json -Depth 10 | Write-Host
52+
53+
# Extract both model configs
54+
$gpt4o = $aiModelDeployments | Where-Object { $_.model.name -like "gpt-4o*" }
55+
$embed = $aiModelDeployments | Where-Object { $_.model.name -like "text-embedding-ada-002" }
56+
57+
if (-not $gpt4o -or -not $embed) {
58+
Write-Error "❌ ERROR: Could not find both gpt-4o and text-embedding-ada-002 models."
59+
exit 1
60+
}
61+
62+
$GPT4O_Name = if ($env:AZURE_ENV_MODEL_NAME) { $env:AZURE_ENV_MODEL_NAME } else { $gpt4o.model.name }
63+
$GPT4O_Capacity = if ($env:AZURE_ENV_MODEL_CAPACITY) { $env:AZURE_ENV_MODEL_CAPACITY } else { $gpt4o.sku.capacity }
64+
$GPT4O_DeploymentType = if ($env:AZURE_ENV_MODEL_DEPLOYMENT_TYPE) { $env:AZURE_ENV_MODEL_DEPLOYMENT_TYPE } else { $gpt4o.sku.name }
65+
66+
$Embedding_Name = if ($env:AZURE_ENV_EMBEDDING_MODEL_NAME) { $env:AZURE_ENV_EMBEDDING_MODEL_NAME } else { $embed.model.name }
67+
$Embedding_Capacity = if ($env:AZURE_ENV_EMBEDDING_MODEL_CAPACITY) { $env:AZURE_ENV_EMBEDDING_MODEL_CAPACITY } else { $embed.sku.capacity }
68+
$Embedding_DeploymentType = $embed.sku.name
69+
70+
# Optional: Check if already deployed
71+
if (-not $AiFoundryName -and $ResourceGroup) {
72+
$AiFoundryName = az cognitiveservices account list `
73+
--resource-group $ResourceGroup `
74+
--query "sort_by([?kind=='AIServices'], &name)[0].name" `
75+
-o tsv 2>$null
76+
}
77+
78+
if ($AiFoundryName -and $ResourceGroup) {
79+
$existing = az cognitiveservices account show `
80+
--name $AiFoundryName `
81+
--resource-group $ResourceGroup `
82+
--query "name" --output tsv 2>$null
83+
84+
if ($existing) {
85+
azd env set AZURE_AIFOUNDRY_NAME $existing | Out-Null
86+
87+
$deployedModelsOutput = az cognitiveservices account deployment list `
88+
--name $AiFoundryName `
89+
--resource-group $ResourceGroup `
90+
--query "[].name" --output tsv 2>$null
91+
92+
$deployedModels = @()
93+
if ($deployedModelsOutput -is [string]) {
94+
$deployedModels += $deployedModelsOutput
95+
} elseif ($deployedModelsOutput) {
96+
$deployedModels = $deployedModelsOutput -split "`r?`n"
97+
}
98+
99+
$missingDeployments = @($gpt4o.name, $embed.name) | Where-Object { $_ -notin $deployedModels }
100+
101+
if ($missingDeployments.Count -eq 0) {
102+
Write-Host "⏭️ All models already deployed in AI Foundry '$AiFoundryName'. Skipping validation."
103+
exit 0
104+
} else {
105+
Write-Host "🔍 Missing models: $($missingDeployments -join ', ')"
106+
}
107+
}
108+
}
109+
110+
# Set subscription and call inner script
111+
az account set --subscription $SubscriptionId
112+
Write-Host "🎯 Active Subscription: $(az account show --query '[name, id]' --output tsv)"
113+
114+
# ✅ CALL INNER SCRIPT ONCE with all values together
115+
& .\infra\scripts\validate_model_quota.ps1 `
116+
-Location $Location `
117+
-GPT4O_Name $GPT4O_Name `
118+
-GPT4O_Capacity $GPT4O_Capacity `
119+
-GPT4O_DeploymentType $GPT4O_DeploymentType `
120+
-Embedding_Name $Embedding_Name `
121+
-Embedding_Capacity $Embedding_Capacity `
122+
-Embedding_DeploymentType $Embedding_DeploymentType
123+
124+
$exitCode = $LASTEXITCODE
125+
if ($exitCode -ne 0) {
126+
Write-Error "❌ ERROR: Quota validation failed."
127+
exit 1
128+
} else {
129+
Write-Host "✅ All model deployments passed quota validation successfully."
130+
exit 0
131+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/bin/bash
2+
3+
SUBSCRIPTION_ID=""
4+
LOCATION=""
5+
MODELS_PARAMETER=""
6+
7+
while [[ $# -gt 0 ]]; do
8+
case "$1" in
9+
--SubscriptionId)
10+
SUBSCRIPTION_ID="$2"
11+
shift 2
12+
;;
13+
--Location)
14+
LOCATION="$2"
15+
shift 2
16+
;;
17+
--ModelsParameter)
18+
MODELS_PARAMETER="$2"
19+
shift 2
20+
;;
21+
*)
22+
echo "❌ ERROR: Unknown option: $1"
23+
exit 1
24+
;;
25+
esac
26+
done
27+
28+
AIFOUNDRY_NAME="${AZURE_AIFOUNDRY_NAME}"
29+
RESOURCE_GROUP="${AZURE_RESOURCE_GROUP}"
30+
31+
# Validate required parameters
32+
MISSING_PARAMS=()
33+
[[ -z "$SUBSCRIPTION_ID" ]] && MISSING_PARAMS+=("SubscriptionId")
34+
[[ -z "$LOCATION" ]] && MISSING_PARAMS+=("Location")
35+
[[ -z "$MODELS_PARAMETER" ]] && MISSING_PARAMS+=("ModelsParameter")
36+
37+
if [[ ${#MISSING_PARAMS[@]} -ne 0 ]]; then
38+
echo "❌ ERROR: Missing required parameters: ${MISSING_PARAMS[*]}"
39+
echo "Usage: $0 --SubscriptionId <SUBSCRIPTION_ID> --Location <LOCATION> --ModelsParameter <MODELS_PARAMETER>"
40+
exit 1
41+
fi
42+
43+
# Check Azure login
44+
if ! az account show > /dev/null 2>&1; then
45+
echo "❌ ERROR: You are not logged in to Azure CLI. Run 'az login'."
46+
exit 1
47+
fi
48+
49+
# Load models from parameters file
50+
model_json=$(jq -c ".parameters.$MODELS_PARAMETER.value[]" ./infra/main.parameters.json 2>/dev/null)
51+
if [[ $? -ne 0 || -z "$model_json" ]]; then
52+
echo "❌ ERROR: '$MODELS_PARAMETER' not found in main.parameters.json"
53+
exit 1
54+
fi
55+
56+
echo "ℹ️ Loaded AI model deployments:"
57+
echo "$model_json" | jq
58+
59+
gpt4o=$(echo "$model_json" | jq -c 'select(.model.name | test("gpt-4o"))' | head -n1)
60+
embedding=$(echo "$model_json" | jq -c 'select(.model.name == "text-embedding-ada-002")' | head -n1)
61+
62+
if [[ -z "$gpt4o" || -z "$embedding" ]]; then
63+
echo "❌ ERROR: Both gpt-4o and text-embedding-ada-002 must be present."
64+
exit 1
65+
fi
66+
67+
GPT4O_NAME="${AZURE_ENV_MODEL_NAME:-$(echo "$gpt4o" | jq -r '.model.name')}"
68+
GPT4O_CAPACITY="${AZURE_ENV_MODEL_CAPACITY:-$(echo "$gpt4o" | jq -r '.sku.capacity')}"
69+
GPT4O_TYPE="${AZURE_ENV_MODEL_DEPLOYMENT_TYPE:-$(echo "$gpt4o" | jq -r '.sku.name')}"
70+
71+
EMBED_NAME="${AZURE_ENV_EMBEDDING_MODEL_NAME:-$(echo "$embedding" | jq -r '.model.name')}"
72+
EMBED_CAPACITY="${AZURE_ENV_EMBEDDING_MODEL_CAPACITY:-$(echo "$embedding" | jq -r '.sku.capacity')}"
73+
EMBED_TYPE="${AZURE_ENV_EMBEDDING_MODEL_DEPLOYMENT_TYPE:-$(echo "$embedding" | jq -r '.sku.name')}"
74+
75+
# Try to discover AI Foundry if not provided
76+
if [[ -z "$AIFOUNDRY_NAME" && -n "$RESOURCE_GROUP" ]]; then
77+
AIFOUNDRY_NAME=$(az cognitiveservices account list \
78+
--resource-group "$RESOURCE_GROUP" \
79+
--query "sort_by([?kind=='AIServices'], &name)[0].name" -o tsv 2>/dev/null)
80+
fi
81+
82+
if [[ -n "$AIFOUNDRY_NAME" && -n "$RESOURCE_GROUP" ]]; then
83+
existing=$(az cognitiveservices account show \
84+
--name "$AIFOUNDRY_NAME" \
85+
--resource-group "$RESOURCE_GROUP" \
86+
--query "name" -o tsv 2>/dev/null)
87+
88+
if [[ -n "$existing" ]]; then
89+
azd env set AZURE_AIFOUNDRY_NAME "$existing" > /dev/null
90+
91+
deployedModels=$(az cognitiveservices account deployment list \
92+
--name "$AIFOUNDRY_NAME" \
93+
--resource-group "$RESOURCE_GROUP" \
94+
--query "[].name" -o tsv 2>/dev/null)
95+
96+
missing_models=()
97+
for model in "$GPT4O_NAME" "$EMBED_NAME"; do
98+
if ! grep -qw "$model" <<< "$deployedModels"; then
99+
missing_models+=("$model")
100+
fi
101+
done
102+
103+
if [[ ${#missing_models[@]} -eq 0 ]]; then
104+
echo "⏭️ All models already deployed in AI Foundry '$AIFOUNDRY_NAME'. Skipping quota validation."
105+
exit 0
106+
else
107+
echo "🔍 Missing model deployments: ${missing_models[*]}"
108+
fi
109+
fi
110+
fi
111+
112+
# Proceed with quota validation
113+
az account set --subscription "$SUBSCRIPTION_ID"
114+
echo "🎯 Active Subscription: $(az account show --query '[name, id]' --output tsv)"
115+
116+
./infra/scripts/validate_model_quota.sh \
117+
--location "$LOCATION" \
118+
--GPT4O_Name "$GPT4O_NAME" \
119+
--GPT4O_Capacity "$GPT4O_CAPACITY" \
120+
--GPT4O_DeploymentType "$GPT4O_TYPE" \
121+
--Embedding_Name "$EMBED_NAME" \
122+
--Embedding_Capacity "$EMBED_CAPACITY" \
123+
--Embedding_DeploymentType "$EMBED_TYPE"
124+
125+
exit_code=$?
126+
if [[ $exit_code -ne 0 ]]; then
127+
echo "❌ ERROR: Quota validation failed."
128+
exit 1
129+
else
130+
echo "✅ All model deployments passed quota validation successfully."
131+
exit 0
132+
fi

0 commit comments

Comments
 (0)