Skip to content

Commit 0f50a02

Browse files
Merge branch 'main' into psl-refactor-email
2 parents 0943c7e + 916aeb2 commit 0f50a02

File tree

6 files changed

+2186
-618
lines changed

6 files changed

+2186
-618
lines changed

docs/CustomizingAzdParameters.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ By default this template will use the environment name as the prefix to prevent
2222
| `AZURE_LOCATION` | string | `eastus` | Sets the primary Azure region for resource deployment. |
2323
| `AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID` | string | Guide to get your [Existing Workspace ID](/docs/re-use-log-analytics.md) | Reuses an existing Log Analytics Workspace instead of provisioning a new one. |
2424
| `AZURE_EXISTING_AI_PROJECT_RESOURCE_ID` | string | `<Existing AI Project resource Id>` | Reuses an existing AIFoundry and AIFoundryProject instead of creating a new one. |
25+
| `AZURE_ENV_VM_SIZE` | string | `Standard_D2s_v5` | Overrides the jumpbox VM size (private networking only). Default: `Standard_D2s_v5`. |
2526

2627
## How to Set a Parameter
2728

docs/TroubleShootingSteps.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ Use these as quick reference guides to unblock your deployments.
6161
| **ServiceQuotaExceeded** | Free tier service quota limit reached for Azure AI Search | This error occurs when you attempt to deploy an Azure AI Search service but have already reached the **free tier quota limit** for your subscription. Each Azure subscription is limited to **one free tier Search service**.<br><br>**Example error message:**<br>`ServiceQuotaExceeded: Operation would exceed 'free' tier service quota. You are using 1 out of 1 'free' tier service quota.`<br><br>**Common causes:**<br><ul><li>Already have a free tier Azure AI Search service in the subscription</li><li>Previous deployment created a free tier Search service that wasn't deleted</li><li>Attempting to deploy multiple environments with free tier Search services</li></ul><br>**Resolution:**<br><ul><li>**Option 1: Delete existing free tier Search service:**<br>`az search service list --query "[?sku.name=='free']" -o table`<br>`az search service delete --name <service-name> --resource-group <rg-name> --yes`</li><li>**Option 2: Upgrade to a paid SKU:**<br>Modify your Bicep/ARM template to use `basic`, `standard`, or higher SKU instead of `free`</li><li>**Option 3: Use existing Search service:**<br>Reference the existing free tier Search service in your deployment instead of creating a new one</li><li>**Request quota increase:**<br>Submit a support request with issue type 'Service and subscription limits (quota)' and quota type 'Search' via [Azure Quota Request](https://aka.ms/AddQuotaSubscription)</li></ul><br>**Reference:**<br><ul><li>[Azure AI Search service limits](https://learn.microsoft.com/en-us/azure/search/search-limits-quotas-capacity)</li><li>[Azure AI Search pricing tiers](https://learn.microsoft.com/en-us/azure/search/search-sku-tier)</li></ul> |
6262
| **InsufficientQuota** | Not enough quota available in subscription | <ul><li>Check if you have sufficient quota available in your subscription before deployment</li><li>To verify, refer to the [quota_check](../docs/quota_check.md) file for details</li></ul> |
6363
| **MaxNumberOfRegionalEnvironmentsInSubExceeded** | Maximum Container App Environments limit reached for region |This error occurs when you attempt to create more **Azure Container App Environments** than the regional quota limit allows for your subscription. Each Azure region has a specific limit on the number of Container App Environments that can be created per subscription.<br><br>**Common Causes:**<br><ul><li>Deploying to regions with low quota limits (e.g., Sweden Central allows only 1 environment)</li><li>Multiple deployments without cleaning up previous environments</li><li>Exceeding the standard limit of 15 environments in most major regions</li></ul><br>**Resolution:**<br><ul><li>**Delete unused environments** in the target region, OR</li><li>**Deploy to a different region** with available capacity, OR</li><li>**Request quota increase** via [Azure Support](https://go.microsoft.com/fwlink/?linkid=2208872)</li></ul><br>**Reference:**<br><ul><li>[Azure Container Apps quotas](https://learn.microsoft.com/en-us/azure/container-apps/quotas)</li><li>[Azure subscription and service limits](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits)</li></ul> |
64-
| **SkuNotAvailable** | Requested SKU not available in selected location or zone | You receive this error in the following scenarios:<br><ul><li>When the resource SKU you've selected, such as VM size, isn't available for a location or zone</li><li>If you're deploying an Azure Spot VM or Spot scale set instance, and there isn't any capacity for Azure Spot in this location. For more information, see Spot error messages</li></ul> |
64+
| **SkuNotAvailable** | Requested SKU not available in selected location or zone | This error occurs when the resource SKU you've selected (such as VM size) isn't available for the target location or availability zone.<br><br>**In this deployment**, the jumpbox VM defaults to `Standard_D2s_v5`. While this size is available in most regions, certain regions or zones may not support it.<br><br>**Resolution:**<br><ul><li>**Check SKU availability** for your target region:<br>`az vm list-skus --location <region> --size Standard_D2s --output table`</li><li>**Override the VM size** if the default isn't available in your region:<br>`azd env set AZURE_ENV_VM_SIZE Standard_D2s_v4`</li><li>**Recommended alternatives** (all support accelerated networking + Premium SSD):<br>- `Standard_D2s_v4` — previous gen, identical pricing<br>- `Standard_D2as_v5` — AMD-based, similar pricing<br>- `Standard_D2s_v3` — older gen, widely available</li><li>**Avoid A-series VMs** (e.g., `Standard_A2m_v2`) — they do not support accelerated networking or Premium SSD, which are required by this deployment</li></ul><br>**Reference:**<br><ul><li>[Resolve errors for SKU not available](https://learn.microsoft.com/en-us/azure/azure-resource-manager/troubleshooting/error-sku-not-available)</li><li>[Azure VM sizes - Dsv5 series](https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dsv5-series)</li></ul> |
6565
| **Conflict - No available instances to satisfy this request** | Azure App Service has insufficient capacity in the region | This error occurs when Azure App Service doesn't have enough available compute instances in the selected region to provision or scale your app.<br><br>**Common Causes:**<br><ul><li>High demand in the selected region (e.g., East US, West Europe)</li><li>Specific SKUs experiencing capacity constraints (Free, Shared, or certain Premium tiers)</li><li>Multiple rapid deployments in the same region</li></ul><br>**Resolution:**<br><ul><li>**Wait and Retry** (15-30 minutes): `azd up`</li><li>**Deploy to a New Resource Group** (Recommended for urgent cases):<br>```<br>azd down --force --purge<br>azd up<br>```</li><li>**Try a Different Region:**<br>Update region in `main.bicep` or `azure.yaml` to a less congested region (e.g., `westus2`, `centralus`, `northeurope`)</li><li>**Use a Different SKU/Tier:**<br>If using Free/Shared tier, upgrade to Basic or Standard<br>Check SKU availability: `az appservice list-locations --sku <sku-name>`</li></ul><br>**Reference:** [Azure App Service Plans](https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans) |
6666

6767
--------------------------------
@@ -120,7 +120,7 @@ Use these as quick reference guides to unblock your deployments.
120120
|-----------------|-------------|------------------|
121121
| **NetcfgSubnetRangeOutsideVnet** | Subnet IP range outside virtual network address space | <ul><li>Ensure the subnet's IP address range falls within the virtual network's address space</li><li>Always validate that the subnet CIDR block is a subset of the VNet range</li><li>For Azure Bastion, the AzureBastionSubnet must be at least /27</li><li>Confirm that the AzureBastionSubnet is deployed inside the VNet</li></ul> |
122122
| **DisableExport_PublicNetworkAccessMustBeDisabled** | Public network access must be disabled when export is disabled | <ul><li>**Check container source:** Confirm whether the deployment is using a Docker image or Azure Container Registry (ACR)</li><li>**Verify ACR configuration:** If ACR is included, review its settings to ensure they comply with Azure requirements</li><li>**Check export settings:** If export is disabled in ACR, make sure public network access is also disabled</li><li>**Redeploy after fix:** Correct the configuration and redeploy. This will prevent the Conflict error during deployment</li><li>For more information refer [ACR Data Loss Prevention](https://learn.microsoft.com/en-us/azure/container-registry/data-loss-prevention) document</li></ul> |
123-
| **VMSizeIsNotPermittedToEnableAcceleratedNetworking** | VM size does not support accelerated networking | This error occurs when you attempt to enable accelerated networking on a VM size that does not support it.<br><br>**How to reproduce:**<br><ul><li>Create or deploy a VM (e.g., via ARM/Bicep) with size `Standard_A2m_v2`</li><li>In the network interface configuration, set `"enableAcceleratedNetworking": true`</li><li>Submit the request → Azure throws `VMSizeIsNotPermittedToEnableAcceleratedNetworking`</li></ul><br>**Resolution:**<br><ul><li>Use a supported VM size that supports accelerated networking</li><li>Check the [Microsoft list of supported VM sizes for accelerated networking](https://learn.microsoft.com/en-us/azure/virtual-network/accelerated-networking-overview#supported-vm-instances)</li><li>Alternatively, disable accelerated networking if the feature is not required for your workload</li></ul> |
123+
| **VMSizeIsNotPermittedToEnableAcceleratedNetworking** | VM size does not support accelerated networking | This error occurs when you attempt to enable accelerated networking on a VM size that does not support it. This deployment's jumpbox VM **requires** accelerated networking.<br><br>**Default VM size:** `Standard_D2s_v5` — supports accelerated networking.<br><br>**How this error happens:**<br><ul><li>You override the VM size (via `AZURE_ENV_VM_SIZE`) with a size that doesn't support accelerated networking (e.g., `Standard_A2m_v2`, A-series, or B-series VMs)</li><li>Azure rejects the deployment with `VMSizeIsNotPermittedToEnableAcceleratedNetworking`</li></ul><br>**Resolution:**<br><ul><li>Use the default `Standard_D2s_v5`, or override with a D-series VM that supports accelerated networking:<br>`azd env set AZURE_ENV_VM_SIZE Standard_D2s_v5`</li><li>**Supported alternatives:** `Standard_D2s_v4`, `Standard_D2as_v5`, `Standard_D2s_v3`</li><li>**Do NOT use:** A-series (`Standard_A2m_v2`), B-series (`Standard_B2s`) — these do not support accelerated networking</li><li>Check supported sizes: [Accelerated networking supported VM instances](https://learn.microsoft.com/en-us/azure/virtual-network/accelerated-networking-overview#supported-vm-instances)</li></ul> |
124124
**NetworkSecurityGroupNotCompliantForAzureBastionSubnet** / **SecurityRuleParameterContainsUnsupportedValue** | NSG rules blocking required Azure Bastion ports | This error occurs when the Network Security Group (NSG) attached to `AzureBastionSubnet` explicitly denies inbound TCP ports 443 and/or 4443, which Azure Bastion requires for management and tunneling.<br><br>**How to reproduce:**<br><ul><li>Deploy the template with `enablePrivateNetworking=true` so the virtualNetwork module creates `AzureBastionSubnet` and a Network Security Group that denies ports 443 and 4443</li><li>Attempt to deploy Azure Bastion into that subnet</li><li>During validation, Bastion detects the deny rules and fails with `NetworkSecurityGroupNotCompliantForAzureBastionSubnet`</li></ul><br>**Resolution:**<br><ul> <li>Allow inbound TCP 443 and 4443 on `AzureBastionSubnet` by updating or removing the NSG deny rules</li><li>Alternatively, deploy Bastion to a subnet without restrictive NSG rules</li><li>For more details, refer to [Azure Bastion NSG requirements](https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg)</li></ul> |
125125
| **RouteTableCannotBeAttachedForAzureBastionSubnet** | Route table attached to Azure Bastion subnet | This error occurs because Azure Bastion subnet (`AzureBastionSubnet`) has a platform restriction that prevents route tables from being attached.<br><br>**How to reproduce:**<br><ul><li>In `virtualNetwork.bicep`, add `attachRouteTable: true` to the `AzureBastionSubnet` configuration:<br>`{ name: 'AzureBastionSubnet', addressPrefixes: ['10.0.10.0/26'], attachRouteTable: true }`</li><li>Add a Route Table module to the template</li><li>Update subnet creation to attach route table conditionally:<br>`routeTableResourceId: subnet.?attachRouteTable == true ? routeTable.outputs.resourceId : null`</li><li>Deploy the template → Azure throws `RouteTableCannotBeAttachedForAzureBastionSubnet`</li></ul><br>**Resolution:**<br><ul><li>Remove the `attachRouteTable: true` flag from `AzureBastionSubnet` configuration</li><li>Ensure no route table is associated with `AzureBastionSubnet`</li><li>Route tables can only be attached to other subnets, not `AzureBastionSubnet`</li><li>For more details, refer to [Azure Bastion subnet requirements](https://learn.microsoft.com/en-us/azure/bastion/configuration-settings#subnet)</li></ul> |
126126

infra/main.bicep

Lines changed: 73 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ module jumpboxVM 'br/public:avm/res/compute/virtual-machine:0.20.0' = if (enable
240240
enableTelemetry: enableTelemetry
241241
computerName: take(jumpboxVmName, 15)
242242
osType: 'Windows'
243-
vmSize: empty(vmSize) ? 'Standard_DS2_v2' : vmSize
243+
vmSize: empty(vmSize) ? 'Standard_D2s_v5' : vmSize
244244
adminUsername: empty(vmAdminUsername) ? 'JumpboxAdminUser' : vmAdminUsername
245245
adminPassword: empty(vmAdminPassword) ? 'JumpboxAdminP@ssw0rd1234!' : vmAdminPassword
246246
managedIdentities: {
@@ -771,36 +771,46 @@ module avmAiServices 'modules/account/aifoundry.bicep' = {
771771
// WAF related parameters
772772
publicNetworkAccess: (enablePrivateNetworking) ? 'Disabled' : 'Enabled'
773773
//publicNetworkAccess: 'Enabled' // Always enabled for AI Services
774-
privateEndpoints: (enablePrivateNetworking && empty(existingProjectResourceId))
775-
? [
776-
{
777-
name: 'pep-aiservices-${solutionSuffix}'
778-
customNetworkInterfaceName: 'nic-aiservices-${solutionSuffix}'
779-
privateEndpointResourceId: virtualNetwork!.outputs.resourceId
780-
privateDnsZoneGroup: {
781-
privateDnsZoneGroupConfigs: [
782-
{
783-
name: 'ai-services-dns-zone-cognitiveservices'
784-
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId
785-
}
786-
{
787-
name: 'ai-services-dns-zone-openai'
788-
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.openAI]!.outputs.resourceId
789-
}
790-
{
791-
name: 'ai-services-dns-zone-aiservices'
792-
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.aiServices]!.outputs.resourceId
793-
}
794-
{
795-
name: 'ai-services-dns-zone-contentunderstanding'
796-
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.contentUnderstanding]!.outputs.resourceId
797-
}
798-
]
799-
}
800-
subnetResourceId: virtualNetwork!.outputs.backendSubnetResourceId // Use the backend subnet
801-
}
802-
]
803-
: []
774+
}
775+
}
776+
777+
module cognitiveServicePrivateEndpoint 'br/public:avm/res/network/private-endpoint:0.8.1' = if (enablePrivateNetworking && empty(existingProjectResourceId)) {
778+
name: take('avm.res.network.private-endpoint.${solutionSuffix}', 64)
779+
params: {
780+
name: 'pep-aiservices-${solutionSuffix}'
781+
location: location
782+
tags: tags
783+
customNetworkInterfaceName: 'nic-aiservices-${solutionSuffix}'
784+
privateLinkServiceConnections: [
785+
{
786+
name: 'pep-aiservices-${solutionSuffix}-cognitiveservices-connection'
787+
properties: {
788+
privateLinkServiceId: avmAiServices.outputs.resourceId
789+
groupIds: ['account']
790+
}
791+
}
792+
]
793+
privateDnsZoneGroup: {
794+
privateDnsZoneGroupConfigs: [
795+
{
796+
name: 'ai-services-dns-zone-cognitiveservices'
797+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId
798+
}
799+
{
800+
name: 'ai-services-dns-zone-openai'
801+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.openAI]!.outputs.resourceId
802+
}
803+
{
804+
name: 'ai-services-dns-zone-aiservices'
805+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.aiServices]!.outputs.resourceId
806+
}
807+
{
808+
name: 'ai-services-dns-zone-contentunderstanding'
809+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.contentUnderstanding]!.outputs.resourceId
810+
}
811+
]
812+
}
813+
subnetResourceId: virtualNetwork!.outputs.backendSubnetResourceId
804814
}
805815
}
806816

