From 35149fa689062b194d24ecd16d71a60b8ff5f39f Mon Sep 17 00:00:00 2001 From: Priyanka-Microsoft Date: Tue, 10 Jun 2025 18:26:27 +0530 Subject: [PATCH 1/2] checking for user region only at first place then fallback region --- scripts/validate_model_deployment_quota.ps1 | 53 +++++++++-- scripts/validate_model_deployment_quota.sh | 98 +++++++++++++-------- scripts/validate_model_quota.ps1 | 85 ++++++++++-------- scripts/validate_model_quota.sh | 52 ++++++----- 4 files changed, 185 insertions(+), 103 deletions(-) diff --git a/scripts/validate_model_deployment_quota.ps1 b/scripts/validate_model_deployment_quota.ps1 index 007442f..57b8396 100644 --- a/scripts/validate_model_deployment_quota.ps1 +++ b/scripts/validate_model_deployment_quota.ps1 @@ -4,17 +4,19 @@ param ( [string]$ModelsParameter ) -# Verify all required parameters are provided +# Read from environment variables (do not pass in azure.yaml) +$AiServiceName = $env:AZURE_AISERVICE_NAME +$ResourceGroup = $env:AZURE_RESOURCE_GROUP + +# Validate required parameters $MissingParams = @() if (-not $SubscriptionId) { $MissingParams += "subscription" } - if (-not $Location) { $MissingParams += "location" } - if (-not $ModelsParameter) { $MissingParams += "models-parameter" } @@ -25,20 +27,56 @@ if ($MissingParams.Count -gt 0) { exit 1 } +# Load main.parameters.json $JsonContent = Get-Content -Path "./infra/main.parameters.json" -Raw | ConvertFrom-Json - if (-not $JsonContent) { Write-Error "❌ ERROR: Failed to parse main.parameters.json. Ensure the JSON file is valid." exit 1 } $aiModelDeployments = $JsonContent.parameters.$ModelsParameter.value - if (-not $aiModelDeployments -or -not ($aiModelDeployments -is [System.Collections.IEnumerable])) { - Write-Error "❌ ERROR: The specified property $ModelsParameter does not exist or is not an array." + Write-Error "❌ ERROR: The specified property '$ModelsParameter' does not exist or is not an array." exit 1 } +# Check if AI resource + all deployments already exist +if ($AiServiceName -and $ResourceGroup) { + $existing = az cognitiveservices account show ` + --name $AiServiceName ` + --resource-group $ResourceGroup ` + --query "name" --output tsv 2>$null + + if ($existing) { + $deployedModels = az cognitiveservices account deployment list ` + --name $AiServiceName ` + --resource-group $ResourceGroup ` + --query "[].name" --output tsv 2>$null + + $requiredDeployments = @() + foreach ($deployment in $aiModelDeployments) { + $requiredDeployments += $deployment.name + } + + $missingDeployments = @() + foreach ($required in $requiredDeployments) { + if ($deployedModels -notcontains $required) { + $missingDeployments += $required + } + } + + if ($missingDeployments.Count -eq 0) { + Write-Host "ℹ️ Azure AI service '$AiServiceName' exists and all required model deployments are provisioned." + Write-Host "⏭️ Skipping quota validation." + exit 0 + } else { + Write-Host "🔍 AI service exists, but the following model deployments are missing: $($missingDeployments -join ', ')" + Write-Host "➡️ Proceeding with quota validation for missing models..." + } + } +} + +# Start quota validation az account set --subscription $SubscriptionId Write-Host "🎯 Active Subscription: $(az account show --query '[name, id]' --output tsv)" @@ -56,8 +94,7 @@ foreach ($deployment in $aiModelDeployments) { if ($exitCode -ne 0) { if ($exitCode -eq 2) { - # Quota error already printed inside the script, exit gracefully without reprinting - exit 1 + exit 1 # already printed, graceful } Write-Error "❌ ERROR: Quota validation failed for model deployment: $name" $QuotaAvailable = $false diff --git a/scripts/validate_model_deployment_quota.sh b/scripts/validate_model_deployment_quota.sh index 3a19cfb..f36b81a 100644 --- a/scripts/validate_model_deployment_quota.sh +++ b/scripts/validate_model_deployment_quota.sh @@ -19,37 +19,66 @@ while [[ $# -gt 0 ]]; do shift 2 ;; *) - echo "Unknown option: $1" + echo "❌ ERROR: Unknown option: $1" exit 1 ;; esac done -# Verify all required parameters are provided and echo missing ones +# Validate required parameters MISSING_PARAMS=() +[[ -z "$SUBSCRIPTION_ID" ]] && MISSING_PARAMS+=("subscription") +[[ -z "$LOCATION" ]] && MISSING_PARAMS+=("location") +[[ -z "$MODELS_PARAMETER" ]] && MISSING_PARAMS+=("models-parameter") -if [[ -z "$SUBSCRIPTION_ID" ]]; then - MISSING_PARAMS+=("subscription") +if [[ ${#MISSING_PARAMS[@]} -ne 0 ]]; then + echo "❌ ERROR: Missing required parameters: ${MISSING_PARAMS[*]}" + echo "Usage: $0 --subscription --location --models-parameter " + exit 1 fi -if [[ -z "$LOCATION" ]]; then - MISSING_PARAMS+=("location") -fi +# Read from environment +AISERVICE_NAME="${AZURE_AISERVICE_NAME}" +RESOURCE_GROUP="${AZURE_RESOURCE_GROUP}" -if [[ -z "$MODELS_PARAMETER" ]]; then - MISSING_PARAMS+=("models-parameter") -fi +# Check service and deployment existence +if [[ -n "$AISERVICE_NAME" && -n "$RESOURCE_GROUP" ]]; then + existing=$(az cognitiveservices account show --name "$AISERVICE_NAME" --resource-group "$RESOURCE_GROUP" --query "name" --output tsv 2>/dev/null) + if [[ -n "$existing" ]]; then + echo "ℹ️ Found Azure AI service: $AISERVICE_NAME" -if [[ ${#MISSING_PARAMS[@]} -ne 0 ]]; then - echo "❌ ERROR: Missing required parameters: ${MISSING_PARAMS[*]}" - echo "Usage: $0 --subscription --location --models-parameter " - exit 1 + existing_deployments=$(az cognitiveservices account deployment list --name "$AISERVICE_NAME" --resource-group "$RESOURCE_GROUP" --query "[].name" --output tsv 2>/dev/null) + + # Extract required model names + required_models=$(jq -r ".parameters.$MODELS_PARAMETER.value[].name" ./infra/main.parameters.json 2>/dev/null) + + if [[ -z "$required_models" ]]; then + echo "❌ ERROR: Failed to extract required model names from main.parameters.json" + exit 1 + fi + + all_present=true + for model in $required_models; do + if ! grep -q -w "$model" <<< "$existing_deployments"; then + all_present=false + break + fi + done + + if [[ "$all_present" == "true" ]]; then + echo "✅ All required model deployments already exist in AI service '$AISERVICE_NAME'." + echo "⏭️ Skipping quota validation." + exit 0 + else + echo "🔍 AI service exists but some model deployments are missing — proceeding with quota validation." + fi + fi fi +# If we reach here, continue with normal quota checks aiModelDeployments=$(jq -c ".parameters.$MODELS_PARAMETER.value[]" ./infra/main.parameters.json) - -if [ $? -ne 0 ]; then - echo "Error: Failed to parse main.parameters.json. Ensure jq is installed and the JSON file is valid." +if [[ $? -ne 0 ]]; then + echo "❌ ERROR: Failed to parse main.parameters.json. Ensure jq is installed and the JSON is valid." exit 1 fi @@ -59,30 +88,29 @@ echo "🎯 Active Subscription: $(az account show --query '[name, id]' --output quotaAvailable=true while IFS= read -r deployment; do - name=${AZURE_ENV_MODEL_NAME:-$(echo "$deployment" | jq -r '.name')} - model=${AZURE_ENV_MODEL_NAME:-$(echo "$deployment" | jq -r '.model.name')} - type=${AZURE_ENV_MODEL_DEPLOYMENT_TYPE:-$(echo "$deployment" | jq -r '.sku.name')} - capacity=${AZURE_ENV_MODEL_CAPACITY:-$(echo "$deployment" | jq -r '.sku.capacity')} + name=${AZURE_ENV_MODEL_NAME:-$(echo "$deployment" | jq -r '.name')} + model=${AZURE_ENV_MODEL_NAME:-$(echo "$deployment" | jq -r '.model.name')} + type=${AZURE_ENV_MODEL_DEPLOYMENT_TYPE:-$(echo "$deployment" | jq -r '.sku.name')} + capacity=${AZURE_ENV_MODEL_CAPACITY:-$(echo "$deployment" | jq -r '.sku.capacity')} echo "🔍 Validating model deployment: $name ..." - ./scripts/validate_model_quota.sh --location "$LOCATION" --model "$model" --capacity $capacity --deployment-type $type + ./scripts/validate_model_quota.sh --location "$LOCATION" --model "$model" --capacity "$capacity" --deployment-type "$type" - # Check if the script failed exit_code=$? - if [ $exit_code -ne 0 ]; then - if [ $exit_code -eq 2 ]; then - # Skip printing any quota validation error — already handled inside the validation script - exit 1 - fi - echo "❌ ERROR: Quota validation failed for model deployment: $name" - quotaAvailable=false + if [[ $exit_code -ne 0 ]]; then + if [[ $exit_code -eq 2 ]]; then + # Quota validation handled inside script — stop immediately + exit 1 + fi + echo "❌ ERROR: Quota validation failed for model deployment: $name" + quotaAvailable=false fi done <<< "$(echo "$aiModelDeployments")" -if [ "$quotaAvailable" = false ]; then - echo "❌ ERROR: One or more model deployments failed validation." - exit 1 +if [[ "$quotaAvailable" = false ]]; then + echo "❌ ERROR: One or more model deployments failed validation." + exit 1 else - echo "✅ All model deployments passed quota validation successfully." - exit 0 + echo "✅ All model deployments passed quota validation successfully." + exit 0 fi diff --git a/scripts/validate_model_quota.ps1 b/scripts/validate_model_quota.ps1 index ef10596..0328e1f 100644 --- a/scripts/validate_model_quota.ps1 +++ b/scripts/validate_model_quota.ps1 @@ -5,7 +5,7 @@ param ( [int]$Capacity ) -# Verify required parameters +# Validate parameters $MissingParams = @() if (-not $Location) { $MissingParams += "location" } if (-not $Model) { $MissingParams += "model" } @@ -24,7 +24,6 @@ if ($DeploymentType -ne "Standard" -and $DeploymentType -ne "GlobalStandard") { } $ModelType = "OpenAI.$DeploymentType.$Model" - $PreferredRegions = @('australiaeast', 'eastus', 'eastus2', 'francecentral', 'japaneast', 'norwayeast', 'southindia', 'swedencentral', 'uksouth', 'westus', 'westus3') $AllResults = @() @@ -33,66 +32,76 @@ function Check-Quota { [string]$Region ) - $ModelInfoRaw = az cognitiveservices usage list --location $Region --query "[?name.value=='$ModelType']" --output json - $ModelInfo = $null - try { + $ModelInfoRaw = az cognitiveservices usage list --location $Region --query "[?name.value=='$ModelType']" --output json $ModelInfo = $ModelInfoRaw | ConvertFrom-Json + if (-not $ModelInfo) { return } + + $CurrentValue = ($ModelInfo | Where-Object { $_.name.value -eq $ModelType }).currentValue + $Limit = ($ModelInfo | Where-Object { $_.name.value -eq $ModelType }).limit + + $CurrentValue = [int]($CurrentValue -replace '\.0+$', '') + $Limit = [int]($Limit -replace '\.0+$', '') + $Available = $Limit - $CurrentValue + + return [PSCustomObject]@{ + Region = $Region + Model = $ModelType + Limit = $Limit + Used = $CurrentValue + Available = $Available + } } catch { return } +} - if (-not $ModelInfo) { - return +# First, check the user-specified region +Write-Host "`n🔍 Checking quota in the requested region '$Location'..." +$PrimaryResult = Check-Quota -Region $Location + +if ($PrimaryResult) { + $AllResults += $PrimaryResult + if ($PrimaryResult.Available -ge $Capacity) { + Write-Host "`n✅ Sufficient quota found in original region '$Location'." + exit 0 + } else { + Write-Host "`n⚠️ Insufficient quota in '$Location' (Available: $($PrimaryResult.Available), Required: $Capacity). Checking fallback regions..." } +} else { + Write-Host "`n⚠️ Could not retrieve quota info for region '$Location'. Checking fallback regions..." +} - $CurrentValue = ($ModelInfo | Where-Object { $_.name.value -eq $ModelType }).currentValue - $Limit = ($ModelInfo | Where-Object { $_.name.value -eq $ModelType }).limit - - $CurrentValue = [int]($CurrentValue -replace '\.0+$', '') - $Limit = [int]($Limit -replace '\.0+$', '') - $Available = $Limit - $CurrentValue +# Remove primary region from fallback list +$FallbackRegions = $PreferredRegions | Where-Object { $_ -ne $Location } - $script:AllResults += [PSCustomObject]@{ - Region = $Region - Model = $ModelType - Limit = $Limit - Used = $CurrentValue - Available = $Available +foreach ($region in $FallbackRegions) { + $result = Check-Quota -Region $region + if ($result) { + $AllResults += $result } } -foreach ($region in $PreferredRegions) { - Check-Quota -Region $region -} - # Display Results Table -Write-Host "\n-------------------------------------------------------------------------------------------------------------" +Write-Host "`n-------------------------------------------------------------------------------------------------------------" Write-Host "| No. | Region | Model Name | Limit | Used | Available |" Write-Host "-------------------------------------------------------------------------------------------------------------" $count = 1 foreach ($entry in $AllResults) { - $index = $PreferredRegions.IndexOf($entry.Region) + 1 $modelShort = $entry.Model.Substring($entry.Model.LastIndexOf(".") + 1) - Write-Host ("| {0,-4} | {1,-16} | {2,-35} | {3,-7} | {4,-7} | {5,-9} |" -f $index, $entry.Region, $entry.Model, $entry.Limit, $entry.Used, $entry.Available) + Write-Host ("| {0,-4} | {1,-16} | {2,-35} | {3,-7} | {4,-7} | {5,-9} |" -f $count, $entry.Region, $entry.Model, $entry.Limit, $entry.Used, $entry.Available) $count++ } Write-Host "-------------------------------------------------------------------------------------------------------------" -$EligibleRegion = $AllResults | Where-Object { $_.Region -eq $Location -and $_.Available -ge $Capacity } -if ($EligibleRegion) { - Write-Host "\n✅ Sufficient quota found in original region '$Location'." - exit 0 -} +# Suggest fallback regions +$EligibleFallbacks = $AllResults | Where-Object { $_.Region -ne $Location -and $_.Available -ge $Capacity } -$FallbackRegions = $AllResults | Where-Object { $_.Region -ne $Location -and $_.Available -ge $Capacity } - -if ($FallbackRegions.Count -gt 0) { - Write-Host "`n❌ Deployment cannot proceed because the original region '$Location' lacks sufficient quota." +if ($EligibleFallbacks.Count -gt 0) { + Write-Host "`n❌ Deployment cannot proceed in '$Location'." Write-Host "➡️ You can retry using one of the following regions with sufficient quota:`n" - - foreach ($region in $FallbackRegions) { + foreach ($region in $EligibleFallbacks) { Write-Host " • $($region.Region) (Available: $($region.Available))" } @@ -104,5 +113,5 @@ if ($FallbackRegions.Count -gt 0) { exit 2 } -Write-Error "❌ ERROR: No available quota found in any region." +Write-Error "`n❌ ERROR: No available quota found in any region." exit 1 \ No newline at end of file diff --git a/scripts/validate_model_quota.sh b/scripts/validate_model_quota.sh index b855fbf..639ce6f 100644 --- a/scripts/validate_model_quota.sh +++ b/scripts/validate_model_quota.sh @@ -7,6 +7,7 @@ CAPACITY=0 ALL_REGIONS=('australiaeast' 'eastus' 'eastus2' 'francecentral' 'japaneast' 'norwayeast' 'southindia' 'swedencentral' 'uksouth' 'westus' 'westus3') +# -------------------- Parse Args -------------------- while [[ $# -gt 0 ]]; do case "$1" in --model) @@ -26,37 +27,39 @@ while [[ $# -gt 0 ]]; do shift 2 ;; *) - echo "Unknown option: $1" + echo "❌ ERROR: Unknown option: $1" exit 1 ;; esac done -# Validate required params +# -------------------- Validate Inputs -------------------- MISSING_PARAMS=() [[ -z "$LOCATION" ]] && MISSING_PARAMS+=("location") [[ -z "$MODEL" ]] && MISSING_PARAMS+=("model") -[[ -z "$CAPACITY" ]] && MISSING_PARAMS+=("capacity") +[[ "$CAPACITY" -le 0 ]] && MISSING_PARAMS+=("capacity") if [[ ${#MISSING_PARAMS[@]} -ne 0 ]]; then - echo "❌ ERROR: Missing required parameters: ${MISSING_PARAMS[*]}" + echo "❌ ERROR: Missing or invalid parameters: ${MISSING_PARAMS[*]}" echo "Usage: $0 --location --model --capacity [--deployment-type ]" exit 1 fi if [[ "$DEPLOYMENT_TYPE" != "Standard" && "$DEPLOYMENT_TYPE" != "GlobalStandard" ]]; then - echo "❌ ERROR: Invalid deployment type: $DEPLOYMENT_TYPE. Allowed values are 'Standard' or 'GlobalStandard'." + echo "❌ ERROR: Invalid deployment type: $DEPLOYMENT_TYPE. Allowed values: 'Standard', 'GlobalStandard'." exit 1 fi MODEL_TYPE="OpenAI.$DEPLOYMENT_TYPE.$MODEL" - -declare -a FALLBACK_REGIONS=() +FALLBACK_REGIONS=() ROW_NO=1 +QUOTA_CHECKED=false +# -------------------- Output Table Header -------------------- printf "\n%-5s | %-20s | %-40s | %-10s | %-10s | %-10s\n" "No." "Region" "Model Name" "Limit" "Used" "Available" printf -- "---------------------------------------------------------------------------------------------------------------------\n" +# -------------------- Check Quota -------------------- for region in "${ALL_REGIONS[@]}"; do MODEL_INFO=$(az cognitiveservices usage list --location "$region" --query "[?name.value=='$MODEL_TYPE']" --output json 2>/dev/null) @@ -67,34 +70,39 @@ for region in "${ALL_REGIONS[@]}"; do printf "%-5s | %-20s | %-40s | %-10s | %-10s | %-10s\n" "$ROW_NO" "$region" "$MODEL_TYPE" "$LIMIT" "$CURRENT_VALUE" "$AVAILABLE" - if [[ "$region" == "$LOCATION" && "$AVAILABLE" -ge "$CAPACITY" ]]; then - echo -e "\n✅ Sufficient quota available in user-specified region: $LOCATION" - exit 0 - fi - - if [[ "$region" != "$LOCATION" && "$AVAILABLE" -ge "$CAPACITY" ]]; then + if [[ "$region" == "$LOCATION" ]]; then + QUOTA_CHECKED=true + if [[ "$AVAILABLE" -ge "$CAPACITY" ]]; then + echo -e "\n✅ Sufficient quota available in user-specified region: $LOCATION" + exit 0 + fi + elif [[ "$AVAILABLE" -ge "$CAPACITY" ]]; then FALLBACK_REGIONS+=("$region ($AVAILABLE)") fi fi - ((ROW_NO++)) done printf -- "---------------------------------------------------------------------------------------------------------------------\n" -if [[ "${#FALLBACK_REGIONS[@]}" -gt 0 ]]; then - echo -e "\n❌ Deployment cannot proceed because the original region '$LOCATION' lacks sufficient quota." - echo "➡️ You can retry using one of the following regions with sufficient quota:" - for fallback in "${FALLBACK_REGIONS[@]}"; do - echo " • $fallback" +# -------------------- Output Result -------------------- +if ! $QUOTA_CHECKED; then + echo -e "\n⚠️ Could not retrieve quota info for region: $LOCATION" +fi + +if [[ ${#FALLBACK_REGIONS[@]} -gt 0 ]]; then + echo -e "\n❌ Insufficient quota in '$LOCATION'." + echo "➡️ You may retry using one of the following fallback regions with enough quota:" + for region in "${FALLBACK_REGIONS[@]}"; do + echo " • $region" done echo -e "\n🔧 To proceed, run:" echo " azd env set AZURE_AISERVICE_LOCATION ''" - echo "📌 To confirm it's set correctly, run:" + echo "📌 To confirm, run:" echo " azd env get-value AZURE_AISERVICE_LOCATION" - echo "▶️ Once confirmed, re-run azd up to deploy the model in the new region." + echo "▶️ Then re-run: azd up" exit 2 fi -echo "❌ ERROR: No available quota found in any of the fallback regions." +echo "❌ ERROR: No region has sufficient quota for '$MODEL_TYPE'." exit 1 \ No newline at end of file From 7a60aae070fbcbf4558f9663f8354ae08e79b30c Mon Sep 17 00:00:00 2001 From: Priyanka-Microsoft Date: Tue, 10 Jun 2025 19:44:58 +0530 Subject: [PATCH 2/2] script updated --- scripts/validate_model_quota.sh | 117 ++++++++++++++++++++++---------- 1 file changed, 82 insertions(+), 35 deletions(-) diff --git a/scripts/validate_model_quota.sh b/scripts/validate_model_quota.sh index 639ce6f..2675257 100644 --- a/scripts/validate_model_quota.sh +++ b/scripts/validate_model_quota.sh @@ -51,58 +51,105 @@ if [[ "$DEPLOYMENT_TYPE" != "Standard" && "$DEPLOYMENT_TYPE" != "GlobalStandard" fi MODEL_TYPE="OpenAI.$DEPLOYMENT_TYPE.$MODEL" -FALLBACK_REGIONS=() +ALL_RESULTS=() +FALLBACK_RESULTS=() ROW_NO=1 -QUOTA_CHECKED=false -# -------------------- Output Table Header -------------------- -printf "\n%-5s | %-20s | %-40s | %-10s | %-10s | %-10s\n" "No." "Region" "Model Name" "Limit" "Used" "Available" -printf -- "---------------------------------------------------------------------------------------------------------------------\n" +# Print validating message only once +echo -e "\n🔍 Validating model deployment: $MODEL ..." -# -------------------- Check Quota -------------------- -for region in "${ALL_REGIONS[@]}"; do - MODEL_INFO=$(az cognitiveservices usage list --location "$region" --query "[?name.value=='$MODEL_TYPE']" --output json 2>/dev/null) +echo "🔍 Checking quota in the requested region '$LOCATION'..." - if [[ -n "$MODEL_INFO" && "$MODEL_INFO" != "[]" ]]; then - CURRENT_VALUE=$(echo "$MODEL_INFO" | jq -r '.[0].currentValue // 0' | cut -d'.' -f1) - LIMIT=$(echo "$MODEL_INFO" | jq -r '.[0].limit // 0' | cut -d'.' -f1) - AVAILABLE=$((LIMIT - CURRENT_VALUE)) +# -------------------- Function: Check Quota -------------------- +check_quota() { + local region="$1" + local output + output=$(az cognitiveservices usage list --location "$region" --query "[?name.value=='$MODEL_TYPE']" --output json 2>/dev/null) - printf "%-5s | %-20s | %-40s | %-10s | %-10s | %-10s\n" "$ROW_NO" "$region" "$MODEL_TYPE" "$LIMIT" "$CURRENT_VALUE" "$AVAILABLE" + if [[ -z "$output" || "$output" == "[]" ]]; then + return 2 # No data + fi - if [[ "$region" == "$LOCATION" ]]; then - QUOTA_CHECKED=true - if [[ "$AVAILABLE" -ge "$CAPACITY" ]]; then - echo -e "\n✅ Sufficient quota available in user-specified region: $LOCATION" - exit 0 - fi - elif [[ "$AVAILABLE" -ge "$CAPACITY" ]]; then - FALLBACK_REGIONS+=("$region ($AVAILABLE)") - fi + local CURRENT_VALUE + local LIMIT + CURRENT_VALUE=$(echo "$output" | jq -r '.[0].currentValue // 0' | cut -d'.' -f1) + LIMIT=$(echo "$output" | jq -r '.[0].limit // 0' | cut -d'.' -f1) + local AVAILABLE=$((LIMIT - CURRENT_VALUE)) + + ALL_RESULTS+=("$region|$LIMIT|$CURRENT_VALUE|$AVAILABLE") + + if [[ "$AVAILABLE" -ge "$CAPACITY" ]]; then + return 0 + else + return 1 + fi +} + +# -------------------- Check User-Specified Region -------------------- +check_quota "$LOCATION" +primary_status=$? + +if [[ $primary_status -eq 2 ]]; then + echo -e "\n⚠️ Could not retrieve quota info for region: '$LOCATION'." + exit 1 +fi + +if [[ $primary_status -eq 1 ]]; then + # Get available quota from ALL_RESULTS for LOCATION to use in warning + primary_entry="${ALL_RESULTS[0]}" + IFS='|' read -r _ limit used available <<< "$primary_entry" + echo -e "\n⚠️ Insufficient quota in '$LOCATION' (Available: $available, Required: $CAPACITY). Checking fallback regions..." +fi + +# -------------------- Check Fallback Regions -------------------- +for region in "${ALL_REGIONS[@]}"; do + [[ "$region" == "$LOCATION" ]] && continue + check_quota "$region" + if [[ $? -eq 0 ]]; then + FALLBACK_RESULTS+=("$region") fi - ((ROW_NO++)) done -printf -- "---------------------------------------------------------------------------------------------------------------------\n" +# -------------------- Print Results Table -------------------- +echo "" +printf "%-6s | %-18s | %-35s | %-8s | %-8s | %-9s\n" "No." "Region" "Model Name" "Limit" "Used" "Available" +printf -- "-------------------------------------------------------------------------------------------------------------\n" + +index=1 +for result in "${ALL_RESULTS[@]}"; do + IFS='|' read -r region limit used available <<< "$result" + printf "| %-4s | %-16s | %-33s | %-7s | %-7s | %-9s |\n" "$index" "$region" "$MODEL_TYPE" "$limit" "$used" "$available" + ((index++)) +done +printf -- "-------------------------------------------------------------------------------------------------------------\n" # -------------------- Output Result -------------------- -if ! $QUOTA_CHECKED; then - echo -e "\n⚠️ Could not retrieve quota info for region: $LOCATION" +if [[ $primary_status -eq 0 ]]; then + echo -e "\n✅ Sufficient quota found in original region '$LOCATION'." + exit 0 fi -if [[ ${#FALLBACK_REGIONS[@]} -gt 0 ]]; then - echo -e "\n❌ Insufficient quota in '$LOCATION'." - echo "➡️ You may retry using one of the following fallback regions with enough quota:" - for region in "${FALLBACK_REGIONS[@]}"; do - echo " • $region" +if [[ ${#FALLBACK_RESULTS[@]} -gt 0 ]]; then + echo -e "\n❌ Deployment cannot proceed in '$LOCATION'." + echo "➡️ You can retry using one of the following regions with sufficient quota:" + echo "" + for region in "${FALLBACK_RESULTS[@]}"; do + for result in "${ALL_RESULTS[@]}"; do + IFS='|' read -r rgn _ _ avail <<< "$result" + if [[ "$rgn" == "$region" ]]; then + echo " • $region (Available: $avail)" + break + fi + done done + echo -e "\n🔧 To proceed, run:" echo " azd env set AZURE_AISERVICE_LOCATION ''" - echo "📌 To confirm, run:" + echo "📌 To confirm it's set correctly, run:" echo " azd env get-value AZURE_AISERVICE_LOCATION" - echo "▶️ Then re-run: azd up" + echo "▶️ Once confirmed, re-run azd up to deploy the model in the new region." exit 2 fi -echo "❌ ERROR: No region has sufficient quota for '$MODEL_TYPE'." -exit 1 \ No newline at end of file +echo -e "\n❌ ERROR: No available quota found in any region." +exit 1