Skip to content

Commit 2cf9646

Browse files
Add documentation for Azure account setup and quota checks; include scripts for quota verification
1 parent 97c7c6d commit 2cf9646

6 files changed

Lines changed: 365 additions & 2 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ Follow the quick deploy steps on the deployment guide to deploy this solution to
7878
<br/>
7979

8080
> ⚠️ **Important: Check Azure OpenAI Quota Availability**
81-
<br/>To ensure sufficient quota is available in your subscription, please follow [quota check instructions guide](./docs/QuotaCheck.md) before you deploy the solution.
81+
<br/>To ensure sufficient quota is available in your subscription, please follow [quota check instructions guide](./content-gen/docs/QuotaCheck.md) before you deploy the solution.
8282
8383
<br/>
8484

8585
### Prerequisites and costs
8686

87-
To deploy this solution accelerator, ensure you have access to an [Azure subscription](https://azure.microsoft.com/free/) with the necessary permissions to create **resource groups, resources, app registrations, and assign roles at the resource group level**. This should include Contributor role at the subscription level and Role Based Access Control role on the subscription and/or resource group level. Follow the steps in [Azure Account Set Up](./docs/AzureAccountSetUp.md).
87+
To deploy this solution accelerator, ensure you have access to an [Azure subscription](https://azure.microsoft.com/free/) with the necessary permissions to create **resource groups, resources, app registrations, and assign roles at the resource group level**. This should include Contributor role at the subscription level and Role Based Access Control role on the subscription and/or resource group level. Follow the steps in [Azure Account Set Up](./content-gen/docs/AzureAccountSetUp.md).
8888

8989
Check the [Azure Products by Region](https://azure.microsoft.com/en-us/explore/global-infrastructure/products-by-region/?products=all&regions=all) page and select a **region** where the following services are available.
9090

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## Azure account setup
2+
3+
1. Sign up for a [free Azure account](https://azure.microsoft.com/free/) and create an Azure Subscription.
4+
2. Check that you have the necessary permissions:
5+
* Your Azure account must have `Microsoft.Authorization/roleAssignments/write` permissions, such as [Role Based Access Control Administrator](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#role-based-access-control-administrator-preview), [User Access Administrator](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#user-access-administrator), or [Owner](https://learn.microsoft.com/azure/role-based-access-control/built-in-roles#owner).
6+
* Your Azure account also needs `Microsoft.Resources/deployments/write` permissions on the subscription level.
7+
8+
You can view the permissions for your account and subscription by following the steps below:
9+
- Navigate to the [Azure Portal](https://portal.azure.com/) and click on `Subscriptions` under 'Navigation'
10+
- Select the subscription you are using for this accelerator from the list.
11+
- If you try to search for your subscription and it does not come up, make sure no filters are selected.
12+
- Select `Access control (IAM)` and you can see the roles that are assigned to your account for this subscription.
13+
- If you want to see more information about the roles, you can go to the `Role assignments`
14+
tab and search by your account name and then click the role you want to view more information about.

content-gen/docs/QuotaCheck.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
## Check Quota Availability Before Deployment
2+
3+
Before deploying the Content Generation Solution Accelerator, **ensure sufficient quota availability** for the required models.
4+
5+
> **For Global Standard | GPT-5.1 - ensure capacity to at least 150 tokens post-deployment for optimal performance.**
6+
7+
> **For Global Standard | GPT-Image-1 - ensure capacity to at least 1 RPM (Requests Per Minute) for image generation.**
8+
9+
10+
### Login if you have not done so already
11+
```
12+
azd auth login
13+
```
14+
15+
16+
### 📌 Default Models & Capacities:
17+
```
18+
gpt-5.1:150, gpt-image-1:1
19+
```
20+
**Note:** GPT-5.1 capacity is in tokens, GPT-Image-1 capacity is in RPM (Requests Per Minute).
21+
### 📌 Default Regions:
22+
```
23+
australiaeast, centralus, eastasia, eastus, eastus2, japaneast, northeurope, southeastasia, swedencentral, uksouth, westus, westus3
24+
```
25+
### Usage Scenarios:
26+
- No parameters passed → Default models and capacities will be checked in default regions.
27+
- Only model(s) provided → The script will check for those models in the default regions.
28+
- Only region(s) provided → The script will check default models in the specified regions.
29+
- Both models and regions provided → The script will check those models in the specified regions.
30+
- `--verbose` passed → Enables detailed logging output for debugging and traceability.
31+
32+
### **Input Formats**
33+
> Use the --models, --regions, and --verbose options for parameter handling:
34+
35+
✔️ Run without parameters to check default models & regions without verbose logging:
36+
```
37+
./quota_check_params.sh
38+
```
39+
✔️ Enable verbose logging:
40+
```
41+
./quota_check_params.sh --verbose
42+
```
43+
✔️ Check specific model(s) in default regions:
44+
```
45+
./quota_check_params.sh --models gpt-5.1:150,gpt-image-1:1
46+
```
47+
✔️ Check default models in specific region(s):
48+
```
49+
./quota_check_params.sh --regions eastus,swedencentral
50+
```
51+
✔️ Passing Both models and regions:
52+
```
53+
./quota_check_params.sh --models gpt-5.1:150,gpt-image-1:1 --regions eastus,swedencentral
54+
```
55+
✔️ All parameters combined:
56+
```
57+
./quota_check_params.sh --models gpt-5.1:150,gpt-image-1:1 --regions eastus,swedencentral --verbose
58+
```
59+
60+
### **Sample Output**
61+
The final table lists regions with available quota. You can select any of these regions for deployment.
62+
63+
![quota-check-ouput](images/quota-check-output.png)
64+
65+
---
66+
### **If using Azure Portal and Cloud Shell**
67+
68+
1. Navigate to the [Azure Portal](https://portal.azure.com).
69+
2. Click on **Azure Cloud Shell** in the top right navigation menu.
70+
3. Run the appropriate command based on your requirement:
71+
72+
**To check quota for the deployment**
73+
74+
```sh
75+
curl -L -o quota_check_params.sh "https://raw.githubusercontent.com/microsoft/content-generation-solution-accelerator/main/content-gen/infra/script/quota_check_params.sh"
76+
chmod +x quota_check_params.sh
77+
./quota_check_params.sh
78+
```
79+
- Refer to [Input Formats](#input-formats) for detailed commands.
80+
81+
### **If using VS Code or Codespaces**
82+
1. Open the terminal in VS Code or Codespaces.
83+
2. If you're using VS Code, click the dropdown on the right side of the terminal window, and select `Git Bash`.
84+
![git_bash](images/git_bash.png)
85+
3. Navigate to the `content-gen/infra/script` folder where the script files are located and make the script as executable:
86+
```sh
87+
cd content-gen/infra/script
88+
chmod +x quota_check_params.sh
89+
```
90+
4. Run the appropriate script based on your requirement:
91+
92+
**To check quota for the deployment**
93+
94+
```sh
95+
./quota_check_params.sh
96+
```
97+
- Refer to [Input Formats](#input-formats) for detailed commands.
98+
99+
5. If you see the error `_bash: az: command not found_`, install Azure CLI:
100+
101+
```sh
102+
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
103+
az login
104+
```
105+
6. Rerun the script after installing Azure CLI.
29.3 KB
Loading
25.3 KB
Loading
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
#!/bin/bash
2+
# VERBOSE=false
3+
4+
MODELS=""
5+
REGIONS=""
6+
VERBOSE=false
7+
8+
while [[ $# -gt 0 ]]; do
9+
case "$1" in
10+
--models)
11+
MODELS="$2"
12+
shift 2
13+
;;
14+
--regions)
15+
REGIONS="$2"
16+
shift 2
17+
;;
18+
--verbose)
19+
VERBOSE=true
20+
shift
21+
;;
22+
*)
23+
echo "Unknown option: $1"
24+
exit 1
25+
;;
26+
esac
27+
done
28+
29+
# Fallback to defaults if not provided
30+
[[ -z "$MODELS" ]]
31+
[[ -z "$REGIONS" ]]
32+
33+
echo "Models: $MODELS"
34+
echo "Regions: $REGIONS"
35+
echo "Verbose: $VERBOSE"
36+
37+
for arg in "$@"; do
38+
if [ "$arg" = "--verbose" ]; then
39+
VERBOSE=true
40+
fi
41+
done
42+
43+
log_verbose() {
44+
if [ "$VERBOSE" = true ]; then
45+
echo "$1"
46+
fi
47+
}
48+
49+
# Default Models and Capacities for Content Generation
50+
# GPT-5.1: 150 tokens, GPT-Image-1: 1 RPM (Requests Per Minute)
51+
DEFAULT_MODEL_CAPACITY="gpt-5.1:150,gpt-image-1:1"
52+
53+
# Convert the comma-separated string into an array
54+
IFS=',' read -r -a MODEL_CAPACITY_PAIRS <<< "$DEFAULT_MODEL_CAPACITY"
55+
56+
echo "🔄 Fetching available Azure subscriptions..."
57+
SUBSCRIPTIONS=$(az account list --query "[?state=='Enabled'].{Name:name, ID:id}" --output tsv)
58+
SUB_COUNT=$(echo "$SUBSCRIPTIONS" | wc -l)
59+
60+
if [ "$SUB_COUNT" -eq 0 ]; then
61+
echo "❌ ERROR: No active Azure subscriptions found. Please log in using 'az login' and ensure you have an active subscription."
62+
exit 1
63+
elif [ "$SUB_COUNT" -eq 1 ]; then
64+
# If only one subscription, automatically select it
65+
AZURE_SUBSCRIPTION_ID=$(echo "$SUBSCRIPTIONS" | awk '{print $2}')
66+
if [ -z "$AZURE_SUBSCRIPTION_ID" ]; then
67+
echo "❌ ERROR: No active Azure subscriptions found. Please log in using 'az login' and ensure you have an active subscription."
68+
exit 1
69+
fi
70+
echo "✅ Using the only available subscription: $AZURE_SUBSCRIPTION_ID"
71+
else
72+
# If multiple subscriptions exist, prompt the user to choose one
73+
echo "Multiple subscriptions found:"
74+
echo "$SUBSCRIPTIONS" | awk '{print NR")", $1, "-", $2}'
75+
76+
while true; do
77+
echo "Enter the number of the subscription to use:"
78+
read SUB_INDEX
79+
80+
# Validate user input
81+
if [[ "$SUB_INDEX" =~ ^[0-9]+$ ]] && [ "$SUB_INDEX" -ge 1 ] && [ "$SUB_INDEX" -le "$SUB_COUNT" ]; then
82+
AZURE_SUBSCRIPTION_ID=$(echo "$SUBSCRIPTIONS" | awk -v idx="$SUB_INDEX" 'NR==idx {print $2}')
83+
echo "✅ Selected Subscription: $AZURE_SUBSCRIPTION_ID"
84+
break
85+
else
86+
echo "❌ Invalid selection. Please enter a valid number from the list."
87+
fi
88+
done
89+
fi
90+
91+
92+
# Set the selected subscription
93+
az account set --subscription "$AZURE_SUBSCRIPTION_ID"
94+
echo "🎯 Active Subscription: $(az account show --query '[name, id]' --output tsv)"
95+
96+
# Default Regions supporting GPT-5.1 and GPT-Image-1 with GlobalStandard SKU
97+
DEFAULT_REGIONS="australiaeast,centralus,eastasia,eastus,eastus2,japaneast,northeurope,southeastasia,swedencentral,uksouth,westus,westus3"
98+
IFS=',' read -r -a DEFAULT_REGION_ARRAY <<< "$DEFAULT_REGIONS"
99+
100+
# Read parameters (if any)
101+
IFS=',' read -r -a USER_PROVIDED_PAIRS <<< "$MODELS"
102+
USER_REGION="$REGIONS"
103+
104+
IS_USER_PROVIDED_PAIRS=false
105+
106+
if [ ${#USER_PROVIDED_PAIRS[@]} -lt 1 ]; then
107+
echo "No parameters provided, using default model-capacity pairs: ${MODEL_CAPACITY_PAIRS[*]}"
108+
else
109+
echo "Using provided model and capacity pairs: ${USER_PROVIDED_PAIRS[*]}"
110+
IS_USER_PROVIDED_PAIRS=true
111+
MODEL_CAPACITY_PAIRS=("${USER_PROVIDED_PAIRS[@]}")
112+
fi
113+
114+
declare -a FINAL_MODEL_NAMES
115+
declare -a FINAL_CAPACITIES
116+
declare -a TABLE_ROWS
117+
118+
for PAIR in "${MODEL_CAPACITY_PAIRS[@]}"; do
119+
MODEL_NAME=$(echo "$PAIR" | cut -d':' -f1 | tr '[:upper:]' '[:lower:]')
120+
CAPACITY=$(echo "$PAIR" | cut -d':' -f2)
121+
122+
if [ -z "$MODEL_NAME" ] || [ -z "$CAPACITY" ]; then
123+
echo "❌ ERROR: Invalid model and capacity pair '$PAIR'. Both model and capacity must be specified."
124+
exit 1
125+
fi
126+
127+
FINAL_MODEL_NAMES+=("$MODEL_NAME")
128+
FINAL_CAPACITIES+=("$CAPACITY")
129+
130+
done
131+
132+
echo "🔄 Using Models: ${FINAL_MODEL_NAMES[*]} with respective Capacities: ${FINAL_CAPACITIES[*]}"
133+
echo "----------------------------------------"
134+
135+
# Check if the user provided a region, if not, use the default regions
136+
if [ -n "$USER_REGION" ]; then
137+
echo "🔍 User provided region: $USER_REGION"
138+
IFS=',' read -r -a REGIONS <<< "$USER_REGION"
139+
else
140+
echo "No region specified, using default regions: ${DEFAULT_REGION_ARRAY[*]}"
141+
REGIONS=("${DEFAULT_REGION_ARRAY[@]}")
142+
APPLY_OR_CONDITION=true
143+
fi
144+
145+
echo "✅ Retrieved Azure regions. Checking availability..."
146+
INDEX=1
147+
148+
VALID_REGIONS=()
149+
for REGION in "${REGIONS[@]}"; do
150+
log_verbose "----------------------------------------"
151+
log_verbose "🔍 Checking region: $REGION"
152+
153+
QUOTA_INFO=$(az cognitiveservices usage list --location "$REGION" --output json | tr '[:upper:]' '[:lower:]')
154+
if [ -z "$QUOTA_INFO" ]; then
155+
log_verbose "⚠️ WARNING: Failed to retrieve quota for region $REGION. Skipping."
156+
continue
157+
fi
158+
159+
AT_LEAST_ONE_MODEL_AVAILABLE=false
160+
TEMP_TABLE_ROWS=()
161+
162+
for index in "${!FINAL_MODEL_NAMES[@]}"; do
163+
MODEL_NAME="${FINAL_MODEL_NAMES[$index]}"
164+
REQUIRED_CAPACITY="${FINAL_CAPACITIES[$index]}"
165+
FOUND=false
166+
INSUFFICIENT_QUOTA=false
167+
168+
MODEL_TYPES=("openai.standard.$MODEL_NAME" "openai.globalstandard.$MODEL_NAME")
169+
170+
for MODEL_TYPE in "${MODEL_TYPES[@]}"; do
171+
FOUND=false
172+
INSUFFICIENT_QUOTA=false
173+
log_verbose "🔍 Checking model: $MODEL_NAME with required capacity: $REQUIRED_CAPACITY ($MODEL_TYPE)"
174+
175+
MODEL_INFO=$(echo "$QUOTA_INFO" | awk -v model="\"value\": \"$MODEL_TYPE\"" '
176+
BEGIN { RS="},"; FS="," }
177+
$0 ~ model { print $0 }
178+
')
179+
180+
if [ -z "$MODEL_INFO" ]; then
181+
FOUND=false
182+
log_verbose "⚠️ WARNING: No quota information found for model: $MODEL_NAME in region: $REGION for model type: $MODEL_TYPE."
183+
continue
184+
fi
185+
186+
if [ -n "$MODEL_INFO" ]; then
187+
FOUND=true
188+
CURRENT_VALUE=$(echo "$MODEL_INFO" | awk -F': ' '/"currentvalue"/ {print $2}' | tr -d ',' | tr -d ' ')
189+
LIMIT=$(echo "$MODEL_INFO" | awk -F': ' '/"limit"/ {print $2}' | tr -d ',' | tr -d ' ')
190+
191+
CURRENT_VALUE=${CURRENT_VALUE:-0}
192+
LIMIT=${LIMIT:-0}
193+
194+
CURRENT_VALUE=$(echo "$CURRENT_VALUE" | cut -d'.' -f1)
195+
LIMIT=$(echo "$LIMIT" | cut -d'.' -f1)
196+
197+
AVAILABLE=$((LIMIT - CURRENT_VALUE))
198+
log_verbose "✅ Model: $MODEL_TYPE | Used: $CURRENT_VALUE | Limit: $LIMIT | Available: $AVAILABLE"
199+
200+
if [ "$AVAILABLE" -ge "$REQUIRED_CAPACITY" ]; then
201+
FOUND=true
202+
AT_LEAST_ONE_MODEL_AVAILABLE=true
203+
TEMP_TABLE_ROWS+=("$(printf "| %-4s | %-20s | %-43s | %-10s | %-10s | %-10s |" "$INDEX" "$REGION" "$MODEL_TYPE" "$LIMIT" "$CURRENT_VALUE" "$AVAILABLE")")
204+
else
205+
INSUFFICIENT_QUOTA=true
206+
fi
207+
fi
208+
209+
if [ "$FOUND" = false ]; then
210+
log_verbose "❌ No models found for model: $MODEL_NAME in region: $REGION (${MODEL_TYPES[*]})"
211+
212+
elif [ "$INSUFFICIENT_QUOTA" = true ]; then
213+
log_verbose "⚠️ Model $MODEL_NAME in region: $REGION has insufficient quota (${MODEL_TYPES[*]})."
214+
fi
215+
done
216+
done
217+
218+
# For content-gen, we only need GPT-5.1, so check if at least one model is available
219+
if [ "$AT_LEAST_ONE_MODEL_AVAILABLE" = true ] && [ "$INSUFFICIENT_QUOTA" = false ] && [ "$FOUND" = true ]; then
220+
VALID_REGIONS+=("$REGION")
221+
TABLE_ROWS+=("${TEMP_TABLE_ROWS[@]}")
222+
INDEX=$((INDEX + 1))
223+
elif [ ${#USER_PROVIDED_PAIRS[@]} -eq 0 ]; then
224+
echo "🚫 Skipping $REGION as it does not meet quota requirements."
225+
fi
226+
227+
done
228+
229+
if [ ${#TABLE_ROWS[@]} -eq 0 ]; then
230+
echo "--------------------------------------------------------------------------------------------------------------------"
231+
232+
echo "❌ No regions have sufficient quota for all required models. Please request a quota increase: https://aka.ms/oai/stuquotarequest"
233+
else
234+
echo "---------------------------------------------------------------------------------------------------------------------"
235+
printf "| %-4s | %-20s | %-43s | %-10s | %-10s | %-10s |\n" "No." "Region" "Model Name" "Limit" "Used" "Available"
236+
echo "---------------------------------------------------------------------------------------------------------------------"
237+
for ROW in "${TABLE_ROWS[@]}"; do
238+
echo "$ROW"
239+
done
240+
echo "---------------------------------------------------------------------------------------------------------------------"
241+
echo "➡️ To request a quota increase, visit: https://aka.ms/oai/stuquotarequest"
242+
fi
243+
244+
echo "✅ Script completed."

0 commit comments

Comments
 (0)