@@ -838,28 +848,38 @@ module avmAiServices_cu 'br/public:avm/res/cognitive-services/account:0.13.2' =
838848
]
839849

840850
publicNetworkAccess: (enablePrivateNetworking) ? 'Disabled' : 'Enabled'
841-
privateEndpoints: (enablePrivateNetworking)
842-
? [
843-
{
844-
name: 'pep-aicu-${solutionSuffix}'
845-
customNetworkInterfaceName: 'nic-aicu-${solutionSuffix}'
846-
privateEndpointResourceId: virtualNetwork!.outputs.resourceId
847-
privateDnsZoneGroup: {
848-
privateDnsZoneGroupConfigs: [
849-
{
850-
name: 'aicu-dns-zone-cognitiveservices'
851-
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId
852-
}
853-
{
854-
name: 'aicu-dns-zone-contentunderstanding'
855-
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.contentUnderstanding]!.outputs.resourceId
856-
}
857-
]
858-
}
859-
subnetResourceId: virtualNetwork!.outputs.backendSubnetResourceId // Use the backend subnet
860-
}
861-
]
862-
: []
851+
}
852+
}
853+
854+
module contentUnderstandingPrivateEndpoint 'br/public:avm/res/network/private-endpoint:0.8.1' = if (enablePrivateNetworking) {
855+
name: take('avm.res.network.private-endpoint.aicu-${solutionSuffix}', 64)
856+
params: {
857+
name: 'pep-aicu-${solutionSuffix}'
858+
location: location
859+
tags: tags
860+
customNetworkInterfaceName: 'nic-aicu-${solutionSuffix}'
861+
privateLinkServiceConnections: [
862+
{
863+
name: 'pep-aicu-${solutionSuffix}-cognitiveservices-connection'
864+
properties: {
865+
privateLinkServiceId: avmAiServices_cu.outputs.resourceId
866+
groupIds: ['account']
867+
}
868+
}
869+
]
870+
privateDnsZoneGroup: {
871+
privateDnsZoneGroupConfigs: [
872+
{
873+
name: 'aicu-dns-zone-cognitiveservices'
874+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId
875+
}
876+
{
877+
name: 'aicu-dns-zone-contentunderstanding'
878+
privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.contentUnderstanding]!.outputs.resourceId
879+
}
880+
]
881+
}
882+
subnetResourceId: virtualNetwork!.outputs.backendSubnetResourceId
863883
}
864884
}
865885

0 commit comments

Comments
 (0)