diff --git a/docs/CustomizingAzdParameters.md b/docs/CustomizingAzdParameters.md
index b71a16a3..ef32e82d 100644
--- a/docs/CustomizingAzdParameters.md
+++ b/docs/CustomizingAzdParameters.md
@@ -23,6 +23,7 @@ By default this template will use the environment name as the prefix to prevent
| `AZURE_ENV_COSMOS_SECONDARY_LOCATION` | string | *(not set by default)* | Specifies the secondary region for Cosmos DB. Required if `enableRedundancy` is `true`. |
| `AZURE_EXISTING_AI_PROJECT_RESOURCE_ID` | string | *(not set by default)* | Specifies the existing AI Foundry Project Resource ID if it needs to be reused. |
| `AZURE_ENV_ACR_NAME` | string | `cmsacontainerreg.azurecr.io` | Specifies the Azure Container Registry name to use for container images. |
+| `AZURE_ENV_VM_SIZE` | string | `Standard_D2s_v5` | Overrides the jumpbox VM size (private networking only). Default: `Standard_D2s_v5`. |
---
diff --git a/docs/TroubleShootingSteps.md b/docs/TroubleShootingSteps.md
index 95ebe363..0a4b8ab1 100644
--- a/docs/TroubleShootingSteps.md
+++ b/docs/TroubleShootingSteps.md
@@ -61,7 +61,7 @@ Use these as quick reference guides to unblock your deployments.
| **ServiceQuotaExceeded** | Free tier service quota limit reached for Azure AI Search | This error occurs when you attempt to deploy an Azure AI Search service but have already reached the **free tier quota limit** for your subscription. Each Azure subscription is limited to **one free tier Search service**.
**Example error message:**
`ServiceQuotaExceeded: Operation would exceed 'free' tier service quota. You are using 1 out of 1 'free' tier service quota.`
**Common causes:**
- Already have a free tier Azure AI Search service in the subscription
- Previous deployment created a free tier Search service that wasn't deleted
- Attempting to deploy multiple environments with free tier Search services
**Resolution:**
- **Option 1: Delete existing free tier Search service:**
`az search service list --query "[?sku.name=='free']" -o table`
`az search service delete --name --resource-group --yes` - **Option 2: Upgrade to a paid SKU:**
Modify your Bicep/ARM template to use `basic`, `standard`, or higher SKU instead of `free` - **Option 3: Use existing Search service:**
Reference the existing free tier Search service in your deployment instead of creating a new one - **Request quota increase:**
Submit a support request with issue type 'Service and subscription limits (quota)' and quota type 'Search' via [Azure Quota Request](https://aka.ms/AddQuotaSubscription)
**Reference:**
- [Azure AI Search service limits](https://learn.microsoft.com/en-us/azure/search/search-limits-quotas-capacity)
- [Azure AI Search pricing tiers](https://learn.microsoft.com/en-us/azure/search/search-sku-tier)
|
| **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 60+ 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 + Premium SSD):
- `Standard_D2s_v4` — previous gen, identical pricing
- `Standard_D2as_v5` — AMD-based, similar pricing
- `Standard_D2s_v3` — older gen, widely available - **Avoid A-series VMs** (e.g., `Standard_A2m_v2`) — they do not support accelerated networking or Premium SSD, which are required by this deployment
**Reference:**
- [Resolve errors for SKU not available](https://learn.microsoft.com/en-us/azure/azure-resource-manager/troubleshooting/error-sku-not-available)
- [Azure VM sizes - Dsv5 series](https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dsv5-series)
|
| **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) |
--------------------------------
@@ -120,7 +120,7 @@ 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.
**How to reproduce:**
- Create or deploy a VM (e.g., via ARM/Bicep) with size `Standard_A2m_v2`
- In the network interface configuration, set `"enableAcceleratedNetworking": true`
- Submit the request → Azure throws `VMSizeIsNotPermittedToEnableAcceleratedNetworking`
**Resolution:**
- Use a supported VM size that supports accelerated networking
- Check the [Microsoft list of supported VM sizes for accelerated networking](https://learn.microsoft.com/en-us/azure/virtual-network/accelerated-networking-overview#supported-vm-instances)
- Alternatively, disable accelerated networking if the feature is not required for your workload
|
+| **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`, or override with a D-series VM that supports accelerated networking:
`azd env set AZURE_ENV_VM_SIZE Standard_D2s_v5` - **Supported alternatives:** `Standard_D2s_v4`, `Standard_D2as_v5`, `Standard_D2s_v3`
- **Do NOT use:** A-series (`Standard_A2m_v2`), B-series (`Standard_B2s`) — these do not support accelerated networking
- Check supported sizes: [Accelerated networking supported VM instances](https://learn.microsoft.com/en-us/azure/virtual-network/accelerated-networking-overview#supported-vm-instances)
|
**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:**
- Allow inbound TCP 443 and 4443 on `AzureBastionSubnet` by updating or removing the NSG deny rules
- Alternatively, deploy Bastion to a subnet without restrictive NSG rules
- For more details, refer to [Azure Bastion NSG requirements](https://learn.microsoft.com/en-us/azure/bastion/bastion-nsg)
|
| **RouteTableCannotBeAttachedForAzureBastionSubnet** | Route table attached to Azure Bastion subnet | This error occurs because Azure Bastion subnet (`AzureBastionSubnet`) has a platform restriction that prevents route tables from being attached.
**How to reproduce:**
- In `virtualNetwork.bicep`, add `attachRouteTable: true` to the `AzureBastionSubnet` configuration:
`{ name: 'AzureBastionSubnet', addressPrefixes: ['10.0.10.0/26'], attachRouteTable: true }` - Add a Route Table module to the template
- Update subnet creation to attach route table conditionally:
`routeTableResourceId: subnet.?attachRouteTable == true ? routeTable.outputs.resourceId : null` - Deploy the template → Azure throws `RouteTableCannotBeAttachedForAzureBastionSubnet`
**Resolution:**
- Remove the `attachRouteTable: true` flag from `AzureBastionSubnet` configuration
- Ensure no route table is associated with `AzureBastionSubnet`
- Route tables can only be attached to other subnets, not `AzureBastionSubnet`
- For more details, refer to [Azure Bastion subnet requirements](https://learn.microsoft.com/en-us/azure/bastion/configuration-settings#subnet)
|
diff --git a/infra/main.bicep b/infra/main.bicep
index 31852aa0..7a55a7f9 100644
--- a/infra/main.bicep
+++ b/infra/main.bicep
@@ -637,7 +637,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.20.0' = if (e
enableTelemetry: enableTelemetry
computerName: take(virtualMachineResourceName, 15)
osType: 'Windows'
- vmSize: vmSize ?? 'Standard_D2s_v3'
+ vmSize: vmSize ?? 'Standard_D2s_v5'
adminUsername: vmAdminUsername ?? 'JumpboxAdminUser'
adminPassword: vmAdminPassword ?? 'JumpboxAdminP@ssw0rd1234!'
managedIdentities: {
diff --git a/infra/main.json b/infra/main.json
index bf15cc8e..87283bf4 100644
--- a/infra/main.json
+++ b/infra/main.json
@@ -5,8 +5,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "14323896881835347609"
+ "version": "0.38.33.27573",
+ "templateHash": "467152886292252530"
},
"name": "Modernize Your Code Solution Accelerator",
"description": "CSA CTO Gold Standard Solution Accelerator for Modernize Your Code. \r\n"
@@ -243,7 +243,11 @@
"privatelink.documents.azure.com",
"privatelink.vaultcore.azure.net",
"[format('privatelink.blob.{0}', environment().suffixes.storage)]",
- "[format('privatelink.file.{0}', environment().suffixes.storage)]"
+ "[format('privatelink.file.{0}', environment().suffixes.storage)]",
+ "privatelink.monitor.azure.com",
+ "privatelink.oms.opinsights.azure.com",
+ "privatelink.ods.opinsights.azure.com",
+ "privatelink.agentsvc.azure-automation.net"
],
"dnsZoneIndex": {
"cognitiveServices": 0,
@@ -252,7 +256,11 @@
"cosmosDB": 3,
"keyVault": 4,
"storageBlob": 5,
- "storageFile": 6
+ "storageFile": 6,
+ "monitor": 7,
+ "oms": 8,
+ "ods": 9,
+ "agentSvc": 10
},
"bastionHostName": "[format('bas-{0}', variables('solutionSuffix'))]",
"maintenanceConfigurationResourceName": "[format('mc-{0}', variables('solutionSuffix'))]",
@@ -3931,12 +3939,11 @@
"disableIpMasking": {
"value": false
},
- "disableLocalAuth": {
- "value": true
- },
"flowType": {
"value": "Bluefield"
- }
+ },
+ "publicNetworkAccessForIngestion": "[if(parameters('enablePrivateNetworking'), createObject('value', 'Disabled'), createObject('value', 'Enabled'))]",
+ "publicNetworkAccessForQuery": "[if(parameters('enablePrivateNetworking'), createObject('value', 'Disabled'), createObject('value', 'Enabled'))]"
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
@@ -4662,6 +4669,354 @@
"logAnalyticsWorkspace"
]
},
+ "dataCollectionEndpoint": {
+ "condition": "[and(parameters('enablePrivateNetworking'), parameters('enableMonitoring'))]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2025-04-01",
+ "name": "[take(format('avm.res.insights.data-collection-endpoint.{0}', variables('solutionSuffix')), 64)]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "name": {
+ "value": "[format('dce-{0}', variables('solutionSuffix'))]"
+ },
+ "location": {
+ "value": "[parameters('location')]"
+ },
+ "kind": {
+ "value": "Windows"
+ },
+ "publicNetworkAccess": {
+ "value": "Disabled"
+ },
+ "tags": {
+ "value": "[variables('allTags')]"
+ },
+ "enableTelemetry": {
+ "value": "[parameters('enableTelemetry')]"
+ }
+ },
+ "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.31.92.45157",
+ "templateHash": "2803753346410103560"
+ },
+ "name": "Data Collection Endpoints",
+ "description": "This module deploys a Data Collection Endpoint.",
+ "owner": "Azure/module-maintainers"
+ },
+ "definitions": {
+ "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."
+ }
+ }
+ },
+ "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.3.0"
+ }
+ }
+ },
+ "roleAssignmentType": {
+ "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."
+ }
+ }
+ },
+ "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.3.0"
+ }
+ }
+ }
+ },
+ "parameters": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the data collection endpoint. The name is case insensitive."
+ }
+ },
+ "description": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Description of the data collection endpoint."
+ }
+ },
+ "enableTelemetry": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Optional. Enable/Disable usage telemetry for module."
+ }
+ },
+ "kind": {
+ "type": "string",
+ "defaultValue": "Linux",
+ "allowedValues": [
+ "Linux",
+ "Windows"
+ ],
+ "metadata": {
+ "description": "Optional. The kind of the resource."
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Optional. Location for all Resources."
+ }
+ },
+ "lock": {
+ "$ref": "#/definitions/lockType",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The lock settings of the service."
+ }
+ },
+ "roleAssignments": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/roleAssignmentType"
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Array of role assignments to create."
+ }
+ },
+ "publicNetworkAccess": {
+ "type": "string",
+ "defaultValue": "Disabled",
+ "allowedValues": [
+ "Enabled",
+ "Disabled",
+ "SecuredByPerimeter"
+ ],
+ "metadata": {
+ "description": "Optional. The configuration to set whether network access from public internet to the endpoints are allowed."
+ }
+ },
+ "tags": {
+ "type": "object",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Resource tags."
+ }
+ }
+ },
+ "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')]",
+ "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
+ "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')]"
+ }
+ },
+ "resources": {
+ "avmTelemetry": {
+ "condition": "[parameters('enableTelemetry')]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2024-03-01",
+ "name": "[format('46d3xbcp.res.insights-datacollectionendpoint.{0}.{1}', replace('0.5.0', '.', '-'), 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"
+ }
+ }
+ }
+ }
+ },
+ "dataCollectionEndpoint": {
+ "type": "Microsoft.Insights/dataCollectionEndpoints",
+ "apiVersion": "2023-03-11",
+ "name": "[parameters('name')]",
+ "kind": "[parameters('kind')]",
+ "location": "[parameters('location')]",
+ "tags": "[parameters('tags')]",
+ "properties": {
+ "networkAcls": {
+ "publicNetworkAccess": "[parameters('publicNetworkAccess')]"
+ },
+ "description": "[parameters('description')]"
+ }
+ },
+ "dataCollectionEndpoint_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.Insights/dataCollectionEndpoints/{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": [
+ "dataCollectionEndpoint"
+ ]
+ },
+ "dataCollectionEndpoint_roleAssignments": {
+ "copy": {
+ "name": "dataCollectionEndpoint_roleAssignments",
+ "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
+ },
+ "type": "Microsoft.Authorization/roleAssignments",
+ "apiVersion": "2022-04-01",
+ "scope": "[format('Microsoft.Insights/dataCollectionEndpoints/{0}', parameters('name'))]",
+ "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Insights/dataCollectionEndpoints', 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": [
+ "dataCollectionEndpoint"
+ ]
+ }
+ },
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the dataCollectionEndpoint."
+ },
+ "value": "[parameters('name')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the dataCollectionEndpoint."
+ },
+ "value": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', parameters('name'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group the dataCollectionEndpoint was created in."
+ },
+ "value": "[resourceGroup().name]"
+ },
+ "location": {
+ "type": "string",
+ "metadata": {
+ "description": "The location the resource was deployed into."
+ },
+ "value": "[reference('dataCollectionEndpoint', '2023-03-11', 'full').location]"
+ }
+ }
+ }
+ }
+ },
"virtualNetwork": {
"condition": "[parameters('enablePrivateNetworking')]",
"type": "Microsoft.Resources/deployments",
@@ -4702,8 +5057,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "4892991135758906801"
+ "version": "0.38.33.27573",
+ "templateHash": "11189353177117695367"
}
},
"definitions": {
@@ -10526,50 +10881,1602 @@
}
},
"parameters": {
- "privateDnsZoneName": {
+ "privateDnsZoneName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment."
+ }
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The name of the TXT record."
+ }
+ },
+ "metadata": {
+ "type": "object",
+ "metadata": {
+ "__bicep_resource_derived_type!": {
+ "source": "Microsoft.Network/privateDnsZones/TXT@2024-06-01#properties/properties/properties/metadata"
+ },
+ "description": "Optional. The metadata attached to the record set."
+ },
+ "nullable": true
+ },
+ "ttl": {
+ "type": "int",
+ "defaultValue": 3600,
+ "metadata": {
+ "description": "Optional. The TTL (time-to-live) of the records in the record set."
+ }
+ },
+ "txtRecords": {
+ "type": "array",
+ "metadata": {
+ "__bicep_resource_derived_type!": {
+ "source": "Microsoft.Network/privateDnsZones/TXT@2024-06-01#properties/properties/properties/txtRecords"
+ },
+ "description": "Optional. The list of TXT records in the record set."
+ },
+ "nullable": true
+ },
+ "enableTelemetry": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Optional. Enable/Disable usage telemetry for module."
+ }
+ },
+ "roleAssignments": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/roleAssignmentType"
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Array of role assignments to create."
+ }
+ }
+ },
+ "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')]",
+ "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]",
+ "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]",
+ "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]",
+ "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')]"
+ }
+ },
+ "resources": {
+ "avmTelemetry": {
+ "condition": "[parameters('enableTelemetry')]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2024-03-01",
+ "name": "[format('46d3xbcp.res.nw-privdnszonetxt.{0}.{1}', replace('0.1.0', '.', '-'), substring(uniqueString(deployment().name), 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"
+ }
+ }
+ }
+ }
+ },
+ "privateDnsZone": {
+ "existing": true,
+ "type": "Microsoft.Network/privateDnsZones",
+ "apiVersion": "2020-06-01",
+ "name": "[parameters('privateDnsZoneName')]"
+ },
+ "TXT": {
+ "type": "Microsoft.Network/privateDnsZones/TXT",
+ "apiVersion": "2020-06-01",
+ "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]",
+ "properties": {
+ "metadata": "[parameters('metadata')]",
+ "ttl": "[parameters('ttl')]",
+ "txtRecords": "[parameters('txtRecords')]"
+ }
+ },
+ "TXT_roleAssignments": {
+ "copy": {
+ "name": "TXT_roleAssignments",
+ "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
+ },
+ "type": "Microsoft.Authorization/roleAssignments",
+ "apiVersion": "2022-04-01",
+ "scope": "[format('Microsoft.Network/privateDnsZones/{0}/TXT/{1}', parameters('privateDnsZoneName'), parameters('name'))]",
+ "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones/TXT', parameters('privateDnsZoneName'), 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": [
+ "TXT"
+ ]
+ }
+ },
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the deployed TXT record."
+ },
+ "value": "[parameters('name')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the deployed TXT record."
+ },
+ "value": "[resourceId('Microsoft.Network/privateDnsZones/TXT', parameters('privateDnsZoneName'), parameters('name'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource group of the deployed TXT record."
+ },
+ "value": "[resourceGroup().name]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "privateDnsZone"
+ ]
+ },
+ "privateDnsZone_virtualNetworkLinks": {
+ "copy": {
+ "name": "privateDnsZone_virtualNetworkLinks",
+ "count": "[length(coalesce(parameters('virtualNetworkLinks'), createArray()))]"
+ },
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2022-09-01",
+ "name": "[format('{0}-PrivateDnsZone-VNetLink-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "privateDnsZoneName": {
+ "value": "[parameters('name')]"
+ },
+ "name": {
+ "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'name'), format('{0}-vnetlink', last(split(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()].virtualNetworkResourceId, '/'))))]"
+ },
+ "virtualNetworkResourceId": {
+ "value": "[coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()].virtualNetworkResourceId]"
+ },
+ "location": {
+ "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'location'), 'global')]"
+ },
+ "registrationEnabled": {
+ "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'registrationEnabled'), false())]"
+ },
+ "tags": {
+ "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'tags'), parameters('tags'))]"
+ },
+ "resolutionPolicy": {
+ "value": "[tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'resolutionPolicy')]"
+ }
+ },
+ "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.37.4.10188",
+ "templateHash": "517173107480898390"
+ },
+ "name": "Private DNS Zone Virtual Network Link",
+ "description": "This module deploys a Private DNS Zone Virtual Network Link."
+ },
+ "parameters": {
+ "privateDnsZoneName": {
+ "type": "string",
+ "metadata": {
+ "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment."
+ }
+ },
+ "name": {
+ "type": "string",
+ "defaultValue": "[format('{0}-vnetlink', last(split(parameters('virtualNetworkResourceId'), '/')))]",
+ "metadata": {
+ "description": "Optional. The name of the virtual network link."
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "global",
+ "metadata": {
+ "description": "Optional. The location of the PrivateDNSZone. Should be global."
+ }
+ },
+ "tags": {
+ "type": "object",
+ "metadata": {
+ "__bicep_resource_derived_type!": {
+ "source": "Microsoft.Network/privateDnsZones/virtualNetworkLinks@2024-06-01#properties/tags"
+ },
+ "description": "Optional. Tags of the resource."
+ },
+ "nullable": true
+ },
+ "registrationEnabled": {
+ "type": "bool",
+ "defaultValue": false,
+ "metadata": {
+ "description": "Optional. Is auto-registration of virtual machine records in the virtual network in the Private DNS zone enabled?."
+ }
+ },
+ "virtualNetworkResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Link to another virtual network resource ID."
+ }
+ },
+ "resolutionPolicy": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The resolution policy on the virtual network link. Only applicable for virtual network links to privatelink zones, and for A,AAAA,CNAME queries. When set to `NxDomainRedirect`, Azure DNS resolver falls back to public resolution if private dns query resolution results in non-existent domain response. `Default` is configured as the default option."
+ }
+ }
+ },
+ "resources": {
+ "privateDnsZone": {
+ "existing": true,
+ "type": "Microsoft.Network/privateDnsZones",
+ "apiVersion": "2020-06-01",
+ "name": "[parameters('privateDnsZoneName')]"
+ },
+ "virtualNetworkLink": {
+ "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
+ "apiVersion": "2024-06-01",
+ "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]",
+ "location": "[parameters('location')]",
+ "tags": "[parameters('tags')]",
+ "properties": {
+ "registrationEnabled": "[parameters('registrationEnabled')]",
+ "virtualNetwork": {
+ "id": "[parameters('virtualNetworkResourceId')]"
+ },
+ "resolutionPolicy": "[parameters('resolutionPolicy')]"
+ }
+ }
+ },
+ "outputs": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the deployed virtual network link."
+ },
+ "value": "[parameters('name')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the deployed virtual network link."
+ },
+ "value": "[resourceId('Microsoft.Network/privateDnsZones/virtualNetworkLinks', parameters('privateDnsZoneName'), parameters('name'))]"
+ },
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource group of the deployed virtual network link."
+ },
+ "value": "[resourceGroup().name]"
+ },
+ "location": {
+ "type": "string",
+ "metadata": {
+ "description": "The location the resource was deployed into."
+ },
+ "value": "[reference('virtualNetworkLink', '2024-06-01', 'full').location]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "privateDnsZone"
+ ]
+ }
+ },
+ "outputs": {
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource group the private DNS zone was deployed into."
+ },
+ "value": "[resourceGroup().name]"
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the private DNS zone."
+ },
+ "value": "[parameters('name')]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the private DNS zone."
+ },
+ "value": "[resourceId('Microsoft.Network/privateDnsZones', parameters('name'))]"
+ },
+ "location": {
+ "type": "string",
+ "metadata": {
+ "description": "The location the resource was deployed into."
+ },
+ "value": "[reference('privateDnsZone', '2020-06-01', 'full').location]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "virtualNetwork"
+ ]
+ },
+ "azureMonitorPrivateLinkScope": {
+ "condition": "[parameters('enablePrivateNetworking')]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2025-04-01",
+ "name": "[take(format('avm.res.insights.private-link-scope.{0}', variables('solutionSuffix')), 64)]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "name": {
+ "value": "[format('ampls-{0}', variables('solutionSuffix'))]"
+ },
+ "location": {
+ "value": "global"
+ },
+ "accessModeSettings": {
+ "value": {
+ "ingestionAccessMode": "PrivateOnly",
+ "queryAccessMode": "PrivateOnly"
+ }
+ },
+ "scopedResources": {
+ "value": "[concat(createArray(createObject('name', 'scoped-law', 'linkedResourceId', if(variables('useExistingLogAnalytics'), parameters('existingLogAnalyticsWorkspaceId'), reference('logAnalyticsWorkspace').outputs.resourceId.value))), if(parameters('enableMonitoring'), createArray(createObject('name', 'scoped-appi', 'linkedResourceId', reference('applicationInsights').outputs.resourceId.value), createObject('name', 'scoped-dce', 'linkedResourceId', reference('dataCollectionEndpoint').outputs.resourceId.value)), createArray()))]"
+ },
+ "privateEndpoints": {
+ "value": [
+ {
+ "name": "[format('pep-ampls-{0}', variables('solutionSuffix'))]",
+ "subnetResourceId": "[reference('virtualNetwork').outputs.pepsSubnetResourceId.value]",
+ "privateDnsZoneGroup": {
+ "privateDnsZoneGroupConfigs": [
+ {
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').monitor)).outputs.resourceId.value]"
+ },
+ {
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').oms)).outputs.resourceId.value]"
+ },
+ {
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').ods)).outputs.resourceId.value]"
+ },
+ {
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').agentSvc)).outputs.resourceId.value]"
+ },
+ {
+ "privateDnsZoneResourceId": "[reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)).outputs.resourceId.value]"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "tags": {
+ "value": "[variables('allTags')]"
+ },
+ "enableTelemetry": {
+ "value": "[parameters('enableTelemetry')]"
+ }
+ },
+ "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.33.93.31351",
+ "templateHash": "524476480902078754"
+ },
+ "name": "Azure Monitor Private Link Scopes",
+ "description": "This module deploys an Azure Monitor Private Link Scope."
+ },
+ "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
+ }
+ },
+ "scopedResourceType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Name of the private link scoped resource."
+ }
+ },
+ "linkedResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The resource ID of the scoped Azure monitor resource."
+ }
+ }
+ },
+ "metadata": {
+ "__bicep_export!": true,
+ "description": "The scoped resource type."
+ }
+ },
+ "accessModeType": {
+ "type": "object",
+ "properties": {
+ "exclusions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "privateEndpointConnectionName": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The private endpoint connection name associated to the private endpoint on which we want to apply the specific access mode settings."
+ }
+ },
+ "ingestionAccessMode": {
+ "type": "string",
+ "allowedValues": [
+ "Open",
+ "PrivateOnly"
+ ],
+ "metadata": {
+ "description": "Required. Specifies the access mode of ingestion through the specified private endpoint connection in the exclusion."
+ }
+ },
+ "queryAccessMode": {
+ "type": "string",
+ "allowedValues": [
+ "Open",
+ "PrivateOnly"
+ ],
+ "metadata": {
+ "description": "Required. Specifies the access mode of queries through the specified private endpoint connection in the exclusion."
+ }
+ }
+ }
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. List of exclusions that override the default access mode settings for specific private endpoint connections. Exclusions for the current created Private endpoints can only be applied post initial provisioning."
+ }
+ },
+ "ingestionAccessMode": {
+ "type": "string",
+ "allowedValues": [
+ "Open",
+ "PrivateOnly"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specifies the default access mode of ingestion through associated private endpoints in scope. Default is \"Open\" if no private endpoints are configured and will be set to \"PrivateOnly\" if private endpoints are configured. Override default behaviour by explicitly providing a value."
+ }
+ },
+ "queryAccessMode": {
+ "type": "string",
+ "allowedValues": [
+ "Open",
+ "PrivateOnly"
+ ],
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specifies the default access mode of queries through associated private endpoints in scope. Default is \"Open\" if no private endpoints are configured and will be set to \"PrivateOnly\" if private endpoints are configured. Override default behaviour by explicitly providing a value."
+ }
+ }
+ },
+ "metadata": {
+ "__bicep_export!": true,
+ "description": "The access mode type."
+ }
+ },
+ "_1.privateEndpointCustomDnsConfigType": {
+ "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_imported_from!": {
+ "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
+ }
+ }
+ },
+ "_1.privateEndpointIpConfigurationType": {
+ "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."
+ }
+ },
+ "memberName": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to."
+ }
+ },
+ "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_imported_from!": {
+ "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
+ }
+ }
+ },
+ "_1.privateEndpointPrivateDnsZoneGroupType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name of the Private DNS Zone Group."
+ }
+ },
+ "privateDnsZoneGroupConfigs": {
+ "type": "array",
+ "items": {
+ "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": {
+ "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_imported_from!": {
+ "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
+ }
+ }
+ },
+ "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."
+ }
+ }
+ },
+ "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"
+ }
+ }
+ },
+ "privateEndpointSingleServiceType": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name of the Private Endpoint."
+ }
+ },
+ "location": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The location to deploy the Private Endpoint to."
+ }
+ },
+ "privateLinkServiceConnectionName": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The name of the private link connection to create."
+ }
+ },
+ "service": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The subresource to deploy the Private Endpoint for. For example \"vault\" for a Key Vault Private Endpoint."
+ }
+ },
+ "subnetResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. Resource ID of the subnet where the endpoint needs to be created."
+ }
+ },
+ "resourceGroupResourceId": {
+ "type": "string",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used."
+ }
+ },
+ "privateDnsZoneGroup": {
+ "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The private DNS Zone Group to configure for the Private Endpoint."
+ }
+ },
+ "isManualConnection": {
+ "type": "bool",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. If Manual Private Link Connection is required."
+ }
+ },
+ "manualConnectionRequestMessage": {
+ "type": "string",
+ "nullable": true,
+ "maxLength": 140,
+ "metadata": {
+ "description": "Optional. A message passed to the owner of the remote resource with the manual connection request."
+ }
+ },
+ "customDnsConfigs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType"
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Custom DNS configurations."
+ }
+ },
+ "ipConfigurations": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/_1.privateEndpointIpConfigurationType"
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints."
+ }
+ },
+ "applicationSecurityGroupResourceIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "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."
+ }
+ },
+ "lock": {
+ "$ref": "#/definitions/lockType",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specify the type of lock."
+ }
+ },
+ "roleAssignments": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/roleAssignmentType"
+ },
+ "nullable": true,
+ "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."
+ }
+ },
+ "enableTelemetry": {
+ "type": "bool",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Enable/Disable usage telemetry for module."
+ }
+ }
+ },
+ "metadata": {
+ "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).",
+ "__bicep_imported_from!": {
+ "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1"
+ }
+ }
+ },
+ "roleAssignmentType": {
+ "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."
+ }
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "parameters": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "Required. Name of the private link scope."
+ }
+ },
+ "accessModeSettings": {
+ "$ref": "#/definitions/accessModeType",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Specifies the access mode of ingestion or queries through associated private endpoints in scope. For security reasons, it is recommended to use PrivateOnly whenever possible to avoid data exfiltration.\n\n* Private Only - This mode allows the connected virtual network to reach only Private Link resources. It is the most secure mode and is set as the default when the `privateEndpoints` parameter is configured.\n* Open - Allows the connected virtual network to reach both Private Link resources and the resources not in the AMPLS resource. Data exfiltration cannot be prevented in this mode."
+ }
+ },
+ "location": {
+ "type": "string",
+ "defaultValue": "global",
+ "metadata": {
+ "description": "Optional. The location of the private link scope. Should be global."
+ }
+ },
+ "lock": {
+ "$ref": "#/definitions/lockType",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The lock settings of the service."
+ }
+ },
+ "roleAssignments": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/roleAssignmentType"
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Array of role assignments to create."
+ }
+ },
+ "scopedResources": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/scopedResourceType"
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Configuration details for Azure Monitor Resources."
+ }
+ },
+ "privateEndpoints": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/privateEndpointSingleServiceType"
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible."
+ }
+ },
+ "tags": {
+ "type": "object",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Resource tags."
+ }
+ },
+ "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')]",
+ "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]",
+ "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]",
+ "Logic App Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '87a39d53-fc1b-424a-814c-f7e04687dc9e')]",
+ "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]",
+ "Monitoring Metrics Publisher": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb')]",
+ "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]",
+ "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')]",
+ "Tag Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4a9ae827-6dc8-4573-8ac7-8239d42aa03f')]",
+ "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
+ }
+ },
+ "resources": {
+ "avmTelemetry": {
+ "condition": "[parameters('enableTelemetry')]",
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2024-03-01",
+ "name": "[format('46d3xbcp.res.insights-privatelinkscope.{0}.{1}', replace('0.6.0', '.', '-'), 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"
+ }
+ }
+ }
+ }
+ },
+ "privateLinkScope": {
+ "type": "microsoft.insights/privateLinkScopes",
+ "apiVersion": "2021-07-01-preview",
+ "name": "[parameters('name')]",
+ "location": "[parameters('location')]",
+ "tags": "[parameters('tags')]",
+ "properties": {
+ "accessModeSettings": "[coalesce(parameters('accessModeSettings'), if(not(empty(parameters('privateEndpoints'))), createObject('ingestionAccessMode', 'PrivateOnly', 'queryAccessMode', 'PrivateOnly'), createObject('ingestionAccessMode', 'Open', 'queryAccessMode', 'Open')))]"
+ }
+ },
+ "privateLinkScope_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.insights/privateLinkScopes/{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": [
+ "privateLinkScope"
+ ]
+ },
+ "privateLinkScope_roleAssignments": {
+ "copy": {
+ "name": "privateLinkScope_roleAssignments",
+ "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
+ },
+ "type": "Microsoft.Authorization/roleAssignments",
+ "apiVersion": "2022-04-01",
+ "scope": "[format('microsoft.insights/privateLinkScopes/{0}', parameters('name'))]",
+ "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('microsoft.insights/privateLinkScopes', 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": [
+ "privateLinkScope"
+ ]
+ },
+ "privateLinkScope_scopedResource": {
+ "copy": {
+ "name": "privateLinkScope_scopedResource",
+ "count": "[length(coalesce(parameters('scopedResources'), createArray()))]"
+ },
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2022-09-01",
+ "name": "[format('{0}-PrivateLinkScope-ScopedResource-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "name": {
+ "value": "[coalesce(parameters('scopedResources'), createArray())[copyIndex()].name]"
+ },
+ "privateLinkScopeName": {
+ "value": "[parameters('name')]"
+ },
+ "linkedResourceId": {
+ "value": "[coalesce(parameters('scopedResources'), createArray())[copyIndex()].linkedResourceId]"
+ }
+ },
+ "template": {
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
+ "contentVersion": "1.0.0.0",
+ "metadata": {
+ "_generator": {
+ "name": "bicep",
+ "version": "0.33.93.31351",
+ "templateHash": "18319290317274254807"
+ },
+ "name": "Private Link Scope Scoped Resources",
+ "description": "This module deploys a Private Link Scope Scoped Resource."
+ },
+ "parameters": {
+ "name": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "Required. Name of the private link scoped resource."
+ }
+ },
+ "privateLinkScopeName": {
+ "type": "string",
+ "minLength": 1,
+ "metadata": {
+ "description": "Conditional. The name of the parent private link scope. Required if the template is used in a standalone deployment."
+ }
+ },
+ "linkedResourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "Required. The resource ID of the scoped Azure monitor resource."
+ }
+ }
+ },
+ "resources": [
+ {
+ "type": "Microsoft.Insights/privateLinkScopes/scopedResources",
+ "apiVersion": "2021-07-01-preview",
+ "name": "[format('{0}/{1}', parameters('privateLinkScopeName'), parameters('name'))]",
+ "properties": {
+ "linkedResourceId": "[parameters('linkedResourceId')]"
+ }
+ }
+ ],
+ "outputs": {
+ "resourceGroupName": {
+ "type": "string",
+ "metadata": {
+ "description": "The name of the resource group where the resource has been deployed."
+ },
+ "value": "[resourceGroup().name]"
+ },
+ "resourceId": {
+ "type": "string",
+ "metadata": {
+ "description": "The resource ID of the deployed scopedResource."
+ },
+ "value": "[resourceId('Microsoft.Insights/privateLinkScopes/scopedResources', parameters('privateLinkScopeName'), parameters('name'))]"
+ },
+ "name": {
+ "type": "string",
+ "metadata": {
+ "description": "The full name of the deployed Scoped Resource."
+ },
+ "value": "[parameters('name')]"
+ }
+ }
+ }
+ },
+ "dependsOn": [
+ "privateLinkScope"
+ ]
+ },
+ "privateLinkScope_privateEndpoints": {
+ "copy": {
+ "name": "privateLinkScope_privateEndpoints",
+ "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]"
+ },
+ "type": "Microsoft.Resources/deployments",
+ "apiVersion": "2022-09-01",
+ "name": "[format('{0}-privateLinkScope-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
+ "subscriptionId": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[2]]",
+ "resourceGroup": "[split(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupResourceId'), tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'subnetResourceId')), '/')[4]]",
+ "properties": {
+ "expressionEvaluationOptions": {
+ "scope": "inner"
+ },
+ "mode": "Incremental",
+ "parameters": {
+ "name": {
+ "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('microsoft.insights/privateLinkScopes', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'azuremonitor'), copyIndex()))]"
+ },
+ "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('microsoft.insights/privateLinkScopes', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'azuremonitor'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('microsoft.insights/privateLinkScopes', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'azuremonitor')))))), createObject('value', null()))]",
+ "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('microsoft.insights/privateLinkScopes', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'azuremonitor'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('microsoft.insights/privateLinkScopes', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'azuremonitor')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]",
+ "subnetResourceId": {
+ "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]"
+ },
+ "enableTelemetry": {
+ "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]"
+ },
+ "location": {
+ "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]"
+ },
+ "lock": {
+ "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]"
+ },
+ "privateDnsZoneGroup": {
+ "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]"
+ },
+ "roleAssignments": {
+ "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]"
+ },
+ "tags": {
+ "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]"
+ },
+ "customDnsConfigs": {
+ "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]"
+ },
+ "ipConfigurations": {
+ "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]"
+ },
+ "applicationSecurityGroupResourceIds": {
+ "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]"
+ },
+ "customNetworkInterfaceName": {
+ "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]"
+ }
+ },
+ "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.33.13.18514",
+ "templateHash": "15954548978129725136"
+ },
+ "name": "Private Endpoints",
+ "description": "This module deploys a Private Endpoint."
+ },
+ "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."
+ }
+ }
+ },
+ "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
+ }
+ },
+ "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."
+ }
+ }
+ },
+ "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"
+ }
+ }
+ },
+ "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"
+ }
+ }
+ },
+ "roleAssignmentType": {
+ "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."
+ }
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "parameters": {
+ "name": {
"type": "string",
"metadata": {
- "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment."
+ "description": "Required. Name of the private endpoint resource to create."
}
},
- "name": {
+ "subnetResourceId": {
"type": "string",
"metadata": {
- "description": "Required. The name of the TXT record."
+ "description": "Required. Resource ID of the subnet where the endpoint needs to be created."
}
},
- "metadata": {
- "type": "object",
- "metadata": {
- "__bicep_resource_derived_type!": {
- "source": "Microsoft.Network/privateDnsZones/TXT@2024-06-01#properties/properties/properties/metadata"
- },
- "description": "Optional. The metadata attached to the record set."
+ "applicationSecurityGroupResourceIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
},
- "nullable": true
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Application security groups in which the private endpoint IP configuration is included."
+ }
},
- "ttl": {
- "type": "int",
- "defaultValue": 3600,
+ "customNetworkInterfaceName": {
+ "type": "string",
+ "nullable": true,
"metadata": {
- "description": "Optional. The TTL (time-to-live) of the records in the record set."
+ "description": "Optional. The custom name of the network interface attached to the private endpoint."
}
},
- "txtRecords": {
+ "ipConfigurations": {
"type": "array",
- "metadata": {
- "__bicep_resource_derived_type!": {
- "source": "Microsoft.Network/privateDnsZones/TXT@2024-06-01#properties/properties/properties/txtRecords"
- },
- "description": "Optional. The list of TXT records in the record set."
+ "items": {
+ "$ref": "#/definitions/ipConfigurationType"
},
- "nullable": true
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints."
+ }
},
- "enableTelemetry": {
- "type": "bool",
- "defaultValue": true,
+ "privateDnsZoneGroup": {
+ "$ref": "#/definitions/privateDnsZoneGroupType",
+ "nullable": true,
"metadata": {
- "description": "Optional. Enable/Disable usage telemetry for module."
+ "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",
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. The lock settings of the service."
}
},
"roleAssignments": {
@@ -10581,6 +12488,50 @@
"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": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/customDnsConfigType"
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Optional. Custom DNS configurations."
+ }
+ },
+ "manualPrivateLinkServiceConnections": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/privateLinkServiceConnectionType"
+ },
+ "nullable": true,
+ "metadata": {
+ "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."
+ }
+ },
+ "privateLinkServiceConnections": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/privateLinkServiceConnectionType"
+ },
+ "nullable": true,
+ "metadata": {
+ "description": "Conditional. A grouping of information about the connection to the remote resource. Required if `manualPrivateLinkServiceConnections` is empty."
+ }
+ },
+ "enableTelemetry": {
+ "type": "bool",
+ "defaultValue": true,
+ "metadata": {
+ "description": "Optional. Enable/Disable usage telemetry for module."
+ }
}
},
"variables": {
@@ -10593,12 +12544,15 @@
],
"builtInRoleNames": {
"Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]",
- "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]",
+ "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')]",
- "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]"
+ "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]"
}
},
"resources": {
@@ -10606,7 +12560,7 @@
"condition": "[parameters('enableTelemetry')]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2024-03-01",
- "name": "[format('46d3xbcp.res.nw-privdnszonetxt.{0}.{1}', replace('0.1.0', '.', '-'), substring(uniqueString(deployment().name), 0, 4))]",
+ "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.10.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]",
"properties": {
"mode": "Incremental",
"template": {
@@ -10622,31 +12576,55 @@
}
}
},
- "privateDnsZone": {
- "existing": true,
- "type": "Microsoft.Network/privateDnsZones",
- "apiVersion": "2020-06-01",
- "name": "[parameters('privateDnsZoneName')]"
- },
- "TXT": {
- "type": "Microsoft.Network/privateDnsZones/TXT",
- "apiVersion": "2020-06-01",
- "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]",
+ "privateEndpoint": {
+ "type": "Microsoft.Network/privateEndpoints",
+ "apiVersion": "2023-11-01",
+ "name": "[parameters('name')]",
+ "location": "[parameters('location')]",
+ "tags": "[parameters('tags')]",
"properties": {
- "metadata": "[parameters('metadata')]",
- "ttl": "[parameters('ttl')]",
- "txtRecords": "[parameters('txtRecords')]"
+ "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')]"
+ }
}
},
- "TXT_roleAssignments": {
+ "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": "TXT_roleAssignments",
+ "name": "privateEndpoint_roleAssignments",
"count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]"
},
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2022-04-01",
- "scope": "[format('Microsoft.Network/privateDnsZones/{0}/TXT/{1}', parameters('privateDnsZoneName'), parameters('name'))]",
- "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateDnsZones/TXT', parameters('privateDnsZoneName'), parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]",
+ "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]",
@@ -10657,232 +12635,278 @@
"delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]"
},
"dependsOn": [
- "TXT"
+ "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.33.13.18514",
+ "templateHash": "5440815542537978381"
+ },
+ "name": "Private Endpoint Private DNS Zone Groups",
+ "description": "This module deploys a Private Endpoint Private DNS Zone Group."
+ },
+ "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')]"
+ }
+ }
+ },
+ "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": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed TXT record."
- },
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
- "metadata": {
- "description": "The resource ID of the deployed TXT record."
- },
- "value": "[resourceId('Microsoft.Network/privateDnsZones/TXT', parameters('privateDnsZoneName'), parameters('name'))]"
- },
"resourceGroupName": {
"type": "string",
"metadata": {
- "description": "The resource group of the deployed TXT record."
+ "description": "The resource group the private endpoint was deployed into."
},
"value": "[resourceGroup().name]"
- }
- }
- }
- },
- "dependsOn": [
- "privateDnsZone"
- ]
- },
- "privateDnsZone_virtualNetworkLinks": {
- "copy": {
- "name": "privateDnsZone_virtualNetworkLinks",
- "count": "[length(coalesce(parameters('virtualNetworkLinks'), createArray()))]"
- },
- "type": "Microsoft.Resources/deployments",
- "apiVersion": "2022-09-01",
- "name": "[format('{0}-PrivateDnsZone-VNetLink-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]",
- "properties": {
- "expressionEvaluationOptions": {
- "scope": "inner"
- },
- "mode": "Incremental",
- "parameters": {
- "privateDnsZoneName": {
- "value": "[parameters('name')]"
- },
- "name": {
- "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'name'), format('{0}-vnetlink', last(split(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()].virtualNetworkResourceId, '/'))))]"
- },
- "virtualNetworkResourceId": {
- "value": "[coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()].virtualNetworkResourceId]"
- },
- "location": {
- "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'location'), 'global')]"
- },
- "registrationEnabled": {
- "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'registrationEnabled'), false())]"
- },
- "tags": {
- "value": "[coalesce(tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'tags'), parameters('tags'))]"
- },
- "resolutionPolicy": {
- "value": "[tryGet(coalesce(parameters('virtualNetworkLinks'), createArray())[copyIndex()], 'resolutionPolicy')]"
- }
- },
- "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.37.4.10188",
- "templateHash": "517173107480898390"
},
- "name": "Private DNS Zone Virtual Network Link",
- "description": "This module deploys a Private DNS Zone Virtual Network Link."
- },
- "parameters": {
- "privateDnsZoneName": {
+ "resourceId": {
"type": "string",
"metadata": {
- "description": "Conditional. The name of the parent Private DNS zone. Required if the template is used in a standalone deployment."
- }
+ "description": "The resource ID of the private endpoint."
+ },
+ "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]"
},
"name": {
"type": "string",
- "defaultValue": "[format('{0}-vnetlink', last(split(parameters('virtualNetworkResourceId'), '/')))]",
"metadata": {
- "description": "Optional. The name of the virtual network link."
- }
+ "description": "The name of the private endpoint."
+ },
+ "value": "[parameters('name')]"
},
"location": {
"type": "string",
- "defaultValue": "global",
- "metadata": {
- "description": "Optional. The location of the PrivateDNSZone. Should be global."
- }
- },
- "tags": {
- "type": "object",
"metadata": {
- "__bicep_resource_derived_type!": {
- "source": "Microsoft.Network/privateDnsZones/virtualNetworkLinks@2024-06-01#properties/tags"
- },
- "description": "Optional. Tags of the resource."
+ "description": "The location the resource was deployed into."
},
- "nullable": true
- },
- "registrationEnabled": {
- "type": "bool",
- "defaultValue": false,
- "metadata": {
- "description": "Optional. Is auto-registration of virtual machine records in the virtual network in the Private DNS zone enabled?."
- }
+ "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]"
},
- "virtualNetworkResourceId": {
- "type": "string",
- "metadata": {
- "description": "Required. Link to another virtual network resource ID."
- }
- },
- "resolutionPolicy": {
- "type": "string",
- "nullable": true,
- "metadata": {
- "description": "Optional. The resolution policy on the virtual network link. Only applicable for virtual network links to privatelink zones, and for A,AAAA,CNAME queries. When set to `NxDomainRedirect`, Azure DNS resolver falls back to public resolution if private dns query resolution results in non-existent domain response. `Default` is configured as the default option."
- }
- }
- },
- "resources": {
- "privateDnsZone": {
- "existing": true,
- "type": "Microsoft.Network/privateDnsZones",
- "apiVersion": "2020-06-01",
- "name": "[parameters('privateDnsZoneName')]"
- },
- "virtualNetworkLink": {
- "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
- "apiVersion": "2024-06-01",
- "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('name'))]",
- "location": "[parameters('location')]",
- "tags": "[parameters('tags')]",
- "properties": {
- "registrationEnabled": "[parameters('registrationEnabled')]",
- "virtualNetwork": {
- "id": "[parameters('virtualNetworkResourceId')]"
- },
- "resolutionPolicy": "[parameters('resolutionPolicy')]"
- }
- }
- },
- "outputs": {
- "name": {
- "type": "string",
- "metadata": {
- "description": "The name of the deployed virtual network link."
+ "customDnsConfigs": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/customDnsConfigType"
},
- "value": "[parameters('name')]"
- },
- "resourceId": {
- "type": "string",
"metadata": {
- "description": "The resource ID of the deployed virtual network link."
+ "description": "The custom DNS configurations of the private endpoint."
},
- "value": "[resourceId('Microsoft.Network/privateDnsZones/virtualNetworkLinks', parameters('privateDnsZoneName'), parameters('name'))]"
+ "value": "[reference('privateEndpoint').customDnsConfigs]"
},
- "resourceGroupName": {
- "type": "string",
+ "networkInterfaceResourceIds": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
"metadata": {
- "description": "The resource group of the deployed virtual network link."
+ "description": "The resource IDs of the network interfaces associated with the private endpoint."
},
- "value": "[resourceGroup().name]"
+ "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]"
},
- "location": {
+ "groupId": {
"type": "string",
+ "nullable": true,
"metadata": {
- "description": "The location the resource was deployed into."
+ "description": "The group Id for the private endpoint Group."
},
- "value": "[reference('virtualNetworkLink', '2024-06-01', 'full').location]"
+ "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": [
- "privateDnsZone"
+ "privateLinkScope",
+ "privateLinkScope_scopedResource"
]
}
},
"outputs": {
- "resourceGroupName": {
+ "name": {
"type": "string",
"metadata": {
- "description": "The resource group the private DNS zone was deployed into."
+ "description": "The name of the private link scope."
},
- "value": "[resourceGroup().name]"
+ "value": "[parameters('name')]"
},
- "name": {
+ "resourceId": {
"type": "string",
"metadata": {
- "description": "The name of the private DNS zone."
+ "description": "The resource ID of the private link scope."
},
- "value": "[parameters('name')]"
+ "value": "[resourceId('microsoft.insights/privateLinkScopes', parameters('name'))]"
},
- "resourceId": {
+ "resourceGroupName": {
"type": "string",
"metadata": {
- "description": "The resource ID of the private DNS zone."
+ "description": "The resource group the private link scope was deployed into."
},
- "value": "[resourceId('Microsoft.Network/privateDnsZones', parameters('name'))]"
+ "value": "[resourceGroup().name]"
},
"location": {
"type": "string",
"metadata": {
"description": "The location the resource was deployed into."
},
- "value": "[reference('privateDnsZone', '2020-06-01', 'full').location]"
+ "value": "[reference('privateLinkScope', '2021-07-01-preview', 'full').location]"
+ },
+ "privateEndpoints": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/privateEndpointOutputType"
+ },
+ "metadata": {
+ "description": "The private endpoints of the private link scope."
+ },
+ "copy": {
+ "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]",
+ "input": {
+ "name": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.name.value]",
+ "resourceId": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]",
+ "groupId": "[tryGet(tryGet(reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs, 'groupId'), 'value')]",
+ "customDnsConfigs": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfigs.value]",
+ "networkInterfaceResourceIds": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]"
+ }
+ }
}
}
}
},
"dependsOn": [
+ "applicationInsights",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').ods)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').monitor)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').oms)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').agentSvc)]",
+ "dataCollectionEndpoint",
+ "logAnalyticsWorkspace",
"virtualNetwork"
]
},
@@ -13053,6 +15077,7 @@
"dataCollectionRuleProperties": {
"value": {
"kind": "Windows",
+ "dataCollectionEndpointResourceId": "[reference('dataCollectionEndpoint').outputs.resourceId.value]",
"dataSources": {
"performanceCounters": [
{
@@ -13110,26 +15135,6 @@
],
"name": "perfCounterDataSource60"
}
- ],
- "windowsEventLogs": [
- {
- "name": "SecurityAuditEvents",
- "streams": [
- "Microsoft-WindowsEvent"
- ],
- "eventLogName": "Security",
- "eventTypes": [
- {
- "eventType": "Audit Success"
- },
- {
- "eventType": "Audit Failure"
- }
- ],
- "xPathQueries": [
- "Security!*[System[(EventID=4624 or EventID=4625)]]"
- ]
- }
]
},
"destinations": {
@@ -13147,9 +15152,7 @@
],
"destinations": [
"[format('la-{0}', variables('dataCollectionRulesResourceName'))]"
- ],
- "transformKql": "source",
- "outputStream": "Microsoft-Perf"
+ ]
}
]
}
@@ -14221,6 +16224,7 @@
}
},
"dependsOn": [
+ "dataCollectionEndpoint",
"existingLogAnalyticsWorkspace",
"logAnalyticsWorkspace"
]
@@ -14619,7 +16623,7 @@
"value": "Windows"
},
"vmSize": {
- "value": "[coalesce(parameters('vmSize'), 'Standard_D2s_v3')]"
+ "value": "[coalesce(parameters('vmSize'), 'Standard_D2s_v5')]"
},
"adminUsername": {
"value": "[coalesce(parameters('vmAdminUsername'), 'JumpboxAdminUser')]"
@@ -23616,8 +25620,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "15268521456197740686"
+ "version": "0.38.33.27573",
+ "templateHash": "13645014962264885823"
},
"name": "AI Services and Project Module",
"description": "This module creates an AI Services resource and an AI Foundry project within it. It supports private networking, OpenAI deployments, and role assignments."
@@ -24957,8 +26961,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "6664885964502172426"
+ "version": "0.38.33.27573",
+ "templateHash": "14773633292567160969"
}
},
"definitions": {
@@ -25921,7 +27925,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": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
+ "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]",
"name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
"properties": {
"level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
@@ -25935,7 +27939,7 @@
},
"type": "Microsoft.Insights/diagnosticSettings",
"apiVersion": "2021-05-01-preview",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
+ "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]",
"name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
"properties": {
"copy": [
@@ -25973,7 +27977,7 @@
},
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
+ "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', 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]",
@@ -26669,8 +28673,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "14939823368517410024"
+ "version": "0.38.33.27573",
+ "templateHash": "14205022069293553223"
}
},
"definitions": {
@@ -26823,8 +28827,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "13151306134286549002"
+ "version": "0.38.33.27573",
+ "templateHash": "12063034585175087716"
}
},
"definitions": {
@@ -27041,8 +29045,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "6664885964502172426"
+ "version": "0.38.33.27573",
+ "templateHash": "14773633292567160969"
}
},
"definitions": {
@@ -28005,7 +30009,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": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
+ "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]",
"name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]",
"properties": {
"level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]",
@@ -28019,7 +30023,7 @@
},
"type": "Microsoft.Insights/diagnosticSettings",
"apiVersion": "2021-05-01-preview",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
+ "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', parameters('name'))]",
"name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]",
"properties": {
"copy": [
@@ -28057,7 +30061,7 @@
},
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2022-04-01",
- "scope": "[resourceId('Microsoft.CognitiveServices/accounts', parameters('name'))]",
+ "scope": "[format('Microsoft.CognitiveServices/accounts/{0}', 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]",
@@ -28753,8 +30757,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "14939823368517410024"
+ "version": "0.38.33.27573",
+ "templateHash": "14205022069293553223"
}
},
"definitions": {
@@ -28907,8 +30911,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "13151306134286549002"
+ "version": "0.38.33.27573",
+ "templateHash": "12063034585175087716"
}
},
"definitions": {
@@ -29206,8 +31210,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "9525047811797133596"
+ "version": "0.38.33.27573",
+ "templateHash": "8737165639797720533"
}
},
"definitions": {
@@ -37401,8 +39405,8 @@
},
"dependsOn": [
"appIdentity",
- "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageFile)]",
"[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)]",
+ "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageFile)]",
"logAnalyticsWorkspace",
"virtualNetwork"
]
@@ -37451,8 +39455,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "9495092499292590311"
+ "version": "0.38.33.27573",
+ "templateHash": "7725000075924948023"
}
},
"definitions": {
@@ -41314,8 +43318,8 @@
"metadata": {
"_generator": {
"name": "bicep",
- "version": "0.40.2.10011",
- "templateHash": "17583156542522410309"
+ "version": "0.38.33.27573",
+ "templateHash": "5400870525857167617"
}
},
"definitions": {
diff --git a/infra/main.waf.parameters.json b/infra/main.waf.parameters.json
index 98a1ead9..93b5eefb 100644
--- a/infra/main.waf.parameters.json
+++ b/infra/main.waf.parameters.json
@@ -47,6 +47,9 @@
"vmAdminPassword": {
"value": "${AZURE_ENV_JUMPBOX_ADMIN_PASSWORD}"
},
+ "vmSize": {
+ "value": "${AZURE_ENV_VM_SIZE}"
+ },
"backendExists": {
"value": "${SERVICE_BACKEND_RESOURCE_EXISTS=false}"
},
diff --git a/infra/main_custom.bicep b/infra/main_custom.bicep
index aa4a7553..cd34b604 100644
--- a/infra/main_custom.bicep
+++ b/infra/main_custom.bicep
@@ -566,7 +566,7 @@ module virtualMachine 'br/public:avm/res/compute/virtual-machine:0.20.0' = if (e
enableTelemetry: enableTelemetry
computerName: take(virtualMachineResourceName, 15)
osType: 'Windows'
- vmSize: vmSize ?? 'Standard_D2s_v3'
+ vmSize: vmSize ?? 'Standard_D2s_v5'
adminUsername: vmAdminUsername ?? 'JumpboxAdminUser'
adminPassword: vmAdminPassword ?? 'JumpboxAdminP@ssw0rd1234!'
managedIdentities: {
diff --git a/infra/modules/virtualNetwork.bicep b/infra/modules/virtualNetwork.bicep
index 54b507bc..82b158f6 100644
--- a/infra/modules/virtualNetwork.bicep
+++ b/infra/modules/virtualNetwork.bicep
@@ -170,10 +170,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 available
+// 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-Domain Routing (CIDR) Sizing Reference Table (Best Practices)
// | CIDR | # of Addresses | # of /24s | Notes |
diff --git a/infra/samples/network-subnet-design.bicep b/infra/samples/network-subnet-design.bicep
index 50347a91..63c90c39 100644
--- a/infra/samples/network-subnet-design.bicep
+++ b/infra/samples/network-subnet-design.bicep
@@ -110,7 +110,7 @@ import { jumpBoxConfigurationType } from 'network/jumpbox.bicep'
@description('Optional. Configuration for the Jumpbox VM. Leave null to omit Jumpbox creation.')
param jumpboxConfiguration jumpBoxConfigurationType = {
name: 'vm-jumpbox-${resourcesName}'
- size: 'Standard_D2s_v3' // Default size, can be overridden
+ size: 'Standard_D2s_v5' // Default size, can be overridden
username: vmAdminUsername
password: vmAdminPassword
subnet: {
diff --git a/infra/samples/network/network-resources.bicep b/infra/samples/network/network-resources.bicep
index 7e2e8658..076d9ae1 100644
--- a/infra/samples/network/network-resources.bicep
+++ b/infra/samples/network/network-resources.bicep
@@ -75,7 +75,7 @@ module jumpbox 'jumpbox.bicep' = if (!empty(jumpboxConfiguration)) {
params: {
name: jumpboxConfiguration.?name ?? 'vm-jumpbox-${resourcesName}'
vnetName: virtualNetwork.outputs.name
- size: jumpboxConfiguration.?size ?? 'Standard_D2s_v3'
+ size: jumpboxConfiguration.?size ?? 'Standard_D2s_v5'
logAnalyticsWorkspaceId: logAnalyticsWorkSpaceResourceId
location: location
subnet: jumpboxConfiguration.?subnet