diff --git a/docs/CustomizingAzdParameters.md b/docs/CustomizingAzdParameters.md
index 607339cb..f4c4357a 100644
--- a/docs/CustomizingAzdParameters.md
+++ b/docs/CustomizingAzdParameters.md
@@ -21,6 +21,7 @@ By default this template will use the environment name as the prefix to prevent
| `AZURE_ENV_CONTAINER_IMAGE_TAG` | string | `latest` | Sets the container image tag (e.g., `latest`, `dev`, `hotfix`). |
| `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. |
| `AZURE_ENV_FOUNDRY_PROJECT_ID` | string | Guide to get your [Existing AI Project ID](/docs/re-use-foundry-project.md) | Reuses an existing AI Foundry and AI Foundry Project instead of creating a new one. |
+| `AZURE_ENV_VM_SIZE` | string | `Standard_D2s_v5` | Overrides the jumpbox VM size (private networking only). Default: `Standard_D2s_v5`. |
## How to Set a Parameter
diff --git a/docs/TroubleShootingSteps.md b/docs/TroubleShootingSteps.md
index b014b1d6..1673a894 100644
--- a/docs/TroubleShootingSteps.md
+++ b/docs/TroubleShootingSteps.md
@@ -62,7 +62,7 @@ Use these as quick reference guides to unblock your deployments.
| **InternalSubscriptionIsOverQuotaForSku/
ManagedEnvironmentProvisioningError** | Subscription quota exceeded for the requested SKU | Quotas are applied per resource group, subscriptions, accounts, and other scopes. For example, your subscription might be configured to limit the number of vCPUs for a region. If you attempt to deploy a virtual machine with more vCPUs than the permitted amount, you receive an error that the quota was exceeded.
For PowerShell, use the `Get-AzVMUsage` cmdlet to find virtual machine quotas:
`Get-AzVMUsage -Location "West US"`
Based on available quota you can deploy application otherwise, you can request for more quota |
| **InsufficientQuota** | Not enough quota available in subscription |
- Check if you have sufficient quota available in your subscription before deployment
- To verify, refer to the [quota_check](../docs/quota_check.md) file for details
|
| **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.
**Common Causes:**
- Deploying to regions with low quota limits (e.g., Sweden Central allows only 1 environment)
- Multiple deployments without cleaning up previous environments
- Exceeding the standard limit of 15 environments in most major regions
**Resolution:**
- **Delete unused environments** in the target region, OR
- **Deploy to a different region** with available capacity, OR
- **Request quota increase** via [Azure Support](https://go.microsoft.com/fwlink/?linkid=2208872)
**Reference:**
- [Azure Container Apps quotas](https://learn.microsoft.com/en-us/azure/container-apps/quotas)
- [Azure subscription and service limits](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits)
|
-| **SkuNotAvailable** | Requested SKU not available in selected location or zone | You receive this error in the following scenarios:
- When the resource SKU you've selected, such as VM size, isn't available for a location or zone
- 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
|
+| **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.
**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.
**Resolution:**
- **Check SKU availability** for your target region:
`az vm list-skus --location --size Standard_D2s --output table` - **Override the VM size** if the default isn't available in your region:
`azd env set AZURE_ENV_VM_SIZE Standard_D2s_v4` - **Recommended alternatives** (all support accelerated networking):
`Standard_D2s_v4`, `Standard_D2as_v5` (AMD), `Standard_D2s_v3` - **Avoid these sizes**: `Standard_DS2_v2` (being retired), A-series (no accelerated networking)
- If deploying an Azure Spot VM, check [Spot capacity](https://aka.ms/azurespotpricing)
|
| **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.
**Common Causes:**
- High demand in the selected region (e.g., East US, West Europe)
- Specific SKUs experiencing capacity constraints (Free, Shared, or certain Premium tiers)
- Multiple rapid deployments in the same region
**Resolution:**
- **Wait and Retry** (15-30 minutes): `azd up`
- **Deploy to a New Resource Group** (Recommended for urgent cases):
```
azd down --force --purge
azd up
``` - **Try a Different Region:**
Update region in `main.bicep` or `azure.yaml` to a less congested region (e.g., `westus2`, `centralus`, `northeurope`) - **Use a Different SKU/Tier:**
If using Free/Shared tier, upgrade to Basic or Standard
Check SKU availability: `az appservice list-locations --sku `
**Reference:** [Azure App Service Plans](https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans) |
--------------------------------
@@ -121,6 +121,8 @@ Use these as quick reference guides to unblock your deployments.
|-----------------|-------------|------------------|
| **NetcfgSubnetRangeOutsideVnet** | Subnet IP range outside virtual network address space | - Ensure the subnet's IP address range falls within the virtual network's address space
- Always validate that the subnet CIDR block is a subset of the VNet range
- For Azure Bastion, the AzureBastionSubnet must be at least /27
- Confirm that the AzureBastionSubnet is deployed inside the VNet
|
| **DisableExport_PublicNetworkAccessMustBeDisabled** | Public network access must be disabled when export is disabled | - **Check container source:** Confirm whether the deployment is using a Docker image or Azure Container Registry (ACR)
- **Verify ACR configuration:** If ACR is included, review its settings to ensure they comply with Azure requirements
- **Check export settings:** If export is disabled in ACR, make sure public network access is also disabled
- **Redeploy after fix:** Correct the configuration and redeploy. This will prevent the Conflict error during deployment
- For more information refer [ACR Data Loss Prevention](https://learn.microsoft.com/en-us/azure/container-registry/data-loss-prevention) document
|
+| **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.
**Default VM size:** `Standard_D2s_v5` — supports accelerated networking.
**How this error happens:**
- 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)
- Azure rejects the deployment with `VMSizeIsNotPermittedToEnableAcceleratedNetworking`
**Resolution:**
- Use the default `Standard_D2s_v5` (recommended)
- If overriding VM size, choose one that supports accelerated networking:
`Standard_D2s_v4`, `Standard_D2as_v5` (AMD), `Standard_D2s_v3` - Verify VM size supports accelerated networking:
`az vm list-skus --location --size --query "[?capabilities[?name=='AcceleratedNetworkingEnabled' && value=='True']]"` - Avoid A-series and B-series VMs — they do not support accelerated networking
- See [VM sizes with accelerated networking](https://learn.microsoft.com/en-us/azure/virtual-network/accelerated-networking-overview)
|
+| **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.
**How to reproduce:**
- Deploy the template with `enablePrivateNetworking=true` so the virtualNetwork module creates `AzureBastionSubnet` and a Network Security Group that denies ports 443 and 4443
- Attempt to deploy Azure Bastion into that subnet
- During validation, Bastion detects the deny rules and fails with `NetworkSecurityGroupNotCompliantForAzureBastionSubnet`
**Resolution:**
- **Remove or modify deny rules** for ports 443 and 4443 in the NSG attached to `AzureBastionSubnet`
- **Ensure required inbound rules** per [Azure Bastion NSG requirements](https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg)
- **Use Bicep conditions** to skip NSG attachments for `AzureBastionSubnet` if deploying Bastion
- **Validate the NSG configuration** before deploying Bastion into the subnet
|
---------------------------------
diff --git a/infra/main.bicep b/infra/main.bicep
index b56bf400..ef2a0495 100644
--- a/infra/main.bicep
+++ b/infra/main.bicep
@@ -229,7 +229,7 @@ module jumpboxVM 'br/public:avm/res/compute/virtual-machine:0.20.0' = if (enable
enableTelemetry: enableTelemetry
computerName: take(jumpboxVmName, 15)
osType: 'Windows'
- vmSize: empty(vmSize) ? 'Standard_DS2_v2' : vmSize
+ vmSize: empty(vmSize) ? 'Standard_D2s_v5' : vmSize
adminUsername: empty(vmAdminUsername) ? 'JumpboxAdminUser' : vmAdminUsername
adminPassword: empty(vmAdminPassword) ? 'JumpboxAdminP@ssw0rd1234!' : vmAdminPassword
managedIdentities: {
@@ -776,40 +776,50 @@ module avmAiServices 'modules/account/aifoundry.bicep' = {
// WAF related parameters
publicNetworkAccess: (enablePrivateNetworking) ? 'Disabled' : 'Enabled'
//publicNetworkAccess: 'Enabled' // Always enabled for AI Services
- privateEndpoints: (enablePrivateNetworking && empty(existingProjectResourceId))
- ? [
- {
- name: 'pep-aiservices-${solutionSuffix}'
- customNetworkInterfaceName: 'nic-aiservices-${solutionSuffix}'
- privateEndpointResourceId: virtualNetwork!.outputs.resourceId
- privateDnsZoneGroup: {
- privateDnsZoneGroupConfigs: [
- {
- name: 'ai-services-dns-zone-cognitiveservices'
- privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId
- }
- {
- name: 'ai-services-dns-zone-openai'
- privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.openAI]!.outputs.resourceId
- }
- {
- name: 'ai-services-dns-zone-aiservices'
- privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.aiServices]!.outputs.resourceId
- }
- {
- name: 'ai-services-dns-zone-contentunderstanding'
- privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.contentUnderstanding]!.outputs.resourceId
- }
- ]
- }
- subnetResourceId: virtualNetwork!.outputs.backendSubnetResourceId // Use the backend subnet
- }
- ]
- : []
}
}
-module avmAiServices_cu 'br/public:avm/res/cognitive-services/account:0.13.2' = {
+module cognitiveServicePrivateEndpoint 'br/public:avm/res/network/private-endpoint:0.8.1' = if (enablePrivateNetworking && empty(existingProjectResourceId)) {
+ name: take('avm.res.network.private-endpoint.${solutionSuffix}', 64)
+ params: {
+ name: 'pep-aiservices-${solutionSuffix}'
+ location: location
+ tags: tags
+ customNetworkInterfaceName: 'nic-aiservices-${solutionSuffix}'
+ privateLinkServiceConnections: [
+ {
+ name: 'pep-aiservices-${solutionSuffix}-cognitiveservices-connection'
+ properties: {
+ privateLinkServiceId: avmAiServices.outputs.resourceId
+ groupIds: ['account']
+ }
+ }
+ ]
+ privateDnsZoneGroup: {
+ privateDnsZoneGroupConfigs: [
+ {
+ name: 'ai-services-dns-zone-cognitiveservices'
+ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId
+ }
+ {
+ name: 'ai-services-dns-zone-openai'
+ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.openAI]!.outputs.resourceId
+ }
+ {
+ name: 'ai-services-dns-zone-aiservices'
+ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.aiServices]!.outputs.resourceId
+ }
+ {
+ name: 'ai-services-dns-zone-contentunderstanding'
+ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.contentUnderstanding]!.outputs.resourceId
+ }
+ ]
+ }
+ subnetResourceId: virtualNetwork!.outputs.backendSubnetResourceId
+ }
+}
+
+module avmAiServices_cu 'br/public:avm/res/cognitive-services/account:0.14.1' = {
name: take('avm.res.cognitive-services.account.content-understanding.${solutionSuffix}', 64)
params: {
@@ -848,28 +858,42 @@ module avmAiServices_cu 'br/public:avm/res/cognitive-services/account:0.13.2' =
]
publicNetworkAccess: (enablePrivateNetworking) ? 'Disabled' : 'Enabled'
- privateEndpoints: (enablePrivateNetworking)
- ? [
- {
- name: 'pep-aicu-${solutionSuffix}'
- customNetworkInterfaceName: 'nic-aicu-${solutionSuffix}'
- privateEndpointResourceId: virtualNetwork!.outputs.resourceId
- privateDnsZoneGroup: {
- privateDnsZoneGroupConfigs: [
- {
- name: 'aicu-dns-zone-cognitiveservices'
- privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId
- }
- {
- name: 'aicu-dns-zone-contentunderstanding'
- privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.contentUnderstanding]!.outputs.resourceId
- }
- ]
- }
- subnetResourceId: virtualNetwork!.outputs.backendSubnetResourceId // Use the backend subnet
- }
- ]
- : []
+ }
+}
+
+module contentUnderstandingPrivateEndpoint 'br/public:avm/res/network/private-endpoint:0.8.1' = if (enablePrivateNetworking) {
+ name: take('avm.res.network.private-endpoint.aicu-${solutionSuffix}', 64)
+ params: {
+ name: 'pep-aicu-${solutionSuffix}'
+ location: location
+ tags: tags
+ customNetworkInterfaceName: 'nic-aicu-${solutionSuffix}'
+ privateLinkServiceConnections: [
+ {
+ name: 'pep-aicu-${solutionSuffix}-cognitiveservices-connection'
+ properties: {
+ privateLinkServiceId: avmAiServices_cu.outputs.resourceId
+ groupIds: ['account']
+ }
+ }
+ ]
+ privateDnsZoneGroup: {
+ privateDnsZoneGroupConfigs: [
+ {
+ name: 'aicu-dns-zone-cognitiveservices'
+ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.cognitiveServices]!.outputs.resourceId
+ }
+ {
+ name: 'ai-services-dns-zone-aiservices'
+ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.aiServices]!.outputs.resourceId
+ }
+ {
+ name: 'aicu-dns-zone-contentunderstanding'
+ privateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.contentUnderstanding]!.outputs.resourceId
+ }
+ ]
+ }
+ subnetResourceId: virtualNetwork!.outputs.backendSubnetResourceId
}
}
@@ -1631,6 +1655,10 @@ module avmContainerApp_update 'br/public:avm/res/app/container-app:0.19.0' = {
: []
}
}
+ dependsOn: [
+ cognitiveServicePrivateEndpoint
+ contentUnderstandingPrivateEndpoint
+ ]
}
module avmContainerApp_API_update 'br/public:avm/res/app/container-app:0.19.0' = {
@@ -1754,6 +1782,9 @@ module avmContainerApp_API_update 'br/public:avm/res/app/container-app:0.19.0' =
]
}
}
+ dependsOn: [
+ cognitiveServicePrivateEndpoint
+ ]
}
// ========== Container App Workflow Update ========== //
diff --git a/infra/main.json b/infra/main.json
index f1569c33..0a31a398 100644
--- a/infra/main.json
+++ b/infra/main.json
@@ -5,8 +5,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "10682864961053259354"
+ "version": "0.40.2.10011",
+ "templateHash": "91469570804589345"
},
"name": "Content Processing Solution Accelerator",
"description": "Bicep template to deploy the Content Processing Solution Accelerator with AVM compliance."
@@ -338,8 +338,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "2779842231546071291"
+ "version": "0.40.2.10011",
+ "templateHash": "637986880127430337"
}
},
"definitions": {
@@ -4916,7 +4916,7 @@
"osType": {
"value": "Windows"
},
- "vmSize": "[if(empty(parameters('vmSize')), createObject('value', 'Standard_DS2_v2'), createObject('value', parameters('vmSize')))]",
+ "vmSize": "[if(empty(parameters('vmSize')), createObject('value', 'Standard_D2s_v5'), createObject('value', parameters('vmSize')))]",
"adminUsername": "[if(empty(parameters('vmAdminUsername')), createObject('value', 'JumpboxAdminUser'), createObject('value', parameters('vmAdminUsername')))]",
"adminPassword": "[if(empty(parameters('vmAdminPassword')), createObject('value', 'JumpboxAdminP@ssw0rd1234!'), createObject('value', parameters('vmAdminPassword')))]",
"managedIdentities": {
@@ -19215,8 +19215,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "9967760373683235080"
+ "version": "0.40.2.10011",
+ "templateHash": "3741201002953968110"
}
},
"parameters": {
@@ -23221,8 +23221,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "11438993289824448790"
+ "version": "0.40.2.10011",
+ "templateHash": "10844547551448610415"
}
},
"parameters": {
@@ -23813,8 +23813,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "18073394536155497558"
+ "version": "0.40.2.10011",
+ "templateHash": "7885429842089695683"
},
"name": "Container Registry Module"
},
@@ -35177,8 +35177,8 @@
"avmContainerApp_API",
"avmContainerApp_Workflow",
"avmManagedIdentity",
- "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)]",
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageQueue)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)]",
"virtualNetwork"
]
},
@@ -35289,8 +35289,7 @@
}
]
},
- "publicNetworkAccess": "[if(parameters('enablePrivateNetworking'), createObject('value', 'Disabled'), createObject('value', 'Enabled'))]",
- "privateEndpoints": "[if(and(parameters('enablePrivateNetworking'), empty(variables('existingProjectResourceId'))), createObject('value', createArray(createObject('name', format('pep-aiservices-{0}', variables('solutionSuffix')), 'customNetworkInterfaceName', format('nic-aiservices-{0}', variables('solutionSuffix')), 'privateEndpointResourceId', reference('virtualNetwork').outputs.resourceId.value, 'privateDnsZoneGroup', createObject('privateDnsZoneGroupConfigs', createArray(createObject('name', 'ai-services-dns-zone-cognitiveservices', 'privateDnsZoneResourceId', reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)).outputs.resourceId.value), createObject('name', 'ai-services-dns-zone-openai', 'privateDnsZoneResourceId', reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)).outputs.resourceId.value), createObject('name', 'ai-services-dns-zone-aiservices', 'privateDnsZoneResourceId', reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)).outputs.resourceId.value), createObject('name', 'ai-services-dns-zone-contentunderstanding', 'privateDnsZoneResourceId', reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').contentUnderstanding)).outputs.resourceId.value))), 'subnetResourceId', reference('virtualNetwork').outputs.backendSubnetResourceId.value))), createObject('value', createArray()))]"
+ "publicNetworkAccess": "[if(parameters('enablePrivateNetworking'), createObject('value', 'Disabled'), createObject('value', 'Enabled'))]"
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
@@ -35299,8 +35298,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "11365341673325597162"
+ "version": "0.40.2.10011",
+ "templateHash": "7557665774149769517"
},
"name": "Cognitive Services",
"description": "This module deploys a Cognitive Service."
@@ -36549,8 +36548,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "15006072223125242147"
+ "version": "0.40.2.10011",
+ "templateHash": "6588447351857766372"
}
},
"definitions": {
@@ -37513,7 +37512,7 @@
"condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
"type": "Microsoft.Authorization/locks",
"apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]",
+ "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
"name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
"properties": {
"level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
@@ -37527,7 +37526,7 @@
},
"type": "Microsoft.Insights/diagnosticSettings",
"apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]",
+ "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
"name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
"properties": {
"copy": [
@@ -37565,7 +37564,7 @@
},
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]",
+ "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
"name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.CognitiveServices/accounts', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
"properties": {
"roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
@@ -38358,8 +38357,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "12797226417049698978"
+ "version": "0.40.2.10011",
+ "templateHash": "14939823368517410024"
}
},
"definitions": {
@@ -38512,8 +38511,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "422299638943108486"
+ "version": "0.40.2.10011",
+ "templateHash": "13151306134286549002"
}
},
"definitions": {
@@ -38730,8 +38729,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "15006072223125242147"
+ "version": "0.40.2.10011",
+ "templateHash": "6588447351857766372"
}
},
"definitions": {
@@ -39694,7 +39693,7 @@
"condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
"type": "Microsoft.Authorization/locks",
"apiVersion": "2020-05-01",
- "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]",
+ "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
"name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
"properties": {
"level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
@@ -39708,7 +39707,7 @@
},
"type": "Microsoft.Insights/diagnosticSettings",
"apiVersion": "2021-05-01-preview",
- "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]",
+ "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
"name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
"properties": {
"copy": [
@@ -39746,7 +39745,7 @@
},
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]",
+ "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
"name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.CognitiveServices/accounts', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
"properties": {
"roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
@@ -40539,8 +40538,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "12797226417049698978"
+ "version": "0.40.2.10011",
+ "templateHash": "14939823368517410024"
}
},
"definitions": {
@@ -40693,8 +40692,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.39.26.7824",
- "templateHash": "422299638943108486"
+ "version": "0.40.2.10011",
+ "templateHash": "13151306134286549002"
}
},
"definitions": {
@@ -40935,18 +40934,14 @@
"avmContainerApp",
"avmContainerApp_Workflow",
"avmManagedIdentity",
- "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]",
- "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)]",
- "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').contentUnderstanding)]",
- "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)]",
- "logAnalyticsWorkspace",
- "virtualNetwork"
+ "logAnalyticsWorkspace"
]
},
- "avmAiServices_cu": {
+ "cognitiveServicePrivateEndpoint": {
+ "condition": "[and(parameters('enablePrivateNetworking'), empty(variables('existingProjectResourceId')))]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2025-04-01",
- "name": "[take(format('avm.res.cognitive-services.account.content-understanding.{0}', variables('solutionSuffix')), 64)]",
+ "name": "[take(format('avm.res.network.private-endpoint.{0}', variables('solutionSuffix')), 64)]",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
@@ -40954,62 +40949,55 @@
"mode": "Incremental",
"parameters": {
"name": {
- "value": "[format('aicu-{0}', variables('solutionSuffix'))]"
+ "value": "[format('pep-aiservices-{0}', variables('solutionSuffix'))]"
},
"location": {
- "value": "[parameters('contentUnderstandingLocation')]"
- },
- "sku": {
- "value": "S0"
- },
- "managedIdentities": {
- "value": {
- "systemAssigned": false,
- "userAssignedResourceIds": [
- "[reference('avmManagedIdentity').outputs.resourceId.value]"
- ]
- }
- },
- "kind": {
- "value": "AIServices"
+ "value": "[parameters('location')]"
},
"tags": {
- "value": {
- "app": "[variables('solutionSuffix')]",
- "location": "[parameters('location')]"
- }
- },
- "customSubDomainName": {
- "value": "[format('aicu-{0}', variables('solutionSuffix'))]"
- },
- "disableLocalAuth": {
- "value": true
- },
- "enableTelemetry": {
- "value": "[parameters('enableTelemetry')]"
+ "value": "[parameters('tags')]"
},
- "networkAcls": {
- "value": {
- "bypass": "AzureServices",
- "defaultAction": "Allow"
- }
+ "customNetworkInterfaceName": {
+ "value": "[format('nic-aiservices-{0}', variables('solutionSuffix'))]"
},
- "roleAssignments": {
+ "privateLinkServiceConnections": {
"value": [
{
- "principalId": "[reference('avmContainerApp').outputs.systemAssignedMIPrincipalId.value]",
- "roleDefinitionIdOrName": "a97b65f3-24c7-4388-baec-2e87135dc908",
- "principalType": "ServicePrincipal"
- },
- {
- "principalId": "[reference('avmContainerApp_Workflow').outputs.systemAssignedMIPrincipalId.value]",
- "roleDefinitionIdOrName": "a97b65f3-24c7-4388-baec-2e87135dc908",
- "principalType": "ServicePrincipal"
+ "name": "[format('pep-aiservices-{0}-cognitiveservices-connection', variables('solutionSuffix'))]",
+ "properties": {
+ "privateLinkServiceId": "[reference('avmAiServices').outputs.resourceId.value]",
+ "groupIds": [
+ "account"
+ ]
+ }
}
]
},
- "publicNetworkAccess": "[if(parameters('enablePrivateNetworking'), createObject('value', 'Disabled'), createObject('value', 'Enabled'))]",
- "privateEndpoints": "[if(parameters('enablePrivateNetworking'), createObject('value', createArray(createObject('name', format('pep-aicu-{0}', variables('solutionSuffix')), 'customNetworkInterfaceName', format('nic-aicu-{0}', variables('solutionSuffix')), 'privateEndpointResourceId', reference('virtualNetwork').outputs.resourceId.value, 'privateDnsZoneGroup', createObject('privateDnsZoneGroupConfigs', createArray(createObject('name', 'aicu-dns-zone-cognitiveservices', 'privateDnsZoneResourceId', reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)).outputs.resourceId.value), createObject('name', 'aicu-dns-zone-contentunderstanding', 'privateDnsZoneResourceId', reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').contentUnderstanding)).outputs.resourceId.value))), 'subnetResourceId', reference('virtualNetwork').outputs.backendSubnetResourceId.value))), createObject('value', createArray()))]"
+ "privateDnsZoneGroup": {
+ "value": {
+ "privateDnsZoneGroupConfigs": [
+ {
+ "name": "ai-services-dns-zone-cognitiveservices",
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)).outputs.resourceId.value]"
+ },
+ {
+ "name": "ai-services-dns-zone-openai",
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)).outputs.resourceId.value]"
+ },
+ {
+ "name": "ai-services-dns-zone-aiservices",
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)).outputs.resourceId.value]"
+ },
+ {
+ "name": "ai-services-dns-zone-contentunderstanding",
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').contentUnderstanding)).outputs.resourceId.value]"
+ }
+ ]
+ }
+ },
+ "subnetResourceId": {
+ "value": "[reference('virtualNetwork').outputs.backendSubnetResourceId.value]"
+ }
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
@@ -41018,373 +41006,1159 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.37.4.10188",
- "templateHash": "9381727816193702843"
+ "version": "0.30.23.60470",
+ "templateHash": "2541425927059591098"
},
- "name": "Cognitive Services",
- "description": "This module deploys a Cognitive Service."
+ "name": "Private Endpoints",
+ "description": "This module deploys a Private Endpoint.",
+ "owner": "Azure/module-maintainers"
},
"definitions": {
- "privateEndpointOutputType": {
+ "privateDnsZoneGroupType": {
"type": "object",
"properties": {
"name": {
- "type": "string",
- "metadata": {
- "description": "The name of the private endpoint."
- }
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the private endpoint."
- }
- },
- "groupId": {
"type": "string",
"nullable": true,
"metadata": {
- "description": "The group Id for the private endpoint Group."
- }
- },
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "fqdn": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "FQDN that resolves to private endpoint IP address."
- }
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "A list of private IP addresses of the private endpoint."
- }
- }
- }
- },
- "metadata": {
- "description": "The custom DNS configurations of the private endpoint."
+ "description": "Optional. The name of the Private DNS Zone Group."
}
},
- "networkInterfaceResourceIds": {
+ "privateDnsZoneGroupConfigs": {
"type": "array",
"items": {
- "type": "string"
+ "$ref": "#/definitions/privateDnsZoneGroupConfigType"
},
"metadata": {
- "description": "The IDs of the network interfaces associated with the private endpoint."
+ "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones."
}
}
- },
- "metadata": {
- "__bicep_export!": true,
- "description": "The type for the private endpoint output."
}
},
- "deploymentType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of cognitive service account deployment."
- }
- },
- "model": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of Cognitive Services account deployment model."
- }
- },
- "format": {
- "type": "string",
- "metadata": {
- "description": "Required. The format of Cognitive Services account deployment model."
- }
- },
- "version": {
- "type": "string",
- "metadata": {
- "description": "Required. The version of Cognitive Services account deployment model."
- }
+ "roleAssignmentType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
}
},
- "metadata": {
- "description": "Required. Properties of Cognitive Services account deployment model."
- }
- },
- "sku": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the resource model definition representing SKU."
- }
- },
- "capacity": {
- "type": "int",
- "nullable": true,
- "metadata": {
- "description": "Optional. The capacity of the resource model definition representing SKU."
- }
- },
- "tier": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The tier of the resource model definition representing SKU."
- }
- },
- "size": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The size of the resource model definition representing SKU."
- }
- },
- "family": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The family of the resource model definition representing SKU."
- }
+ "roleDefinitionIdOrName": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
}
},
- "nullable": true,
- "metadata": {
- "description": "Optional. The resource model definition representing SKU."
- }
- },
- "raiPolicyName": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name of RAI policy."
- }
- },
- "versionUpgradeOption": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The version upgrade option."
+ "principalId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
+ }
+ },
+ "principalType": {
+ "type": "string",
+ "allowedValues": [
+ "Device",
+ "ForeignGroup",
+ "Group",
+ "ServicePrincipal",
+ "User"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The principal type of the assigned principal ID."
+ }
+ },
+ "description": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The description of the role assignment."
+ }
+ },
+ "condition": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
+ }
+ },
+ "conditionVersion": {
+ "type": "string",
+ "allowedValues": [
+ "2.0"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Version of the condition."
+ }
+ },
+ "delegatedManagedIdentityResourceId": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The Resource Id of the delegated managed identity resource."
+ }
}
}
},
- "metadata": {
- "__bicep_export!": true,
- "description": "The type for a cognitive services account deployment."
- }
+ "nullable": true
},
- "endpointType": {
+ "lockType": {
"type": "object",
"properties": {
"name": {
"type": "string",
"nullable": true,
"metadata": {
- "description": "Type of the endpoint."
+ "description": "Optional. Specify the name of lock."
}
},
- "endpoint": {
+ "kind": {
"type": "string",
+ "allowedValues": [
+ "CanNotDelete",
+ "None",
+ "ReadOnly"
+ ],
"nullable": true,
"metadata": {
- "description": "The endpoint URI."
+ "description": "Optional. Specify the type of lock."
}
}
},
- "metadata": {
- "__bicep_export!": true,
- "description": "The type for a cognitive services account endpoint."
- }
+ "nullable": true
},
- "secretsExportConfigurationType": {
- "type": "object",
- "properties": {
- "keyVaultResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The key vault name where to store the keys and connection strings generated by the modules."
- }
- },
- "accessKey1Name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name for the accessKey1 secret to create."
- }
- },
- "accessKey2Name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The name for the accessKey2 secret to create."
+ "ipConfigurationsType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the resource that is unique within a resource group."
+ }
+ },
+ "properties": {
+ "type": "object",
+ "properties": {
+ "groupId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
+ }
+ },
+ "memberName": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
+ }
+ },
+ "privateIPAddress": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. A private IP address obtained from the private endpoint's subnet."
+ }
+ }
+ },
+ "metadata": {
+ "description": "Required. Properties of private endpoint IP configurations."
+ }
}
}
},
- "metadata": {
- "__bicep_export!": true,
- "description": "The type of the secrets exported to the provided Key Vault."
- }
+ "nullable": true
},
- "commitmentPlanType": {
- "type": "object",
- "properties": {
- "autoRenew": {
- "type": "bool",
- "metadata": {
- "description": "Required. Whether the plan should auto-renew at the end of the current commitment period."
- }
- },
- "current": {
- "type": "object",
+ "manualPrivateLinkServiceConnectionsType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the private link service connection."
+ }
+ },
"properties": {
- "count": {
- "type": "int",
- "metadata": {
- "description": "Required. The number of committed instances (e.g., number of containers or cores)."
+ "type": "object",
+ "properties": {
+ "groupIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "metadata": {
+ "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`."
+ }
+ },
+ "privateLinkServiceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The resource id of private link service."
+ }
+ },
+ "requestMessage": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars."
+ }
}
},
- "tier": {
- "type": "string",
- "metadata": {
- "description": "Required. The tier of the commitment plan (e.g., T1, T2)."
- }
+ "metadata": {
+ "description": "Required. Properties of private link service connection."
}
- },
- "metadata": {
- "description": "Required. The current commitment configuration."
- }
- },
- "hostingModel": {
- "type": "string",
- "metadata": {
- "description": "Required. The hosting model for the commitment plan. (e.g., DisconnectedContainer, ConnectedContainer, ProvisionedWeb, Web)."
- }
- },
- "planType": {
- "type": "string",
- "metadata": {
- "description": "Required. The plan type indicating which capability the plan applies to (e.g., NTTS, STT, CUSTOMSTT, ADDON)."
- }
- },
- "commitmentPlanGuid": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The unique identifier of an existing commitment plan to update. Set to null to create a new plan."
}
- },
- "next": {
- "type": "object",
+ }
+ },
+ "nullable": true
+ },
+ "privateLinkServiceConnectionsType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the private link service connection."
+ }
+ },
"properties": {
- "count": {
- "type": "int",
- "metadata": {
- "description": "Required. The number of committed instances for the next period."
+ "type": "object",
+ "properties": {
+ "groupIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "metadata": {
+ "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`."
+ }
+ },
+ "privateLinkServiceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The resource id of private link service."
+ }
+ },
+ "requestMessage": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars."
+ }
}
},
- "tier": {
- "type": "string",
- "metadata": {
- "description": "Required. The tier for the next commitment period."
- }
+ "metadata": {
+ "description": "Required. Properties of private link service connection."
}
- },
- "nullable": true,
- "metadata": {
- "description": "Optional. The configuration of the next commitment period, if scheduled."
}
}
},
- "metadata": {
- "__bicep_export!": true,
- "description": "The type for a disconnected container commitment plan."
- }
+ "nullable": true
},
- "networkInjectionType": {
- "type": "object",
- "properties": {
- "scenario": {
- "type": "string",
- "allowedValues": [
- "agent",
- "none"
- ],
- "metadata": {
- "description": "Required. The scenario for the network injection."
- }
- },
- "subnetResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The Resource ID of the subnet on the Virtual Network on which to inject."
- }
- },
- "useMicrosoftManagedNetwork": {
- "type": "bool",
- "nullable": true,
- "metadata": {
- "description": "Optional. Whether to use Microsoft Managed Network. Defaults to false."
+ "customDnsConfigType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "fqdn": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. FQDN that resolves to private endpoint IP address."
+ }
+ },
+ "ipAddresses": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "metadata": {
+ "description": "Required. A list of private IP addresses of the private endpoint."
+ }
}
}
},
- "metadata": {
- "__bicep_export!": true,
- "description": "Type for network configuration in AI Foundry where virtual network injection occurs to secure scenarios like Agents entirely within a private network."
- }
+ "nullable": true
},
- "_1.secretSetOutputType": {
+ "privateDnsZoneGroupConfigType": {
"type": "object",
"properties": {
- "secretResourceId": {
- "type": "string",
- "metadata": {
- "description": "The resourceId of the exported secret."
- }
- },
- "secretUri": {
+ "name": {
"type": "string",
+ "nullable": true,
"metadata": {
- "description": "The secret URI of the exported secret."
+ "description": "Optional. The name of the private DNS zone group config."
}
},
- "secretUriWithVersion": {
+ "privateDnsZoneResourceId": {
"type": "string",
"metadata": {
- "description": "The secret URI with version of the exported secret."
+ "description": "Required. The resource id of the private DNS zone."
}
}
},
"metadata": {
- "description": "An AVM-aligned type for the output of the secret set via the secrets export feature.",
"__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.6.0"
+ "sourceTemplate": "private-dns-zone-group/main.bicep"
}
}
+ }
+ },
+ "parameters": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the private endpoint resource to create."
+ }
},
- "_2.lockType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. Specify the name of lock."
- }
+ "subnetResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Resource ID of the subnet where the endpoint needs to be created."
+ }
+ },
+ "applicationSecurityGroupResourceIds": {
+ "type": "array",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Application security groups in which the private endpoint IP configuration is included."
+ }
+ },
+ "customNetworkInterfaceName": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The custom name of the network interface attached to the private endpoint."
+ }
+ },
+ "ipConfigurations": {
+ "$ref": "#/definitions/ipConfigurationsType",
+ "metadata": {
+ "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints."
+ }
+ },
+ "privateDnsZoneGroup": {
+ "$ref": "#/definitions/privateDnsZoneGroupType",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The private DNS zone group to configure for the private endpoint."
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Optional. Location for all Resources."
+ }
+ },
+ "lock": {
+ "$ref": "#/definitions/lockType",
+ "metadata": {
+ "description": "Optional. The lock settings of the service."
+ }
+ },
+ "roleAssignments": {
+ "$ref": "#/definitions/roleAssignmentType",
+ "metadata": {
+ "description": "Optional. Array of role assignments to create."
+ }
+ },
+ "tags": {
+ "type": "object",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Tags to be applied on all resources/resource groups in this deployment."
+ }
+ },
+ "customDnsConfigs": {
+ "$ref": "#/definitions/customDnsConfigType",
+ "metadata": {
+ "description": "Optional. Custom DNS configurations."
+ }
+ },
+ "manualPrivateLinkServiceConnections": {
+ "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType",
+ "metadata": {
+ "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource."
+ }
+ },
+ "privateLinkServiceConnections": {
+ "$ref": "#/definitions/privateLinkServiceConnectionsType",
+ "metadata": {
+ "description": "Optional. A grouping of information about the connection to the remote resource."
+ }
+ },
+ "enableTelemetry": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Optional. Enable/Disable usage telemetry for module."
+ }
+ }
+ },
+ "variables": {
+ "copy": [
+ {
+ "name": "formattedRoleAssignments",
+ "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
+ "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
+ }
+ ],
+ "builtInRoleNames": {
+ "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
+ "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]",
+ "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]",
+ "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]",
+ "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]",
+ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]",
+ "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
+ "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]",
+ "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
+ "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]"
+ }
+ },
+ "resources": {
+ "avmTelemetry": {
+ "condition": "[parameters('enableTelemetry')]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2024-03-01",
+ "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.8.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
+ "properties": {
+ "mode": "Incremental",
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "resources": [],
+ "outputs": {
+ "telemetry": {
+ "type": "String",
+ "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
+ }
+ }
+ }
+ }
+ },
+ "privateEndpoint": {
+ "type": "Microsoft.Network/privateEndpoints",
+ "apiVersion": "2023-11-01",
+ "name": "[parameters('name')]",
+ "location": "[parameters('location')]",
+ "tags": "[parameters('tags')]",
+ "properties": {
+ "copy": [
+ {
+ "name": "applicationSecurityGroups",
+ "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]",
+ "input": {
+ "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]"
+ }
+ }
+ ],
+ "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]",
+ "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]",
+ "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]",
+ "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]",
+ "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]",
+ "subnet": {
+ "id": "[parameters('subnetResourceId')]"
+ }
+ }
+ },
+ "privateEndpoint_lock": {
+ "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
+ "type": "Microsoft.Authorization/locks",
+ "apiVersion": "2020-05-01",
+ "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]",
+ "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
+ "properties": {
+ "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
+ "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
+ },
+ "dependsOn": [
+ "privateEndpoint"
+ ]
+ },
+ "privateEndpoint_roleAssignments": {
+ "copy": {
+ "name": "privateEndpoint_roleAssignments",
+ "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
+ },
+ "type": "Microsoft.Authorization/roleAssignments",
+ "apiVersion": "2022-04-01",
+ "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]",
+ "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
+ "properties": {
+ "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
+ "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
+ "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
+ "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
+ "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
+ "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
+ "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
+ },
+ "dependsOn": [
+ "privateEndpoint"
+ ]
+ },
+ "privateEndpoint_privateDnsZoneGroup": {
+ "condition": "[not(empty(parameters('privateDnsZoneGroup')))]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2022-09-01",
+ "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "name": {
+ "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]"
+ },
+ "privateEndpointName": {
+ "value": "[parameters('name')]"
+ },
+ "privateDnsZoneConfigs": {
+ "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]"
+ }
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "languageVersion": "2.0",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.30.23.60470",
+ "templateHash": "12329174801198479603"
+ },
+ "name": "Private Endpoint Private DNS Zone Groups",
+ "description": "This module deploys a Private Endpoint Private DNS Zone Group.",
+ "owner": "Azure/module-maintainers"
+ },
+ "definitions": {
+ "privateDnsZoneGroupConfigType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name of the private DNS zone group config."
+ }
+ },
+ "privateDnsZoneResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The resource id of the private DNS zone."
+ }
+ }
+ },
+ "metadata": {
+ "__bicep_export!": true
+ }
+ }
+ },
+ "parameters": {
+ "privateEndpointName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment."
+ }
+ },
+ "privateDnsZoneConfigs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/privateDnsZoneGroupConfigType"
+ },
+ "minLength": 1,
+ "maxLength": 5,
+ "metadata": {
+ "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones."
+ }
+ },
+ "name": {
+ "type": "string",
+ "defaultValue": "default",
+ "metadata": {
+ "description": "Optional. The name of the private DNS zone group."
+ }
+ }
+ },
+ "variables": {
+ "copy": [
+ {
+ "name": "privateDnsZoneConfigsVar",
+ "count": "[length(parameters('privateDnsZoneConfigs'))]",
+ "input": {
+ "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]",
+ "properties": {
+ "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]"
+ }
+ }
+ }
+ ]
+ },
+ "resources": {
+ "privateEndpoint": {
+ "existing": true,
+ "type": "Microsoft.Network/privateEndpoints",
+ "apiVersion": "2023-11-01",
+ "name": "[parameters('privateEndpointName')]"
+ },
+ "privateDnsZoneGroup": {
+ "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
+ "apiVersion": "2023-11-01",
+ "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]",
+ "properties": {
+ "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]"
+ },
+ "dependsOn": [
+ "privateEndpoint"
+ ]
+ }
+ },
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the private endpoint DNS zone group."
+ },
+ "value": "[parameters('name')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the private endpoint DNS zone group."
+ },
+ "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource group the private endpoint DNS zone group was deployed into."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "privateEndpoint"
+ ]
+ }
+ },
+ "outputs": {
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource group the private endpoint was deployed into."
+ },
+ "value": "[resourceGroup().name]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the private endpoint."
+ },
+ "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]"
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the private endpoint."
+ },
+ "value": "[parameters('name')]"
+ },
+ "location": {
+ "type": "string",
+ "metadata": {
+ "description": "The location the resource was deployed into."
+ },
+ "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]"
+ },
+ "customDnsConfig": {
+ "$ref": "#/definitions/customDnsConfigType",
+ "metadata": {
+ "description": "The custom DNS configurations of the private endpoint."
+ },
+ "value": "[reference('privateEndpoint').customDnsConfigs]"
+ },
+ "networkInterfaceIds": {
+ "type": "array",
+ "metadata": {
+ "description": "The IDs of the network interfaces associated with the private endpoint."
+ },
+ "value": "[reference('privateEndpoint').networkInterfaces]"
+ },
+ "groupId": {
+ "type": "string",
+ "metadata": {
+ "description": "The group Id for the private endpoint Group."
+ },
+ "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "avmAiServices",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').contentUnderstanding)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]",
+ "virtualNetwork"
+ ]
+ },
+ "avmAiServices_cu": {
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2025-04-01",
+ "name": "[take(format('avm.res.cognitive-services.account.content-understanding.{0}', variables('solutionSuffix')), 64)]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "name": {
+ "value": "[format('aicu-{0}', variables('solutionSuffix'))]"
+ },
+ "location": {
+ "value": "[parameters('contentUnderstandingLocation')]"
+ },
+ "sku": {
+ "value": "S0"
+ },
+ "managedIdentities": {
+ "value": {
+ "systemAssigned": false,
+ "userAssignedResourceIds": [
+ "[reference('avmManagedIdentity').outputs.resourceId.value]"
+ ]
+ }
+ },
+ "kind": {
+ "value": "AIServices"
+ },
+ "tags": {
+ "value": {
+ "app": "[variables('solutionSuffix')]",
+ "location": "[parameters('location')]"
+ }
+ },
+ "customSubDomainName": {
+ "value": "[format('aicu-{0}', variables('solutionSuffix'))]"
+ },
+ "disableLocalAuth": {
+ "value": true
+ },
+ "enableTelemetry": {
+ "value": "[parameters('enableTelemetry')]"
+ },
+ "networkAcls": {
+ "value": {
+ "bypass": "AzureServices",
+ "defaultAction": "Allow"
+ }
+ },
+ "roleAssignments": {
+ "value": [
+ {
+ "principalId": "[reference('avmContainerApp').outputs.systemAssignedMIPrincipalId.value]",
+ "roleDefinitionIdOrName": "a97b65f3-24c7-4388-baec-2e87135dc908",
+ "principalType": "ServicePrincipal"
+ },
+ {
+ "principalId": "[reference('avmContainerApp_Workflow').outputs.systemAssignedMIPrincipalId.value]",
+ "roleDefinitionIdOrName": "a97b65f3-24c7-4388-baec-2e87135dc908",
+ "principalType": "ServicePrincipal"
+ }
+ ]
+ },
+ "publicNetworkAccess": "[if(parameters('enablePrivateNetworking'), createObject('value', 'Disabled'), createObject('value', 'Enabled'))]"
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "languageVersion": "2.0",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.39.26.7824",
+ "templateHash": "6544538318162038728"
+ },
+ "name": "Cognitive Services",
+ "description": "This module deploys a Cognitive Service."
+ },
+ "definitions": {
+ "privateEndpointOutputType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the private endpoint."
+ }
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the private endpoint."
+ }
+ },
+ "groupId": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "The group Id for the private endpoint Group."
+ }
+ },
+ "customDnsConfigs": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "fqdn": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "FQDN that resolves to private endpoint IP address."
+ }
+ },
+ "ipAddresses": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "metadata": {
+ "description": "A list of private IP addresses of the private endpoint."
+ }
+ }
+ }
+ },
+ "metadata": {
+ "description": "The custom DNS configurations of the private endpoint."
+ }
+ },
+ "networkInterfaceResourceIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "metadata": {
+ "description": "The IDs of the network interfaces associated with the private endpoint."
+ }
+ }
+ },
+ "metadata": {
+ "__bicep_export!": true,
+ "description": "The type for the private endpoint output."
+ }
+ },
+ "deploymentType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specify the name of cognitive service account deployment."
+ }
+ },
+ "model": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of Cognitive Services account deployment model."
+ }
+ },
+ "format": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The format of Cognitive Services account deployment model."
+ }
+ },
+ "version": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The version of Cognitive Services account deployment model."
+ }
+ }
+ },
+ "metadata": {
+ "description": "Required. Properties of Cognitive Services account deployment model."
+ }
+ },
+ "sku": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the resource model definition representing SKU."
+ }
+ },
+ "capacity": {
+ "type": "int",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The capacity of the resource model definition representing SKU."
+ }
+ },
+ "tier": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The tier of the resource model definition representing SKU."
+ }
+ },
+ "size": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The size of the resource model definition representing SKU."
+ }
+ },
+ "family": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The family of the resource model definition representing SKU."
+ }
+ }
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The resource model definition representing SKU."
+ }
+ },
+ "raiPolicyName": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name of RAI policy."
+ }
+ },
+ "versionUpgradeOption": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The version upgrade option."
+ }
+ }
+ },
+ "metadata": {
+ "__bicep_export!": true,
+ "description": "The type for a cognitive services account deployment."
+ }
+ },
+ "endpointType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Type of the endpoint."
+ }
+ },
+ "endpoint": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "The endpoint URI."
+ }
+ }
+ },
+ "metadata": {
+ "__bicep_export!": true,
+ "description": "The type for a cognitive services account endpoint."
+ }
+ },
+ "secretsExportConfigurationType": {
+ "type": "object",
+ "properties": {
+ "keyVaultResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The key vault name where to store the keys and connection strings generated by the modules."
+ }
+ },
+ "accessKey1Name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name for the accessKey1 secret to create."
+ }
+ },
+ "accessKey2Name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name for the accessKey2 secret to create."
+ }
+ }
+ },
+ "metadata": {
+ "__bicep_export!": true,
+ "description": "The type of the secrets exported to the provided Key Vault."
+ }
+ },
+ "commitmentPlanType": {
+ "type": "object",
+ "properties": {
+ "autoRenew": {
+ "type": "bool",
+ "metadata": {
+ "description": "Required. Whether the plan should auto-renew at the end of the current commitment period."
+ }
+ },
+ "current": {
+ "type": "object",
+ "properties": {
+ "count": {
+ "type": "int",
+ "metadata": {
+ "description": "Required. The number of committed instances (e.g., number of containers or cores)."
+ }
+ },
+ "tier": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The tier of the commitment plan (e.g., T1, T2)."
+ }
+ }
+ },
+ "metadata": {
+ "description": "Required. The current commitment configuration."
+ }
+ },
+ "hostingModel": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The hosting model for the commitment plan. (e.g., DisconnectedContainer, ConnectedContainer, ProvisionedWeb, Web)."
+ }
+ },
+ "planType": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The plan type indicating which capability the plan applies to (e.g., NTTS, STT, CUSTOMSTT, ADDON)."
+ }
+ },
+ "commitmentPlanGuid": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The unique identifier of an existing commitment plan to update. Set to null to create a new plan."
+ }
+ },
+ "next": {
+ "type": "object",
+ "properties": {
+ "count": {
+ "type": "int",
+ "metadata": {
+ "description": "Required. The number of committed instances for the next period."
+ }
+ },
+ "tier": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The tier for the next commitment period."
+ }
+ }
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The configuration of the next commitment period, if scheduled."
+ }
+ }
+ },
+ "metadata": {
+ "__bicep_export!": true,
+ "description": "The type for a disconnected container commitment plan."
+ }
+ },
+ "networkInjectionType": {
+ "type": "object",
+ "properties": {
+ "scenario": {
+ "type": "string",
+ "allowedValues": [
+ "agent",
+ "none"
+ ],
+ "metadata": {
+ "description": "Required. The scenario for the network injection."
+ }
+ },
+ "subnetResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The Resource ID of the subnet on the Virtual Network on which to inject."
+ }
+ },
+ "useMicrosoftManagedNetwork": {
+ "type": "bool",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Whether to use Microsoft Managed Network. Defaults to false."
+ }
+ }
+ },
+ "metadata": {
+ "__bicep_export!": true,
+ "description": "Type for network configuration in AI Foundry where virtual network injection occurs to secure scenarios like Agents entirely within a private network."
+ }
+ },
+ "_1.secretSetOutputType": {
+ "type": "object",
+ "properties": {
+ "secretResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resourceId of the exported secret."
+ }
+ },
+ "secretUri": {
+ "type": "string",
+ "metadata": {
+ "description": "The secret URI of the exported secret."
+ }
+ },
+ "secretUriWithVersion": {
+ "type": "string",
+ "metadata": {
+ "description": "The secret URI with version of the exported secret."
+ }
+ }
+ },
+ "metadata": {
+ "description": "An AVM-aligned type for the output of the secret set via the secrets export feature.",
+ "__bicep_imported_from!": {
+ "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.6.0"
+ }
+ }
+ },
+ "_2.lockType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specify the name of lock."
+ }
},
"kind": {
"type": "string",
@@ -42364,14 +43138,15 @@
"Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
"Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]",
"User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
- }
+ },
+ "isHSMManagedCMK": "[equals(tryGet(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), ''), '/'), 7), 'managedHSMs')]"
},
"resources": {
"cMKKeyVault::cMKKey": {
- "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]",
+ "condition": "[and(and(not(empty(parameters('customerManagedKey'))), not(variables('isHSMManagedCMK'))), and(not(empty(parameters('customerManagedKey'))), not(variables('isHSMManagedCMK'))))]",
"existing": true,
"type": "Microsoft.KeyVault/vaults/keys",
- "apiVersion": "2024-11-01",
+ "apiVersion": "2025-05-01",
"subscriptionId": "[split(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '/')[2]]",
"resourceGroup": "[split(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '/')[4]]",
"name": "[format('{0}/{1}', last(split(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '/')), tryGet(parameters('customerManagedKey'), 'keyName'))]"
@@ -42380,7 +43155,7 @@
"condition": "[parameters('enableTelemetry')]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.cognitiveservices-account.{0}.{1}', replace('0.13.2', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
+ "name": "[format('46d3xbcp.res.cognitiveservices-account.{0}.{1}', replace('0.14.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
"properties": {
"mode": "Incremental",
"template": {
@@ -42397,10 +43172,10 @@
}
},
"cMKKeyVault": {
- "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]",
+ "condition": "[and(not(empty(parameters('customerManagedKey'))), not(variables('isHSMManagedCMK')))]",
"existing": true,
"type": "Microsoft.KeyVault/vaults",
- "apiVersion": "2024-11-01",
+ "apiVersion": "2025-05-01",
"subscriptionId": "[split(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '/')[2]]",
"resourceGroup": "[split(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '/')[4]]",
"name": "[last(split(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '/'))]"
@@ -42434,7 +43209,7 @@
"allowedFqdnList": "[parameters('allowedFqdnList')]",
"apiProperties": "[parameters('apiProperties')]",
"disableLocalAuth": "[parameters('disableLocalAuth')]",
- "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('keySource', 'Microsoft.KeyVault', 'keyVaultProperties', createObject('identityClientId', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), ''))), reference('cMKUserAssignedIdentity').clientId, null()), 'keyVaultUri', reference('cMKKeyVault').vaultUri, 'keyName', parameters('customerManagedKey').keyName, 'keyVersion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), tryGet(parameters('customerManagedKey'), 'keyVersion'), last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/'))))), null())]",
+ "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('keySource', 'Microsoft.KeyVault', 'keyVaultProperties', createObject('identityClientId', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), ''))), reference('cMKUserAssignedIdentity').clientId, null()), 'keyVaultUri', if(not(variables('isHSMManagedCMK')), reference('cMKKeyVault').vaultUri, format('https://{0}.managedhsm.azure.net/', last(split(parameters('customerManagedKey').keyVaultResourceId, '/')))), 'keyName', parameters('customerManagedKey').keyName, 'keyVersion', if(not(empty(tryGet(parameters('customerManagedKey'), 'keyVersion'))), parameters('customerManagedKey').keyVersion, if(not(variables('isHSMManagedCMK')), last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/')), fail('Managed HSM CMK encryption requires specifying the ''keyVersion''.'))))), null())]",
"migrationToken": "[parameters('migrationToken')]",
"restore": "[parameters('restore')]",
"restrictOutboundNetworkAccess": "[parameters('restrictOutboundNetworkAccess')]",
@@ -42563,7 +43338,7 @@
"count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]"
},
"type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
+ "apiVersion": "2025-04-01",
"name": "[format('{0}-cognitiveService-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
"subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), resourceGroup().id), '/')[2]]",
"resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), resourceGroup().id), '/')[4]]",
@@ -42619,8 +43394,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.34.44.8038",
- "templateHash": "12389807800450456797"
+ "version": "0.38.5.1644",
+ "templateHash": "16604612898799598358"
},
"name": "Private Endpoints",
"description": "This module deploys a Private Endpoint."
@@ -42647,115 +43422,8 @@
}
},
"metadata": {
- "__bicep_export!": true
- }
- },
- "ipConfigurationType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the resource that is unique within a resource group."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupId": {
- "type": "string",
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
- }
- },
- "memberName": {
- "type": "string",
- "metadata": {
- "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
- }
- },
- "privateIPAddress": {
- "type": "string",
- "metadata": {
- "description": "Required. A private IP address obtained from the private endpoint's subnet."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private endpoint IP configurations."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "privateLinkServiceConnectionType": {
- "type": "object",
- "properties": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "Required. The name of the private link service connection."
- }
- },
- "properties": {
- "type": "object",
- "properties": {
- "groupIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`."
- }
- },
- "privateLinkServiceId": {
- "type": "string",
- "metadata": {
- "description": "Required. The resource id of private link service."
- }
- },
- "requestMessage": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars."
- }
- }
- },
- "metadata": {
- "description": "Required. Properties of private link service connection."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
- }
- },
- "customDnsConfigType": {
- "type": "object",
- "properties": {
- "fqdn": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. FQDN that resolves to private endpoint IP address."
- }
- },
- "ipAddresses": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "Required. A list of private IP addresses of the private endpoint."
- }
- }
- },
- "metadata": {
- "__bicep_export!": true
+ "__bicep_export!": true,
+ "description": "The type of a private dns zone group."
}
},
"lockType": {
@@ -42779,12 +43447,19 @@
"metadata": {
"description": "Optional. Specify the type of lock."
}
+ },
+ "notes": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specify the notes of the lock."
+ }
}
},
"metadata": {
"description": "An AVM-aligned type for a lock.",
"__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
+ "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.6.1"
}
}
},
@@ -42806,6 +43481,7 @@
}
},
"metadata": {
+ "description": "The type of a private DNS zone group configuration.",
"__bicep_imported_from!": {
"sourceTemplate": "private-dns-zone-group/main.bicep"
}
@@ -42882,7 +43558,7 @@
"metadata": {
"description": "An AVM-aligned type for a role assignment.",
"__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
+ "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.6.1"
}
}
}
@@ -42919,13 +43595,13 @@
},
"ipConfigurations": {
"type": "array",
- "items": {
- "$ref": "#/definitions/ipConfigurationType"
- },
- "nullable": true,
"metadata": {
+ "__bicep_resource_derived_type!": {
+ "source": "Microsoft.Network/privateEndpoints@2024-01-01#properties/properties/properties/ipConfigurations"
+ },
"description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints."
- }
+ },
+ "nullable": true
},
"privateDnsZoneGroup": {
"$ref": "#/definitions/privateDnsZoneGroupType",
@@ -42960,40 +43636,43 @@
},
"tags": {
"type": "object",
- "nullable": true,
"metadata": {
+ "__bicep_resource_derived_type!": {
+ "source": "Microsoft.Network/privateEndpoints@2024-01-01#properties/tags"
+ },
"description": "Optional. Tags to be applied on all resources/resource groups in this deployment."
- }
+ },
+ "nullable": true
},
"customDnsConfigs": {
"type": "array",
- "items": {
- "$ref": "#/definitions/customDnsConfigType"
- },
- "nullable": true,
"metadata": {
+ "__bicep_resource_derived_type!": {
+ "source": "Microsoft.Network/privateEndpoints@2024-01-01#properties/properties/properties/customDnsConfigs"
+ },
"description": "Optional. Custom DNS configurations."
- }
+ },
+ "nullable": true
},
"manualPrivateLinkServiceConnections": {
"type": "array",
- "items": {
- "$ref": "#/definitions/privateLinkServiceConnectionType"
- },
- "nullable": true,
"metadata": {
+ "__bicep_resource_derived_type!": {
+ "source": "Microsoft.Network/privateEndpoints@2024-01-01#properties/properties/properties/manualPrivateLinkServiceConnections"
+ },
"description": "Conditional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource. Required if `privateLinkServiceConnections` is empty."
- }
+ },
+ "nullable": true
},
"privateLinkServiceConnections": {
"type": "array",
- "items": {
- "$ref": "#/definitions/privateLinkServiceConnectionType"
- },
- "nullable": true,
"metadata": {
+ "__bicep_resource_derived_type!": {
+ "source": "Microsoft.Network/privateEndpoints@2024-01-01#properties/properties/properties/privateLinkServiceConnections"
+ },
"description": "Conditional. A grouping of information about the connection to the remote resource. Required if `manualPrivateLinkServiceConnections` is empty."
- }
+ },
+ "nullable": true
},
"enableTelemetry": {
"type": "bool",
@@ -43028,8 +43707,8 @@
"avmTelemetry": {
"condition": "[parameters('enableTelemetry')]",
"type": "Microsoft.Resources/deployments",
- "apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.11.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
+ "apiVersion": "2025-04-01",
+ "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.11.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
"properties": {
"mode": "Incremental",
"template": {
@@ -43047,7 +43726,7 @@
},
"privateEndpoint": {
"type": "Microsoft.Network/privateEndpoints",
- "apiVersion": "2024-05-01",
+ "apiVersion": "2024-10-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"tags": "[parameters('tags')]",
@@ -43079,7 +43758,7 @@
"name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
"properties": {
"level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
- "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
+ "notes": "[coalesce(tryGet(parameters('lock'), 'notes'), if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.'))]"
},
"dependsOn": [
"privateEndpoint"
@@ -43110,7 +43789,7 @@
"privateEndpoint_privateDnsZoneGroup": {
"condition": "[not(empty(parameters('privateDnsZoneGroup')))]",
"type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
+ "apiVersion": "2025-04-01",
"name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]",
"properties": {
"expressionEvaluationOptions": {
@@ -43135,8 +43814,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.34.44.8038",
- "templateHash": "13997305779829540948"
+ "version": "0.38.5.1644",
+ "templateHash": "24141742673128945"
},
"name": "Private Endpoint Private DNS Zone Groups",
"description": "This module deploys a Private Endpoint Private DNS Zone Group."
@@ -43160,7 +43839,8 @@
}
},
"metadata": {
- "__bicep_export!": true
+ "__bicep_export!": true,
+ "description": "The type of a private DNS zone group configuration."
}
}
},
@@ -43190,33 +43870,30 @@
}
}
},
- "variables": {
- "copy": [
- {
- "name": "privateDnsZoneConfigsVar",
- "count": "[length(parameters('privateDnsZoneConfigs'))]",
- "input": {
- "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]",
- "properties": {
- "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]"
- }
- }
- }
- ]
- },
"resources": {
"privateEndpoint": {
"existing": true,
"type": "Microsoft.Network/privateEndpoints",
- "apiVersion": "2024-05-01",
+ "apiVersion": "2024-10-01",
"name": "[parameters('privateEndpointName')]"
},
"privateDnsZoneGroup": {
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
- "apiVersion": "2024-05-01",
+ "apiVersion": "2024-10-01",
"name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]",
"properties": {
- "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]"
+ "copy": [
+ {
+ "name": "privateDnsZoneConfigs",
+ "count": "[length(parameters('privateDnsZoneConfigs'))]",
+ "input": {
+ "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigs')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigs')].privateDnsZoneResourceId, '/')))]",
+ "properties": {
+ "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigs')].privateDnsZoneResourceId]"
+ }
+ }
+ }
+ ]
}
}
},
@@ -43250,88 +43927,908 @@
]
}
},
- "outputs": {
- "resourceGroupName": {
- "type": "string",
- "metadata": {
- "description": "The resource group the private endpoint was deployed into."
+ "outputs": {
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource group the private endpoint was deployed into."
+ },
+ "value": "[resourceGroup().name]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the private endpoint."
+ },
+ "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]"
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the private endpoint."
+ },
+ "value": "[parameters('name')]"
+ },
+ "location": {
+ "type": "string",
+ "metadata": {
+ "description": "The location the resource was deployed into."
+ },
+ "value": "[reference('privateEndpoint', '2024-10-01', 'full').location]"
+ },
+ "customDnsConfigs": {
+ "type": "array",
+ "metadata": {
+ "__bicep_resource_derived_type!": {
+ "source": "Microsoft.Network/privateEndpoints@2024-01-01#properties/properties/properties/customDnsConfigs",
+ "output": true
+ },
+ "description": "The custom DNS configurations of the private endpoint."
+ },
+ "value": "[reference('privateEndpoint').customDnsConfigs]"
+ },
+ "networkInterfaceResourceIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "metadata": {
+ "description": "The resource IDs of the network interfaces associated with the private endpoint."
+ },
+ "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]"
+ },
+ "groupId": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "The group Id for the private endpoint Group."
+ },
+ "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'manualPrivateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0), tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'privateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0))]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "cognitiveService"
+ ]
+ },
+ "secretsExport": {
+ "condition": "[not(equals(parameters('secretsExportConfiguration'), null()))]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2025-04-01",
+ "name": "[format('{0}-secrets-kv', uniqueString(deployment().name, parameters('location')))]",
+ "subscriptionId": "[split(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '/')[2]]",
+ "resourceGroup": "[split(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '/')[4]]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "keyVaultName": {
+ "value": "[last(split(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '/'))]"
+ },
+ "secretsToSet": {
+ "value": "[union(createArray(), if(contains(parameters('secretsExportConfiguration'), 'accessKey1Name'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'accessKey1Name'), 'value', listKeys('cognitiveService', '2025-06-01').key1)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'accessKey2Name'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'accessKey2Name'), 'value', listKeys('cognitiveService', '2025-06-01').key2)), createArray()))]"
+ }
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "languageVersion": "2.0",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.39.26.7824",
+ "templateHash": "356315690886888607"
+ }
+ },
+ "definitions": {
+ "secretSetOutputType": {
+ "type": "object",
+ "properties": {
+ "secretResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resourceId of the exported secret."
+ }
+ },
+ "secretUri": {
+ "type": "string",
+ "metadata": {
+ "description": "The secret URI of the exported secret."
+ }
+ },
+ "secretUriWithVersion": {
+ "type": "string",
+ "metadata": {
+ "description": "The secret URI with version of the exported secret."
+ }
+ }
+ },
+ "metadata": {
+ "description": "An AVM-aligned type for the output of the secret set via the secrets export feature.",
+ "__bicep_imported_from!": {
+ "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.6.1"
+ }
+ }
+ },
+ "secretToSetType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the secret to set."
+ }
+ },
+ "value": {
+ "type": "securestring",
+ "metadata": {
+ "description": "Required. The value of the secret to set."
+ }
+ }
+ },
+ "metadata": {
+ "description": "An AVM-aligned type for the secret to set via the secrets export feature.",
+ "__bicep_imported_from!": {
+ "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.6.1"
+ }
+ }
+ }
+ },
+ "parameters": {
+ "keyVaultName": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the Key Vault to set the ecrets in."
+ }
+ },
+ "secretsToSet": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/secretToSetType"
+ },
+ "metadata": {
+ "description": "Required. The secrets to set in the Key Vault."
+ }
+ }
+ },
+ "resources": {
+ "keyVault": {
+ "existing": true,
+ "type": "Microsoft.KeyVault/vaults",
+ "apiVersion": "2025-05-01",
+ "name": "[parameters('keyVaultName')]"
+ },
+ "secrets": {
+ "copy": {
+ "name": "secrets",
+ "count": "[length(parameters('secretsToSet'))]"
+ },
+ "type": "Microsoft.KeyVault/vaults/secrets",
+ "apiVersion": "2025-05-01",
+ "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('secretsToSet')[copyIndex()].name)]",
+ "properties": {
+ "value": "[parameters('secretsToSet')[copyIndex()].value]"
+ }
+ }
+ },
+ "outputs": {
+ "secretsSet": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/secretSetOutputType"
+ },
+ "metadata": {
+ "description": "The references to the secrets exported to the provided Key Vault."
+ },
+ "copy": {
+ "count": "[length(range(0, length(coalesce(parameters('secretsToSet'), createArray()))))]",
+ "input": {
+ "secretResourceId": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('secretsToSet')[range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()]].name)]",
+ "secretUri": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUri]",
+ "secretUriWithVersion": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUriWithVersion]"
+ }
+ }
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "cognitiveService"
+ ]
+ }
+ },
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the cognitive services account."
+ },
+ "value": "[parameters('name')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the cognitive services account."
+ },
+ "value": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource group the cognitive services account was deployed into."
+ },
+ "value": "[resourceGroup().name]"
+ },
+ "endpoint": {
+ "type": "string",
+ "metadata": {
+ "description": "The service endpoint of the cognitive services account."
+ },
+ "value": "[reference('cognitiveService').endpoint]"
+ },
+ "endpoints": {
+ "$ref": "#/definitions/endpointType",
+ "metadata": {
+ "description": "All endpoints available for the cognitive services account, types depends on the cognitive service kind."
+ },
+ "value": "[reference('cognitiveService').endpoints]"
+ },
+ "systemAssignedMIPrincipalId": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "The principal ID of the system assigned identity."
+ },
+ "value": "[tryGet(tryGet(reference('cognitiveService', '2025-06-01', 'full'), 'identity'), 'principalId')]"
+ },
+ "location": {
+ "type": "string",
+ "metadata": {
+ "description": "The location the resource was deployed into."
+ },
+ "value": "[reference('cognitiveService', '2025-06-01', 'full').location]"
+ },
+ "exportedSecrets": {
+ "$ref": "#/definitions/secretsOutputType",
+ "metadata": {
+ "description": "A hashtable of references to the secrets exported to the provided Key Vault. The key of each reference is each secret's name."
+ },
+ "value": "[if(not(equals(parameters('secretsExportConfiguration'), null())), toObject(reference('secretsExport').outputs.secretsSet.value, lambda('secret', last(split(lambdaVariables('secret').secretResourceId, '/'))), lambda('secret', lambdaVariables('secret'))), createObject())]"
+ },
+ "privateEndpoints": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/privateEndpointOutputType"
+ },
+ "metadata": {
+ "description": "The private endpoints of the congitive services account."
+ },
+ "copy": {
+ "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]",
+ "input": {
+ "name": "[reference(format('cognitiveService_privateEndpoints[{0}]', copyIndex())).outputs.name.value]",
+ "resourceId": "[reference(format('cognitiveService_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]",
+ "groupId": "[tryGet(tryGet(reference(format('cognitiveService_privateEndpoints[{0}]', copyIndex())).outputs, 'groupId'), 'value')]",
+ "customDnsConfigs": "[reference(format('cognitiveService_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfigs.value]",
+ "networkInterfaceResourceIds": "[reference(format('cognitiveService_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]"
+ }
+ }
+ },
+ "primaryKey": {
+ "type": "securestring",
+ "nullable": true,
+ "metadata": {
+ "description": "The primary access key."
+ },
+ "value": "[if(not(parameters('disableLocalAuth')), listKeys('cognitiveService', '2025-06-01').key1, null())]"
+ },
+ "secondaryKey": {
+ "type": "securestring",
+ "nullable": true,
+ "metadata": {
+ "description": "The secondary access key."
+ },
+ "value": "[if(not(parameters('disableLocalAuth')), listKeys('cognitiveService', '2025-06-01').key2, null())]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "avmContainerApp",
+ "avmContainerApp_Workflow",
+ "avmManagedIdentity"
+ ]
+ },
+ "contentUnderstandingPrivateEndpoint": {
+ "condition": "[parameters('enablePrivateNetworking')]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2025-04-01",
+ "name": "[take(format('avm.res.network.private-endpoint.aicu-{0}', variables('solutionSuffix')), 64)]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "name": {
+ "value": "[format('pep-aicu-{0}', variables('solutionSuffix'))]"
+ },
+ "location": {
+ "value": "[parameters('location')]"
+ },
+ "tags": {
+ "value": "[parameters('tags')]"
+ },
+ "customNetworkInterfaceName": {
+ "value": "[format('nic-aicu-{0}', variables('solutionSuffix'))]"
+ },
+ "privateLinkServiceConnections": {
+ "value": [
+ {
+ "name": "[format('pep-aicu-{0}-cognitiveservices-connection', variables('solutionSuffix'))]",
+ "properties": {
+ "privateLinkServiceId": "[reference('avmAiServices_cu').outputs.resourceId.value]",
+ "groupIds": [
+ "account"
+ ]
+ }
+ }
+ ]
+ },
+ "privateDnsZoneGroup": {
+ "value": {
+ "privateDnsZoneGroupConfigs": [
+ {
+ "name": "aicu-dns-zone-cognitiveservices",
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)).outputs.resourceId.value]"
+ },
+ {
+ "name": "ai-services-dns-zone-aiservices",
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)).outputs.resourceId.value]"
+ },
+ {
+ "name": "aicu-dns-zone-contentunderstanding",
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').contentUnderstanding)).outputs.resourceId.value]"
+ }
+ ]
+ }
+ },
+ "subnetResourceId": {
+ "value": "[reference('virtualNetwork').outputs.backendSubnetResourceId.value]"
+ }
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "languageVersion": "2.0",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.30.23.60470",
+ "templateHash": "2541425927059591098"
+ },
+ "name": "Private Endpoints",
+ "description": "This module deploys a Private Endpoint.",
+ "owner": "Azure/module-maintainers"
+ },
+ "definitions": {
+ "privateDnsZoneGroupType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name of the Private DNS Zone Group."
+ }
+ },
+ "privateDnsZoneGroupConfigs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/privateDnsZoneGroupConfigType"
+ },
+ "metadata": {
+ "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones."
+ }
+ }
+ }
+ },
+ "roleAssignmentType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated."
+ }
+ },
+ "roleDefinitionIdOrName": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'."
+ }
+ },
+ "principalId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to."
+ }
+ },
+ "principalType": {
+ "type": "string",
+ "allowedValues": [
+ "Device",
+ "ForeignGroup",
+ "Group",
+ "ServicePrincipal",
+ "User"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The principal type of the assigned principal ID."
+ }
+ },
+ "description": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The description of the role assignment."
+ }
+ },
+ "condition": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"."
+ }
+ },
+ "conditionVersion": {
+ "type": "string",
+ "allowedValues": [
+ "2.0"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Version of the condition."
+ }
+ },
+ "delegatedManagedIdentityResourceId": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The Resource Id of the delegated managed identity resource."
+ }
+ }
+ }
+ },
+ "nullable": true
+ },
+ "lockType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specify the name of lock."
+ }
+ },
+ "kind": {
+ "type": "string",
+ "allowedValues": [
+ "CanNotDelete",
+ "None",
+ "ReadOnly"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specify the type of lock."
+ }
+ }
+ },
+ "nullable": true
+ },
+ "ipConfigurationsType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the resource that is unique within a resource group."
+ }
+ },
+ "properties": {
+ "type": "object",
+ "properties": {
+ "groupId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
+ }
},
- "value": "[resourceGroup().name]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the private endpoint."
+ "memberName": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string."
+ }
},
- "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]"
+ "privateIPAddress": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. A private IP address obtained from the private endpoint's subnet."
+ }
+ }
},
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the private endpoint."
+ "metadata": {
+ "description": "Required. Properties of private endpoint IP configurations."
+ }
+ }
+ }
+ },
+ "nullable": true
+ },
+ "manualPrivateLinkServiceConnectionsType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the private link service connection."
+ }
+ },
+ "properties": {
+ "type": "object",
+ "properties": {
+ "groupIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "metadata": {
+ "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`."
+ }
},
- "value": "[parameters('name')]"
- },
- "location": {
- "type": "string",
- "metadata": {
- "description": "The location the resource was deployed into."
+ "privateLinkServiceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The resource id of private link service."
+ }
},
- "value": "[reference('privateEndpoint', '2024-05-01', 'full').location]"
+ "requestMessage": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars."
+ }
+ }
},
- "customDnsConfigs": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/customDnsConfigType"
+ "metadata": {
+ "description": "Required. Properties of private link service connection."
+ }
+ }
+ }
+ },
+ "nullable": true
+ },
+ "privateLinkServiceConnectionsType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the private link service connection."
+ }
+ },
+ "properties": {
+ "type": "object",
+ "properties": {
+ "groupIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "metadata": {
+ "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`."
+ }
},
- "metadata": {
- "description": "The custom DNS configurations of the private endpoint."
+ "privateLinkServiceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The resource id of private link service."
+ }
},
- "value": "[reference('privateEndpoint').customDnsConfigs]"
+ "requestMessage": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars."
+ }
+ }
},
- "networkInterfaceResourceIds": {
- "type": "array",
- "items": {
- "type": "string"
- },
- "metadata": {
- "description": "The resource IDs of the network interfaces associated with the private endpoint."
- },
- "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]"
+ "metadata": {
+ "description": "Required. Properties of private link service connection."
+ }
+ }
+ }
+ },
+ "nullable": true
+ },
+ "customDnsConfigType": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "fqdn": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. FQDN that resolves to private endpoint IP address."
+ }
+ },
+ "ipAddresses": {
+ "type": "array",
+ "items": {
+ "type": "string"
},
- "groupId": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "The group Id for the private endpoint Group."
- },
- "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'manualPrivateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0), tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'privateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0))]"
+ "metadata": {
+ "description": "Required. A list of private IP addresses of the private endpoint."
+ }
+ }
+ }
+ },
+ "nullable": true
+ },
+ "privateDnsZoneGroupConfigType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name of the private DNS zone group config."
+ }
+ },
+ "privateDnsZoneResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The resource id of the private DNS zone."
+ }
+ }
+ },
+ "metadata": {
+ "__bicep_imported_from!": {
+ "sourceTemplate": "private-dns-zone-group/main.bicep"
+ }
+ }
+ }
+ },
+ "parameters": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the private endpoint resource to create."
+ }
+ },
+ "subnetResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Resource ID of the subnet where the endpoint needs to be created."
+ }
+ },
+ "applicationSecurityGroupResourceIds": {
+ "type": "array",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Application security groups in which the private endpoint IP configuration is included."
+ }
+ },
+ "customNetworkInterfaceName": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The custom name of the network interface attached to the private endpoint."
+ }
+ },
+ "ipConfigurations": {
+ "$ref": "#/definitions/ipConfigurationsType",
+ "metadata": {
+ "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints."
+ }
+ },
+ "privateDnsZoneGroup": {
+ "$ref": "#/definitions/privateDnsZoneGroupType",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The private DNS zone group to configure for the private endpoint."
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Optional. Location for all Resources."
+ }
+ },
+ "lock": {
+ "$ref": "#/definitions/lockType",
+ "metadata": {
+ "description": "Optional. The lock settings of the service."
+ }
+ },
+ "roleAssignments": {
+ "$ref": "#/definitions/roleAssignmentType",
+ "metadata": {
+ "description": "Optional. Array of role assignments to create."
+ }
+ },
+ "tags": {
+ "type": "object",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Tags to be applied on all resources/resource groups in this deployment."
+ }
+ },
+ "customDnsConfigs": {
+ "$ref": "#/definitions/customDnsConfigType",
+ "metadata": {
+ "description": "Optional. Custom DNS configurations."
+ }
+ },
+ "manualPrivateLinkServiceConnections": {
+ "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType",
+ "metadata": {
+ "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource."
+ }
+ },
+ "privateLinkServiceConnections": {
+ "$ref": "#/definitions/privateLinkServiceConnectionsType",
+ "metadata": {
+ "description": "Optional. A grouping of information about the connection to the remote resource."
+ }
+ },
+ "enableTelemetry": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Optional. Enable/Disable usage telemetry for module."
+ }
+ }
+ },
+ "variables": {
+ "copy": [
+ {
+ "name": "formattedRoleAssignments",
+ "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]",
+ "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]"
+ }
+ ],
+ "builtInRoleNames": {
+ "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
+ "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]",
+ "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]",
+ "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]",
+ "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]",
+ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]",
+ "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
+ "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]",
+ "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]",
+ "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]"
+ }
+ },
+ "resources": {
+ "avmTelemetry": {
+ "condition": "[parameters('enableTelemetry')]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2024-03-01",
+ "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.8.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
+ "properties": {
+ "mode": "Incremental",
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "resources": [],
+ "outputs": {
+ "telemetry": {
+ "type": "String",
+ "value": "For more information, see https://aka.ms/avm/TelemetryInfo"
}
}
}
+ }
+ },
+ "privateEndpoint": {
+ "type": "Microsoft.Network/privateEndpoints",
+ "apiVersion": "2023-11-01",
+ "name": "[parameters('name')]",
+ "location": "[parameters('location')]",
+ "tags": "[parameters('tags')]",
+ "properties": {
+ "copy": [
+ {
+ "name": "applicationSecurityGroups",
+ "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]",
+ "input": {
+ "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]"
+ }
+ }
+ ],
+ "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]",
+ "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]",
+ "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]",
+ "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]",
+ "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]",
+ "subnet": {
+ "id": "[parameters('subnetResourceId')]"
+ }
+ }
+ },
+ "privateEndpoint_lock": {
+ "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]",
+ "type": "Microsoft.Authorization/locks",
+ "apiVersion": "2020-05-01",
+ "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]",
+ "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
+ "properties": {
+ "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
+ "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]"
},
"dependsOn": [
- "cognitiveService"
+ "privateEndpoint"
]
},
- "secretsExport": {
- "condition": "[not(equals(parameters('secretsExportConfiguration'), null()))]",
+ "privateEndpoint_roleAssignments": {
+ "copy": {
+ "name": "privateEndpoint_roleAssignments",
+ "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
+ },
+ "type": "Microsoft.Authorization/roleAssignments",
+ "apiVersion": "2022-04-01",
+ "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]",
+ "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
+ "properties": {
+ "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]",
+ "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]",
+ "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]",
+ "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]",
+ "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]",
+ "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]",
+ "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
+ },
+ "dependsOn": [
+ "privateEndpoint"
+ ]
+ },
+ "privateEndpoint_privateDnsZoneGroup": {
+ "condition": "[not(empty(parameters('privateDnsZoneGroup')))]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2022-09-01",
- "name": "[format('{0}-secrets-kv', uniqueString(deployment().name, parameters('location')))]",
- "subscriptionId": "[split(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '/')[2]]",
- "resourceGroup": "[split(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '/')[4]]",
+ "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
- "keyVaultName": {
- "value": "[last(split(tryGet(parameters('secretsExportConfiguration'), 'keyVaultResourceId'), '/'))]"
+ "name": {
+ "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]"
},
- "secretsToSet": {
- "value": "[union(createArray(), if(contains(parameters('secretsExportConfiguration'), 'accessKey1Name'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'accessKey1Name'), 'value', listKeys('cognitiveService', '2025-06-01').key1)), createArray()), if(contains(parameters('secretsExportConfiguration'), 'accessKey2Name'), createArray(createObject('name', tryGet(parameters('secretsExportConfiguration'), 'accessKey2Name'), 'value', listKeys('cognitiveService', '2025-06-01').key2)), createArray()))]"
+ "privateEndpointName": {
+ "value": "[parameters('name')]"
+ },
+ "privateDnsZoneConfigs": {
+ "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]"
}
},
"template": {
@@ -43341,213 +44838,183 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.37.4.10188",
- "templateHash": "10828079590669389085"
- }
+ "version": "0.30.23.60470",
+ "templateHash": "12329174801198479603"
+ },
+ "name": "Private Endpoint Private DNS Zone Groups",
+ "description": "This module deploys a Private Endpoint Private DNS Zone Group.",
+ "owner": "Azure/module-maintainers"
},
"definitions": {
- "secretSetOutputType": {
- "type": "object",
- "properties": {
- "secretResourceId": {
- "type": "string",
- "metadata": {
- "description": "The resourceId of the exported secret."
- }
- },
- "secretUri": {
- "type": "string",
- "metadata": {
- "description": "The secret URI of the exported secret."
- }
- },
- "secretUriWithVersion": {
- "type": "string",
- "metadata": {
- "description": "The secret URI with version of the exported secret."
- }
- }
- },
- "metadata": {
- "description": "An AVM-aligned type for the output of the secret set via the secrets export feature.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
- }
- },
- "secretToSetType": {
+ "privateDnsZoneGroupConfigType": {
"type": "object",
"properties": {
"name": {
"type": "string",
+ "nullable": true,
"metadata": {
- "description": "Required. The name of the secret to set."
+ "description": "Optional. The name of the private DNS zone group config."
}
},
- "value": {
- "type": "securestring",
+ "privateDnsZoneResourceId": {
+ "type": "string",
"metadata": {
- "description": "Required. The value of the secret to set."
+ "description": "Required. The resource id of the private DNS zone."
}
}
},
"metadata": {
- "description": "An AVM-aligned type for the secret to set via the secrets export feature.",
- "__bicep_imported_from!": {
- "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
- }
+ "__bicep_export!": true
}
}
},
"parameters": {
- "keyVaultName": {
+ "privateEndpointName": {
"type": "string",
"metadata": {
- "description": "Required. The name of the Key Vault to set the ecrets in."
+ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment."
}
},
- "secretsToSet": {
+ "privateDnsZoneConfigs": {
"type": "array",
"items": {
- "$ref": "#/definitions/secretToSetType"
+ "$ref": "#/definitions/privateDnsZoneGroupConfigType"
},
+ "minLength": 1,
+ "maxLength": 5,
"metadata": {
- "description": "Required. The secrets to set in the Key Vault."
+ "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones."
+ }
+ },
+ "name": {
+ "type": "string",
+ "defaultValue": "default",
+ "metadata": {
+ "description": "Optional. The name of the private DNS zone group."
}
}
},
+ "variables": {
+ "copy": [
+ {
+ "name": "privateDnsZoneConfigsVar",
+ "count": "[length(parameters('privateDnsZoneConfigs'))]",
+ "input": {
+ "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]",
+ "properties": {
+ "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]"
+ }
+ }
+ }
+ ]
+ },
"resources": {
- "keyVault": {
+ "privateEndpoint": {
"existing": true,
- "type": "Microsoft.KeyVault/vaults",
- "apiVersion": "2024-11-01",
- "name": "[parameters('keyVaultName')]"
+ "type": "Microsoft.Network/privateEndpoints",
+ "apiVersion": "2023-11-01",
+ "name": "[parameters('privateEndpointName')]"
},
- "secrets": {
- "copy": {
- "name": "secrets",
- "count": "[length(parameters('secretsToSet'))]"
- },
- "type": "Microsoft.KeyVault/vaults/secrets",
- "apiVersion": "2024-11-01",
- "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('secretsToSet')[copyIndex()].name)]",
+ "privateDnsZoneGroup": {
+ "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
+ "apiVersion": "2023-11-01",
+ "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]",
"properties": {
- "value": "[parameters('secretsToSet')[copyIndex()].value]"
- }
+ "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]"
+ },
+ "dependsOn": [
+ "privateEndpoint"
+ ]
}
},
"outputs": {
- "secretsSet": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/secretSetOutputType"
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the private endpoint DNS zone group."
},
+ "value": "[parameters('name')]"
+ },
+ "resourceId": {
+ "type": "string",
"metadata": {
- "description": "The references to the secrets exported to the provided Key Vault."
+ "description": "The resource ID of the private endpoint DNS zone group."
},
- "copy": {
- "count": "[length(range(0, length(coalesce(parameters('secretsToSet'), createArray()))))]",
- "input": {
- "secretResourceId": "[resourceId('Microsoft.KeyVault/vaults/secrets', parameters('keyVaultName'), parameters('secretsToSet')[range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()]].name)]",
- "secretUri": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUri]",
- "secretUriWithVersion": "[reference(format('secrets[{0}]', range(0, length(coalesce(parameters('secretsToSet'), createArray())))[copyIndex()])).secretUriWithVersion]"
- }
- }
+ "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource group the private endpoint DNS zone group was deployed into."
+ },
+ "value": "[resourceGroup().name]"
}
}
}
},
"dependsOn": [
- "cognitiveService"
+ "privateEndpoint"
]
}
},
"outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the cognitive services account."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the cognitive services account."
- },
- "value": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]"
- },
"resourceGroupName": {
"type": "string",
"metadata": {
- "description": "The resource group the cognitive services account was deployed into."
+ "description": "The resource group the private endpoint was deployed into."
},
"value": "[resourceGroup().name]"
},
- "endpoint": {
+ "resourceId": {
"type": "string",
"metadata": {
- "description": "The service endpoint of the cognitive services account."
- },
- "value": "[reference('cognitiveService').endpoint]"
- },
- "endpoints": {
- "$ref": "#/definitions/endpointType",
- "metadata": {
- "description": "All endpoints available for the cognitive services account, types depends on the cognitive service kind."
+ "description": "The resource ID of the private endpoint."
},
- "value": "[reference('cognitiveService').endpoints]"
+ "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]"
},
- "systemAssignedMIPrincipalId": {
+ "name": {
"type": "string",
- "nullable": true,
"metadata": {
- "description": "The principal ID of the system assigned identity."
+ "description": "The name of the private endpoint."
},
- "value": "[tryGet(tryGet(reference('cognitiveService', '2025-06-01', 'full'), 'identity'), 'principalId')]"
+ "value": "[parameters('name')]"
},
"location": {
"type": "string",
"metadata": {
"description": "The location the resource was deployed into."
},
- "value": "[reference('cognitiveService', '2025-06-01', 'full').location]"
+ "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]"
},
- "exportedSecrets": {
- "$ref": "#/definitions/secretsOutputType",
+ "customDnsConfig": {
+ "$ref": "#/definitions/customDnsConfigType",
"metadata": {
- "description": "A hashtable of references to the secrets exported to the provided Key Vault. The key of each reference is each secret's name."
+ "description": "The custom DNS configurations of the private endpoint."
},
- "value": "[if(not(equals(parameters('secretsExportConfiguration'), null())), toObject(reference('secretsExport').outputs.secretsSet.value, lambda('secret', last(split(lambdaVariables('secret').secretResourceId, '/'))), lambda('secret', lambdaVariables('secret'))), createObject())]"
+ "value": "[reference('privateEndpoint').customDnsConfigs]"
},
- "privateEndpoints": {
+ "networkInterfaceIds": {
"type": "array",
- "items": {
- "$ref": "#/definitions/privateEndpointOutputType"
+ "metadata": {
+ "description": "The IDs of the network interfaces associated with the private endpoint."
},
+ "value": "[reference('privateEndpoint').networkInterfaces]"
+ },
+ "groupId": {
+ "type": "string",
"metadata": {
- "description": "The private endpoints of the congitive services account."
+ "description": "The group Id for the private endpoint Group."
},
- "copy": {
- "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]",
- "input": {
- "name": "[reference(format('cognitiveService_privateEndpoints[{0}]', copyIndex())).outputs.name.value]",
- "resourceId": "[reference(format('cognitiveService_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]",
- "groupId": "[tryGet(tryGet(reference(format('cognitiveService_privateEndpoints[{0}]', copyIndex())).outputs, 'groupId'), 'value')]",
- "customDnsConfigs": "[reference(format('cognitiveService_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfigs.value]",
- "networkInterfaceResourceIds": "[reference(format('cognitiveService_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]"
- }
- }
+ "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]"
}
}
}
},
"dependsOn": [
- "avmContainerApp",
- "avmContainerApp_Workflow",
- "avmManagedIdentity",
- "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]",
+ "avmAiServices_cu",
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').contentUnderstanding)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)]",
"virtualNetwork"
]
},
@@ -48358,6 +49825,14 @@
"name": "APP_API_SCOPE",
"value": ""
},
+ {
+ "name": "APP_REDIRECT_URL",
+ "value": "/"
+ },
+ {
+ "name": "APP_POST_REDIRECT_URL",
+ "value": "/"
+ },
{
"name": "APP_CONSOLE_LOG_ENABLED",
"value": "false"
@@ -63711,7 +65186,9 @@
"dependsOn": [
"avmAppConfig",
"avmContainerAppEnv",
- "avmContainerRegistryReader"
+ "avmContainerRegistryReader",
+ "cognitiveServicePrivateEndpoint",
+ "contentUnderstandingPrivateEndpoint"
]
},
"avmContainerApp_API_update": {
@@ -65385,7 +66862,8 @@
"dependsOn": [
"avmAppConfig",
"avmContainerAppEnv",
- "avmContainerRegistryReader"
+ "avmContainerRegistryReader",
+ "cognitiveServicePrivateEndpoint"
]
},
"avmContainerApp_Workflow_update": {
diff --git a/infra/main.waf.parameters.json b/infra/main.waf.parameters.json
index 23fd63ac..58c221c0 100644
--- a/infra/main.waf.parameters.json
+++ b/infra/main.waf.parameters.json
@@ -41,12 +41,15 @@
"enableScalability": {
"value": true
},
- "virtualMachineAdminUsername": {
+ "vmAdminUsername": {
"value": "${AZURE_ENV_VM_ADMIN_USERNAME}"
},
- "virtualMachineAdminPassword": {
+ "vmAdminPassword": {
"value": "${AZURE_ENV_VM_ADMIN_PASSWORD}"
},
+ "vmSize": {
+ "value": "${AZURE_ENV_VM_SIZE}"
+ },
"publicContainerImageEndpoint": {
"value": "${AZURE_ENV_CONTAINER_REGISTRY_ENDPOINT}"
},
diff --git a/infra/modules/virtualNetwork.bicep b/infra/modules/virtualNetwork.bicep
index 575cdfa6..2e83b6ee 100644
--- a/infra/modules/virtualNetwork.bicep
+++ b/infra/modules/virtualNetwork.bicep
@@ -212,10 +212,12 @@ param resourceSuffix string
// VM Size Notes:
// 1 B-series VMs (like Standard_B2ms) do not support accelerated networking.
-// 2 Pick a VM size that does support accelerated networking (the usual jump-box candidates):
-// Standard_DS2_v2 (2 vCPU, 7 GiB RAM, Premium SSD) // The most broadly available (it’s a legacy SKU supported in virtually every region).
-// Standard_D2s_v3 (2 vCPU, 8 GiB RAM, Premium SSD) // next most common
-// Standard_D2s_v4 (2 vCPU, 8 GiB RAM, Premium SSD) // Newest, so fewer regions availabl
+// 2 Pick a VM size that supports accelerated networking + Premium SSD (the usual jump-box candidates):
+// Standard_D2s_v5 (2 vCPU, 8 GiB RAM, Premium SSD/v2/Ultra) // DEFAULT - current-gen Intel, broad regional availability.
+// Standard_D2as_v5 (2 vCPU, 8 GiB RAM, Premium SSD/Ultra) // AMD alternative, typically ~15% cheaper.
+// Standard_D2s_v4 (2 vCPU, 8 GiB RAM, Premium SSD) // Previous gen, also broadly available.
+// Standard_DS2_v2 (2 vCPU, 7 GiB RAM, Premium SSD) // Legacy SKU, being retired from some regions - avoid for new deployments.
+// 3 A-series (Av2) is NOT suitable: no Premium SSD support, no accelerated networking.
// Subnet Classless Inter-Doman Routing (CIDR) Sizing Reference Table (Best Practices)
// | CIDR | # of Addresses | # of /24s | Notes |