From b53fe9ff73c94aef6db58f334d33999240431d5f Mon Sep 17 00:00:00 2001 From: Roopan-Microsoft Date: Tue, 7 Apr 2026 13:49:05 +0530 Subject: [PATCH] fix: reduce default model capacity, add Bicep version guard, remove hardcoded VM credentials - Reduce gptModelCapacity default from 150 to 30 TPM (addresses InsufficientQuota errors - 2.2% of failures) - Add bicep >= 0.33.0 to requiredVersions in azure.yaml and azure_custom.yaml (addresses InvalidTemplate errors - 43.2% of failures) - Remove hardcoded VM password fallback from main.bicep, main_custom.bicep, and main.json (OWASP A07:2021) - Add @minValue(1) constraint to gptModelCapacity parameter - Update docs to reflect new required VM credentials and reduced capacity default - Applied consistently across main.bicep, main_custom.bicep, main.json, and documentation --- azure.yaml | 1 + azure_custom.yaml | 1 + docs/CustomizingAzdParameters.md | 6 +++--- docs/DeploymentGuide.md | 6 ++++-- infra/main.bicep | 15 +++++++-------- infra/main.json | 13 +++++++------ infra/main_custom.bicep | 13 +++++++------ 7 files changed, 30 insertions(+), 25 deletions(-) diff --git a/azure.yaml b/azure.yaml index 89774bcd..03b2c382 100644 --- a/azure.yaml +++ b/azure.yaml @@ -4,6 +4,7 @@ metadata: requiredVersions: azd: '>= 1.18.0 != 1.23.9' + bicep: '>= 0.33.0' parameters: AzureAiServiceLocation: diff --git a/azure_custom.yaml b/azure_custom.yaml index 11f93e2b..85f86f50 100644 --- a/azure_custom.yaml +++ b/azure_custom.yaml @@ -4,6 +4,7 @@ metadata: requiredVersions: azd: '>= 1.18.0 != 1.23.9' + bicep: '>= 0.33.0' parameters: azureAiServiceLocation: diff --git a/docs/CustomizingAzdParameters.md b/docs/CustomizingAzdParameters.md index a5d6799e..dfcbc08a 100644 --- a/docs/CustomizingAzdParameters.md +++ b/docs/CustomizingAzdParameters.md @@ -14,12 +14,12 @@ By default this template will use the environment name as the prefix to prevent | `AZURE_ENV_MODEL_DEPLOYMENT_TYPE` | string | `GlobalStandard` | Change the Model Deployment Type (allowed values: Standard, GlobalStandard). | | `AZURE_ENV_MODEL_NAME` | string | `gpt-4o` | Set the Model Name (allowed values: gpt-4o). | | `AZURE_ENV_MODEL_VERSION` | string | `2024-08-06` | Set the Azure model version (allowed values: 2024-08-06) | -| `AZURE_ENV_MODEL_CAPACITY` | integer | `150` | Set the Model Capacity (choose a number based on available GPT model capacity in your subscription). | +| `AZURE_ENV_MODEL_CAPACITY` | integer | `30` | Set the Model Capacity (choose a number based on available GPT model capacity in your subscription). | | `AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID` | string | Guide to get your [Existing Workspace ID](/docs/re-use-log-analytics.md) | Set this if you want to reuse an existing Log Analytics Workspace instead of creating a new one. | | `AZURE_ENV_IMAGETAG` | string | `latest` | Set the Image tag Like (allowed values: latest, dev, hotfix) | | `AZURE_ENV_VM_SIZE` | string | `Standard_D2s_v5` | Specifies the size of the Jumpbox Virtual Machine (e.g., `Standard_D2s_v5`, `Standard_D2s_v4`). Set a custom value if `enablePrivateNetworking` is `true`. | -| `AZURE_ENV_JUMPBOX_ADMIN_USERNAME` | string | `JumpboxAdminUser` | Specifies the administrator username for the Jumpbox Virtual Machine. | -| `AZURE_ENV_JUMPBOX_ADMIN_PASSWORD` | string | `JumpboxAdminP@ssw0rd1234!` | Specifies the administrator password for the Jumpbox Virtual Machine. | +| `AZURE_ENV_JUMPBOX_ADMIN_USERNAME` | string | *(required when enablePrivateNetworking is true)* | Specifies the administrator username for the Jumpbox Virtual Machine. Must be provided — no default for security. | +| `AZURE_ENV_JUMPBOX_ADMIN_PASSWORD` | string | *(required when enablePrivateNetworking is true)* | Specifies the administrator password for the Jumpbox Virtual Machine. Must meet Azure complexity requirements. | | `AZURE_ENV_COSMOS_SECONDARY_LOCATION` | string | *(not set by default)* | Specifies the secondary region for Cosmos DB. Required if `enableRedundancy` is `true`. | | `AZURE_EXISTING_AI_PROJECT_RESOURCE_ID` | string | *(not set by default)* | Specifies the existing AI Foundry Project Resource ID if it needs to be reused. | | `AZURE_ENV_ACR_NAME` | string | `cmsacontainerreg.azurecr.io` | Specifies the Azure Container Registry name to use for container images. | diff --git a/docs/DeploymentGuide.md b/docs/DeploymentGuide.md index 1225a8aa..3e66e48b 100644 --- a/docs/DeploymentGuide.md +++ b/docs/DeploymentGuide.md @@ -198,17 +198,19 @@ Copy the contents from the production configuration file to your main parameters 5. Select all existing content (Ctrl+A) and paste the copied content (Ctrl+V) 6. Save the file (Ctrl+S) -### 3.2 Set VM Credentials (Optional - Production Deployment Only) +### 3.2 Set VM Credentials (Required for Production Deployment) > **Note:** This section only applies if you selected **Production** deployment type in section 3.1. VMs are not deployed in the default Development/Testing configuration. -By default, hard-coded fallback values are used for VM credentials (`JumpboxAdminUser` / `JumpboxAdminP@ssw0rd1234!`). To set custom credentials: +VM credentials must be explicitly provided when deploying with private networking enabled. No default credentials are used for security reasons. ```shell azd env set AZURE_ENV_JUMPBOX_ADMIN_USERNAME azd env set AZURE_ENV_JUMPBOX_ADMIN_PASSWORD ``` +> **Password requirements:** 12+ characters, at least one uppercase, one lowercase, one number, and one special character. + ### 3.3 Advanced Configuration (Optional)
diff --git a/infra/main.bicep b/infra/main.bicep index 1c02d6c9..0637da78 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -56,8 +56,9 @@ var replicaRegionPairs = { } var replicaLocation = replicaRegionPairs[resourceGroup().location] -@description('Optional. AI model deployment token capacity. Defaults to 150K tokens per minute.') -param gptModelCapacity int = 150 +@description('Optional. AI model deployment token capacity (thousands of tokens per minute). Must not exceed your subscription GlobalStandard quota. Reduce if provisioning fails with InsufficientQuota.') +@minValue(1) +param gptModelCapacity int = 30 @description('Optional. Enable monitoring for the resources. This will enable Application Insights and Log Analytics. Defaults to false.') param enableMonitoring bool = false @@ -77,14 +78,12 @@ param enablePrivateNetworking bool = false @description('Optional. Size of the Jumpbox Virtual Machine when created. Set to custom value if enablePrivateNetworking is true.') param vmSize string? -@description('Optional. Admin username for the Jumpbox Virtual Machine. Set to custom value if enablePrivateNetworking is true.') +@description('Required when enablePrivateNetworking is true. Admin username for the Jumpbox VM. Must be provided — no default for security.') @secure() -//param vmAdminUsername string = take(newGuid(), 20) param vmAdminUsername string? -@description('Optional. Admin password for the Jumpbox Virtual Machine. Set to custom value if enablePrivateNetworking is true.') +@description('Required when enablePrivateNetworking is true. Admin password for the Jumpbox VM. Must meet Azure complexity requirements (12+ chars, uppercase, lowercase, number, special char). Must be provided — no default for security.') @secure() -//param vmAdminPassword string = newGuid() param vmAdminPassword string? @description('Optional. Specifies the resource tags for all the resources. Tag "azd-env-name" is automatically added to all resources.') @@ -637,8 +636,8 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.20.0' = if (e computerName: take(virtualMachineResourceName, 15) osType: 'Windows' vmSize: !empty(vmSize) ? vmSize : 'Standard_D2s_v5' - adminUsername: !empty(vmAdminUsername) ? vmAdminUsername : 'JumpboxAdminUser' - adminPassword: !empty(vmAdminPassword) ? vmAdminPassword : 'JumpboxAdminP@ssw0rd1234!' + adminUsername: vmAdminUsername! + adminPassword: vmAdminPassword! managedIdentities: { systemAssigned: true } diff --git a/infra/main.json b/infra/main.json index f98bb0c5..e0187696 100644 --- a/infra/main.json +++ b/infra/main.json @@ -66,9 +66,10 @@ }, "gptModelCapacity": { "type": "int", - "defaultValue": 150, + "defaultValue": 30, + "minValue": 1, "metadata": { - "description": "Optional. AI model deployment token capacity. Defaults to 150K tokens per minute." + "description": "Optional. AI model deployment token capacity (thousands of tokens per minute). Must not exceed your subscription GlobalStandard quota. Reduce if provisioning fails with InsufficientQuota." } }, "enableMonitoring": { @@ -117,14 +118,14 @@ "type": "securestring", "nullable": true, "metadata": { - "description": "Optional. Admin username for the Jumpbox Virtual Machine. Set to custom value if enablePrivateNetworking is true." + "description": "Required when enablePrivateNetworking is true. Admin username for the Jumpbox VM. Must be provided — no default for security." } }, "vmAdminPassword": { "type": "securestring", "nullable": true, "metadata": { - "description": "Optional. Admin password for the Jumpbox Virtual Machine. Set to custom value if enablePrivateNetworking is true." + "description": "Required when enablePrivateNetworking is true. Admin password for the Jumpbox VM. Must meet Azure complexity requirements (12+ chars, uppercase, lowercase, number, special char). Must be provided — no default for security." } }, "tags": { @@ -16618,8 +16619,8 @@ "value": "Windows" }, "vmSize": "[if(not(empty(parameters('vmSize'))), createObject('value', parameters('vmSize')), createObject('value', 'Standard_D2s_v5'))]", - "adminUsername": "[if(not(empty(parameters('vmAdminUsername'))), createObject('value', parameters('vmAdminUsername')), createObject('value', 'JumpboxAdminUser'))]", - "adminPassword": "[if(not(empty(parameters('vmAdminPassword'))), createObject('value', parameters('vmAdminPassword')), createObject('value', 'JumpboxAdminP@ssw0rd1234!'))]", + "adminUsername": "[createObject('value', parameters('vmAdminUsername'))]", + "adminPassword": "[createObject('value', parameters('vmAdminPassword'))]", "managedIdentities": { "value": { "systemAssigned": true diff --git a/infra/main_custom.bicep b/infra/main_custom.bicep index b6998587..dc19032b 100644 --- a/infra/main_custom.bicep +++ b/infra/main_custom.bicep @@ -56,8 +56,9 @@ var replicaRegionPairs = { } var replicaLocation = replicaRegionPairs[resourceGroup().location] -@description('Optional. AI model deployment token capacity. Defaults to 150K tokens per minute.') -param gptModelCapacity int = 150 +@description('Optional. AI model deployment token capacity (thousands of tokens per minute). Must not exceed your subscription GlobalStandard quota. Reduce if provisioning fails with InsufficientQuota.') +@minValue(1) +param gptModelCapacity int = 30 @description('Optional. Enable monitoring for the resources. This will enable Application Insights and Log Analytics. Defaults to false.') param enableMonitoring bool = false @@ -77,12 +78,12 @@ param enablePrivateNetworking bool = false @description('Optional. Size of the Jumpbox Virtual Machine when created. Set to custom value if enablePrivateNetworking is true.') param vmSize string? -@description('Optional. Admin username for the Jumpbox Virtual Machine. Set to custom value if enablePrivateNetworking is true.') +@description('Required when enablePrivateNetworking is true. Admin username for the Jumpbox VM. Must be provided — no default for security.') @secure() //param vmAdminUsername string = take(newGuid(), 20) param vmAdminUsername string? -@description('Optional. Admin password for the Jumpbox Virtual Machine. Set to custom value if enablePrivateNetworking is true.') +@description('Required when enablePrivateNetworking is true. Admin password for the Jumpbox VM. Must meet Azure complexity requirements (12+ chars, uppercase, lowercase, number, special char). Must be provided — no default for security.') @secure() //param vmAdminPassword string = newGuid() param vmAdminPassword string? @@ -566,8 +567,8 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.20.0' = if (e computerName: take(virtualMachineResourceName, 15) osType: 'Windows' vmSize: !empty(vmSize) ? vmSize : 'Standard_D2s_v5' - adminUsername: !empty(vmAdminUsername) ? vmAdminUsername : 'JumpboxAdminUser' - adminPassword: !empty(vmAdminPassword) ? vmAdminPassword : 'JumpboxAdminP@ssw0rd1234!' + adminUsername: vmAdminUsername! + adminPassword: vmAdminPassword! managedIdentities: { systemAssigned: true }