From 8090ef33d14ca7258894a58644d2b8eb31e1a376 Mon Sep 17 00:00:00 2001 From: Harmanpreet-Microsoft Date: Tue, 17 Mar 2026 18:44:32 +0530 Subject: [PATCH 1/2] Remove unused parameters and definitions from main.parameters.json and main.waf.parameters.json --- infra/main.parameters.json | 65 +--------------------------------- infra/main.waf.parameters.json | 65 +--------------------------------- 2 files changed, 2 insertions(+), 128 deletions(-) diff --git a/infra/main.parameters.json b/infra/main.parameters.json index da8b3cc7..50364403 100644 --- a/infra/main.parameters.json +++ b/infra/main.parameters.json @@ -46,69 +46,6 @@ }, "vmAdminPassword": { "value": "${AZURE_ENV_JUMPBOX_ADMIN_PASSWORD}" - }, - "backendExists": { - "value": "${SERVICE_BACKEND_RESOURCE_EXISTS=false}" - }, - "backendDefinition": { - "value": { - "settings": [ - { - "name": "", - "value": "${VAR}", - "_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.", - "_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR} to use the value of 'VAR' from the current environment." - }, - { - "name": "", - "value": "${VAR_S}", - "secret": true, - "_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.", - "_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR_S} to use the value of 'VAR_S' from the current environment." - } - ] - } - }, - "frontendExists": { - "value": "${SERVICE_FRONTEND_RESOURCE_EXISTS=false}" - }, - "frontendDefinition": { - "value": { - "settings": [ - { - "name": "", - "value": "${VAR}", - "_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.", - "_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR} to use the value of 'VAR' from the current environment." - }, - { - "name": "", - "value": "${VAR_S}", - "secret": true, - "_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.", - "_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR_S} to use the value of 'VAR_S' from the current environment." - } - ] - } - }, - "principalId": { - "value": "${AZURE_PRINCIPAL_ID}" - }, - "aiModelDeployments": { - "value": [ - { - "name": "gpt-4o", - "model": { - "name": "gpt-4o", - "version": "2024-08-06", - "format": "OpenAI" - }, - "sku": { - "name": "GlobalStandard", - "capacity": 50 - } - } - ] } } -} +} \ No newline at end of file diff --git a/infra/main.waf.parameters.json b/infra/main.waf.parameters.json index 98a1ead9..49da5e4a 100644 --- a/infra/main.waf.parameters.json +++ b/infra/main.waf.parameters.json @@ -47,9 +47,6 @@ "vmAdminPassword": { "value": "${AZURE_ENV_JUMPBOX_ADMIN_PASSWORD}" }, - "backendExists": { - "value": "${SERVICE_BACKEND_RESOURCE_EXISTS=false}" - }, "enableMonitoring": { "value": true }, @@ -58,66 +55,6 @@ }, "enableScaling": { "value": true - }, - "backendDefinition": { - "value": { - "settings": [ - { - "name": "", - "value": "${VAR}", - "_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.", - "_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR} to use the value of 'VAR' from the current environment." - }, - { - "name": "", - "value": "${VAR_S}", - "secret": true, - "_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.", - "_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR_S} to use the value of 'VAR_S' from the current environment." - } - ] - } - }, - "frontendExists": { - "value": "${SERVICE_FRONTEND_RESOURCE_EXISTS=false}" - }, - "frontendDefinition": { - "value": { - "settings": [ - { - "name": "", - "value": "${VAR}", - "_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.", - "_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR} to use the value of 'VAR' from the current environment." - }, - { - "name": "", - "value": "${VAR_S}", - "secret": true, - "_comment_name": "The name of the environment variable when running in Azure. If empty, ignored.", - "_comment_value": "The value to provide. This can be a fixed literal, or an expression like ${VAR_S} to use the value of 'VAR_S' from the current environment." - } - ] - } - }, - "principalId": { - "value": "${AZURE_PRINCIPAL_ID}" - }, - "aiModelDeployments": { - "value": [ - { - "name": "gpt-4o", - "model": { - "name": "gpt-4o", - "version": "2024-08-06", - "format": "OpenAI" - }, - "sku": { - "name": "GlobalStandard", - "capacity": 50 - } - } - ] } } -} +} \ No newline at end of file From f91605649eca6ad12f3b7b940aa57654d53e35b6 Mon Sep 17 00:00:00 2001 From: Harmanpreet-Microsoft Date: Thu, 19 Mar 2026 12:50:40 +0530 Subject: [PATCH 2/2] Refactor parameter names for consistency and clarity across Bicep and JSON files --- .github/workflows/deploy.yml | 2 +- docs/CustomizingAzdParameters.md | 24 +- infra/main.bicep | 32 +- infra/main.json | 2096 +++++++++++++++++++++++++++++- infra/main.parameters.json | 30 +- infra/main.waf.parameters.json | 32 +- infra/main_custom.bicep | 28 +- 7 files changed, 2124 insertions(+), 120 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index cb0ad3d2..c61e4e8d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -142,7 +142,7 @@ jobs: --parameters \ solutionName="${{ env.SOLUTION_PREFIX }}" \ azureAiServiceLocation='${{ env.AZURE_LOCATION }}' \ - imageVersion="${IMAGE_TAG}" \ + imageTag="${IMAGE_TAG}" \ createdBy="Pipeline" \ tags="{'Purpose':'Deploying and Cleaning Up Resources for Validation','CreatedDate':'$current_date'}" diff --git a/docs/CustomizingAzdParameters.md b/docs/CustomizingAzdParameters.md index b71a16a3..70a75ae8 100644 --- a/docs/CustomizingAzdParameters.md +++ b/docs/CustomizingAzdParameters.md @@ -12,17 +12,17 @@ By default this template will use the environment name as the prefix to prevent | `AZURE_LOCATION` | string | `` | Location of the Azure resources. Controls where the infrastructure will be deployed. | | `AZURE_ENV_AI_SERVICE_LOCATION` | string | `` | Location of the Azure resources. Controls where the Azure AI Services will be deployed. | | `AZURE_ENV_MODEL_DEPLOYMENT_TYPE` | string | `GlobalStandard` | Change the Model Deployment Type (allowed values: Standard, GlobalStandard). | -| `AZURE_ENV_MODEL_NAME` | string | `gpt-4o` | Set the Model Name (allowed values: gpt-4o). | -| `AZURE_ENV_MODEL_VERSION` | string | `2024-08-06` | Set the Azure model version (allowed values: 2024-08-06) | -| `AZURE_ENV_MODEL_CAPACITY` | integer | `150` | Set the Model Capacity (choose a number based on available GPT model capacity in your subscription). | -| `AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID` | string | Guide to get your [Existing Workspace ID](/docs/re-use-log-analytics.md) | Set this if you want to reuse an existing Log Analytics Workspace instead of creating a new one. | +| `AZURE_ENV_GPT_MODEL_NAME` | string | `gpt-4o` | Set the Model Name (allowed values: gpt-4o). | +| `AZURE_ENV_GPT_MODEL_VERSION` | string | `2024-08-06` | Set the Azure model version (allowed values: 2024-08-06) | +| `AZURE_ENV_GPT_MODEL_CAPACITY` | integer | `150` | Set the Model Capacity (choose a number based on available GPT model capacity in your subscription). | +| `AZURE_ENV_LOG_ANALYTICS_WORKSPACE_RID`| string | Guide to get your [Existing Workspace ID](/docs/re-use-log-analytics.md) | Set this if you want to reuse an existing Log Analytics Workspace instead of creating a new one. | | `AZURE_ENV_IMAGETAG` | string | `latest` | Set the Image tag Like (allowed values: latest, dev, hotfix) | -| `AZURE_ENV_JUMPBOX_SIZE` | string | `Standard_DS2_v2` | Specifies the size of the Jumpbox Virtual Machine. Set a custom value if `enablePrivateNetworking` is `true`. | -| `AZURE_ENV_JUMPBOX_ADMIN_USERNAME` | string | `JumpboxAdminUser` | Specifies the administrator username for the Jumpbox Virtual Machine. | -| `AZURE_ENV_JUMPBOX_ADMIN_PASSWORD` | string | `JumpboxAdminP@ssw0rd1234!` | Specifies the administrator password for the Jumpbox Virtual Machine. | -| `AZURE_ENV_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_DS2_v2` | Specifies the size of the Jumpbox Virtual Machine. Set a custom value if `enablePrivateNetworking` is `true`. | +| `AZURE_ENV_VM_ADMIN_USERNAME` | string | `JumpboxAdminUser` | Specifies the administrator username for the Jumpbox Virtual Machine. | +| `AZURE_ENV_VM_ADMIN_PASSWORD` | string | `JumpboxAdminP@ssw0rd1234!` | Specifies the administrator password for the Jumpbox Virtual Machine. | +| `AZURE_ENV_SECONDARY_LOCATION` | string | *(not set by default)* | Specifies the secondary region for Cosmos DB. Required if `enableRedundancy` is `true`. | +| `AZURE_ENV_FOUNDRY_PROJECT_RID` | string | *(not set by default)* | Specifies the existing AI Foundry Project Resource ID if it needs to be reused. | +| `AZURE_ENV_CONTAINER_REGISTRY_ENDPOINT`| string | `cmsacontainerreg.azurecr.io` | Specifies the Azure Container Registry endpoint to use for container images. | --- @@ -36,12 +36,12 @@ azd env set Set the Log Analytics Workspace Id if you need to reuse the existing workspace ```shell -azd env set AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID '/subscriptions//resourceGroups//providers/Microsoft.OperationalInsights/workspaces/' +azd env set AZURE_ENV_LOG_ANALYTICS_WORKSPACE_RID '/subscriptions//resourceGroups//providers/Microsoft.OperationalInsights/workspaces/' ``` Set the Azure Existing AI Foundry Project Resource ID if you need to reuse the existing AI Foundry Project ```shell -azd env set AZURE_EXISTING_AI_PROJECT_RESOURCE_ID '/subscriptions//resourceGroups//providers/Microsoft.CognitiveServices/accounts//projects/' +azd env set AZURE_ENV_FOUNDRY_PROJECT_RID '/subscriptions//resourceGroups//providers/Microsoft.CognitiveServices/accounts//projects/' ``` **Example:** diff --git a/infra/main.bicep b/infra/main.bicep index 31852aa0..ff99f59f 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -57,13 +57,13 @@ var replicaRegionPairs = { var replicaLocation = replicaRegionPairs[resourceGroup().location] @description('Optional. AI model deployment token capacity. Defaults to 150K tokens per minute.') -param gptModelCapacity int = 150 +param gptDeploymentCapacity int = 150 @description('Optional. Enable monitoring for the resources. This will enable Application Insights and Log Analytics. Defaults to false.') param enableMonitoring bool = false @description('Optional. Enable scaling for the container apps. Defaults to false.') -param enableScaling bool = false +param enableScalability bool = false @description('Optional. Enable redundancy for applicable resources. Defaults to false.') param enableRedundancy bool = false @@ -95,7 +95,7 @@ param enableTelemetry bool = true @minLength(1) @description('Optional. GPT model deployment type. Defaults to GlobalStandard.') -param gptModelDeploymentType string = 'GlobalStandard' +param deploymentType string = 'GlobalStandard' @minLength(1) @description('Optional. Name of the GPT model to deploy. Defaults to gpt-4o.') @@ -103,17 +103,17 @@ param gptModelName string = 'gpt-4o' @minLength(1) @description('Optional. Set the Image tag. Defaults to latest_2025-11-10_599.') -param imageVersion string = 'latest_2025-11-10_599' +param imageTag string = 'latest_2025-11-10_599' -@description('Optional. Azure Container Registry name. Defaults to cmsacontainerreg.azurecr.io') -param acrName string = 'cmsacontainerreg.azurecr.io' +@description('Optional. Azure Container Registry endpoint. Defaults to cmsacontainerreg.azurecr.io') +param containerRegistryEndpoint string = 'cmsacontainerreg.azurecr.io' @minLength(1) @description('Optional. Version of the GPT model to deploy. Defaults to 2024-08-06.') param gptModelVersion string = '2024-08-06' @description('Optional. Use this parameter to use an existing AI project resource ID. Defaults to empty string.') -param azureExistingAIProjectResourceId string = '' +param existingFoundryProjectResourceId string = '' @description('Optional. Use this parameter to use an existing Log Analytics workspace resource ID. Defaults to empty string.') param existingLogAnalyticsWorkspaceId string = '' @@ -145,8 +145,8 @@ var modelDeployment = { version: gptModelVersion } sku: { - name: gptModelDeploymentType - capacity: gptModelCapacity + name: deploymentType + capacity: gptDeploymentCapacity } raiPolicyName: 'Microsoft.Default' } @@ -751,7 +751,7 @@ module aiServices 'modules/ai-foundry/aifoundry.bicep' = { aiServicesPrivateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.aiServices]!.outputs.resourceId } : null - existingFoundryProjectResourceId: azureExistingAIProjectResourceId + existingFoundryProjectResourceId: existingFoundryProjectResourceId disableLocalAuth: true //Should be set to true for WAF aligned configuration customSubDomainName: 'aif-${solutionSuffix}' apiProperties: { @@ -937,7 +937,7 @@ module containerAppBackend 'br/public:avm/res/app/container-app:0.19.0' = { containers: [ { name: 'cmsabackend' - image: '${acrName}/cmsabackend:${imageVersion}' + image: '${containerRegistryEndpoint}/cmsabackend:${imageTag}' env: concat( [ { @@ -1081,10 +1081,10 @@ module containerAppBackend 'br/public:avm/res/app/container-app:0.19.0' = { ingressTargetPort: 8000 ingressExternal: true scaleSettings: { - // maxReplicas: enableScaling ? 3 : 1 + // maxReplicas: enableScalability ? 3 : 1 maxReplicas: 1 // maxReplicas set to 1 (not 3) due to multiple agents created per type during WAF deployment minReplicas: 1 - rules: enableScaling + rules: enableScalability ? [ { name: 'http-scaler' @@ -1125,7 +1125,7 @@ module containerAppFrontend 'br/public:avm/res/app/container-app:0.19.0' = { value: 'prod' } ] - image: '${acrName}/cmsafrontend:${imageVersion}' + image: '${containerRegistryEndpoint}/cmsafrontend:${imageTag}' name: 'cmsafrontend' resources: { cpu: 1 @@ -1136,9 +1136,9 @@ module containerAppFrontend 'br/public:avm/res/app/container-app:0.19.0' = { ingressTargetPort: 3000 ingressExternal: true scaleSettings: { - maxReplicas: enableScaling ? 3 : 1 + maxReplicas: enableScalability ? 3 : 1 minReplicas: 1 - rules: enableScaling + rules: enableScalability ? [ { name: 'http-scaler' diff --git a/infra/main.json b/infra/main.json index bf15cc8e..073bef28 100644 --- a/infra/main.json +++ b/infra/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.40.2.10011", - "templateHash": "14323896881835347609" + "templateHash": "10907393850868295147" }, "name": "Modernize Your Code Solution Accelerator", "description": "CSA CTO Gold Standard Solution Accelerator for Modernize Your Code. \r\n" @@ -64,7 +64,7 @@ "description": "Required. Location for all AI service resources. This location can be different from the resource group location." } }, - "gptModelCapacity": { + "gptDeploymentCapacity": { "type": "int", "defaultValue": 150, "metadata": { @@ -78,7 +78,7 @@ "description": "Optional. Enable monitoring for the resources. This will enable Application Insights and Log Analytics. Defaults to false." } }, - "enableScaling": { + "enableScalability": { "type": "bool", "defaultValue": false, "metadata": { @@ -141,7 +141,7 @@ "description": "Optional. Enable/Disable usage telemetry for module." } }, - "gptModelDeploymentType": { + "deploymentType": { "type": "string", "defaultValue": "GlobalStandard", "minLength": 1, @@ -157,7 +157,7 @@ "description": "Optional. Name of the GPT model to deploy. Defaults to gpt-4o." } }, - "imageVersion": { + "imageTag": { "type": "string", "defaultValue": "latest_2025-11-10_599", "minLength": 1, @@ -165,11 +165,11 @@ "description": "Optional. Set the Image tag. Defaults to latest_2025-11-10_599." } }, - "acrName": { + "containerRegistryEndpoint": { "type": "string", "defaultValue": "cmsacontainerreg.azurecr.io", "metadata": { - "description": "Optional. Azure Container Registry name. Defaults to cmsacontainerreg.azurecr.io" + "description": "Optional. Azure Container Registry endpoint. Defaults to cmsacontainerreg.azurecr.io" } }, "gptModelVersion": { @@ -180,7 +180,7 @@ "description": "Optional. Version of the GPT model to deploy. Defaults to 2024-08-06." } }, - "azureExistingAIProjectResourceId": { + "existingFoundryProjectResourceId": { "type": "string", "defaultValue": "", "metadata": { @@ -227,8 +227,8 @@ "version": "[parameters('gptModelVersion')]" }, "sku": { - "name": "[parameters('gptModelDeploymentType')]", - "capacity": "[parameters('gptModelCapacity')]" + "name": "[parameters('deploymentType')]", + "capacity": "[parameters('gptDeploymentCapacity')]" }, "raiPolicyName": "Microsoft.Default" }, @@ -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", @@ -10886,6 +11241,1675 @@ "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": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "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." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/ipConfigurationType" + }, + "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." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone group to configure for the private endpoint." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "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." + } + }, + "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": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.10.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(variables('formattedRoleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", + "properties": { + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.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": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" + }, + "customDnsConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "networkInterfaceResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "The resource IDs of the network interfaces associated with the private endpoint." + }, + "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]" + }, + "groupId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'manualPrivateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0), tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'privateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0))]" + } + } + } + }, + "dependsOn": [ + "privateLinkScope", + "privateLinkScope_scopedResource" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private link scope." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private link scope." + }, + "value": "[resourceId('microsoft.insights/privateLinkScopes', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private link scope was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "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').monitor)]", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').ods)]", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').agentSvc)]", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').storageBlob)]", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').oms)]", + "dataCollectionEndpoint", + "logAnalyticsWorkspace", + "virtualNetwork" + ] + }, "bastionHost": { "condition": "[parameters('enablePrivateNetworking')]", "type": "Microsoft.Resources/deployments", @@ -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" ] @@ -23554,7 +25558,7 @@ "logAnalyticsWorkspaceResourceId": "[if(parameters('enableMonitoring'), if(variables('useExistingLogAnalytics'), createObject('value', parameters('existingLogAnalyticsWorkspaceId')), createObject('value', reference('logAnalyticsWorkspace').outputs.resourceId.value)), createObject('value', ''))]", "privateNetworking": "[if(parameters('enablePrivateNetworking'), createObject('value', createObject('virtualNetworkResourceId', reference('virtualNetwork').outputs.resourceId.value, 'subnetResourceId', reference('virtualNetwork').outputs.pepsSubnetResourceId.value, 'cogServicesPrivateDnsZoneResourceId', reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)).outputs.resourceId.value, 'openAIPrivateDnsZoneResourceId', reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)).outputs.resourceId.value, 'aiServicesPrivateDnsZoneResourceId', reference(format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)).outputs.resourceId.value)), createObject('value', null()))]", "existingFoundryProjectResourceId": { - "value": "[parameters('azureExistingAIProjectResourceId')]" + "value": "[parameters('existingFoundryProjectResourceId')]" }, "disableLocalAuth": { "value": true @@ -29148,8 +31152,8 @@ "dependsOn": [ "appIdentity", "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').openAI)]", - "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)]", "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').cognitiveServices)]", + "[format('avmPrivateDnsZones[{0}]', variables('dnsZoneIndex').aiServices)]", "logAnalyticsWorkspace", "virtualNetwork" ] @@ -48484,7 +50488,7 @@ "value": [ { "name": "cmsabackend", - "image": "[format('{0}/cmsabackend:{1}', parameters('acrName'), parameters('imageVersion'))]", + "image": "[format('{0}/cmsabackend:{1}', parameters('containerRegistryEndpoint'), parameters('imageTag'))]", "env": "[concat(createArray(createObject('name', 'COSMOSDB_ENDPOINT', 'value', reference('cosmosDb').outputs.endpoint.value), createObject('name', 'COSMOSDB_DATABASE', 'value', reference('cosmosDb').outputs.databaseName.value), createObject('name', 'COSMOSDB_BATCH_CONTAINER', 'value', reference('cosmosDb').outputs.containerNames.value.batch), createObject('name', 'COSMOSDB_FILE_CONTAINER', 'value', reference('cosmosDb').outputs.containerNames.value.file), createObject('name', 'COSMOSDB_LOG_CONTAINER', 'value', reference('cosmosDb').outputs.containerNames.value.log), createObject('name', 'AZURE_BLOB_ACCOUNT_NAME', 'value', reference('storageAccount').outputs.name.value), createObject('name', 'AZURE_BLOB_CONTAINER_NAME', 'value', variables('appStorageContainerName')), createObject('name', 'MIGRATOR_AGENT_MODEL_DEPLOY', 'value', variables('modelDeployment').name), createObject('name', 'PICKER_AGENT_MODEL_DEPLOY', 'value', variables('modelDeployment').name), createObject('name', 'FIXER_AGENT_MODEL_DEPLOY', 'value', variables('modelDeployment').name), createObject('name', 'SEMANTIC_VERIFIER_AGENT_MODEL_DEPLOY', 'value', variables('modelDeployment').name), createObject('name', 'SYNTAX_CHECKER_AGENT_MODEL_DEPLOY', 'value', variables('modelDeployment').name), createObject('name', 'SELECTION_MODEL_DEPLOY', 'value', variables('modelDeployment').name), createObject('name', 'TERMINATION_MODEL_DEPLOY', 'value', variables('modelDeployment').name), createObject('name', 'AZURE_AI_AGENT_MODEL_DEPLOYMENT_NAME', 'value', variables('modelDeployment').name), createObject('name', 'AI_PROJECT_ENDPOINT', 'value', reference('aiServices').outputs.aiProjectInfo.value.apiEndpoint), createObject('name', 'AZURE_AI_AGENT_PROJECT_CONNECTION_STRING', 'value', reference('aiServices').outputs.aiProjectInfo.value.apiEndpoint), createObject('name', 'AZURE_AI_AGENT_PROJECT_NAME', 'value', reference('aiServices').outputs.aiProjectInfo.value.name), createObject('name', 'AZURE_AI_AGENT_RESOURCE_GROUP_NAME', 'value', resourceGroup().name), createObject('name', 'AZURE_AI_AGENT_SUBSCRIPTION_ID', 'value', subscription().subscriptionId), createObject('name', 'AZURE_AI_AGENT_ENDPOINT', 'value', reference('aiServices').outputs.aiProjectInfo.value.apiEndpoint), createObject('name', 'AZURE_CLIENT_ID', 'value', reference('appIdentity').outputs.clientId.value), createObject('name', 'APP_ENV', 'value', 'prod'), createObject('name', 'AZURE_BASIC_LOGGING_LEVEL', 'value', 'INFO'), createObject('name', 'AZURE_PACKAGE_LOGGING_LEVEL', 'value', 'WARNING'), createObject('name', 'AZURE_LOGGING_PACKAGES', 'value', '')), if(parameters('enableMonitoring'), createArray(createObject('name', 'APPLICATIONINSIGHTS_INSTRUMENTATION_KEY', 'value', reference('applicationInsights').outputs.instrumentationKey.value), createObject('name', 'APPLICATIONINSIGHTS_CONNECTION_STRING', 'value', reference('applicationInsights').outputs.connectionString.value)), createArray()))]", "resources": { "cpu": 1, @@ -48504,7 +50508,7 @@ "value": { "maxReplicas": 1, "minReplicas": 1, - "rules": "[if(parameters('enableScaling'), createArray(createObject('name', 'http-scaler', 'http', createObject('metadata', createObject('concurrentRequests', 100)))), createArray())]" + "rules": "[if(parameters('enableScalability'), createArray(createObject('name', 'http-scaler', 'http', createObject('metadata', createObject('concurrentRequests', 100)))), createArray())]" } }, "tags": { @@ -50077,7 +52081,7 @@ "value": "prod" } ], - "image": "[format('{0}/cmsafrontend:{1}', parameters('acrName'), parameters('imageVersion'))]", + "image": "[format('{0}/cmsafrontend:{1}', parameters('containerRegistryEndpoint'), parameters('imageTag'))]", "name": "cmsafrontend", "resources": { "cpu": 1, @@ -50094,9 +52098,9 @@ }, "scaleSettings": { "value": { - "maxReplicas": "[if(parameters('enableScaling'), 3, 1)]", + "maxReplicas": "[if(parameters('enableScalability'), 3, 1)]", "minReplicas": 1, - "rules": "[if(parameters('enableScaling'), createArray(createObject('name', 'http-scaler', 'http', createObject('metadata', createObject('concurrentRequests', 100)))), createArray())]" + "rules": "[if(parameters('enableScalability'), createArray(createObject('name', 'http-scaler', 'http', createObject('metadata', createObject('concurrentRequests', 100)))), createArray())]" } }, "tags": { diff --git a/infra/main.parameters.json b/infra/main.parameters.json index 50364403..a7643965 100644 --- a/infra/main.parameters.json +++ b/infra/main.parameters.json @@ -8,44 +8,44 @@ "location": { "value": "${AZURE_LOCATION}" }, - "gptModelDeploymentType": { + "deploymentType": { "value": "${AZURE_ENV_MODEL_DEPLOYMENT_TYPE}" }, "gptModelName": { - "value": "${AZURE_ENV_MODEL_NAME}" + "value": "${AZURE_ENV_GPT_MODEL_NAME}" }, - "gptModelCapacity": { - "value": "${AZURE_ENV_MODEL_CAPACITY}" + "gptDeploymentCapacity": { + "value": "${AZURE_ENV_GPT_MODEL_CAPACITY}" }, "gptModelVersion": { - "value": "${AZURE_ENV_MODEL_VERSION}" + "value": "${AZURE_ENV_GPT_MODEL_VERSION}" }, - "imageVersion": { + "imageTag": { "value": "${AZURE_ENV_IMAGETAG=latest}" }, - "acrName": { - "value": "${AZURE_ENV_ACR_NAME=cmsacontainerreg.azurecr.io}" + "containerRegistryEndpoint": { + "value": "${AZURE_ENV_CONTAINER_REGISTRY_ENDPOINT=cmsacontainerreg.azurecr.io}" }, "existingLogAnalyticsWorkspaceId": { - "value": "${AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID}" + "value": "${AZURE_ENV_LOG_ANALYTICS_WORKSPACE_RID}" }, - "azureExistingAIProjectResourceId": { - "value": "${AZURE_EXISTING_AI_PROJECT_RESOURCE_ID}" + "existingFoundryProjectResourceId": { + "value": "${AZURE_ENV_FOUNDRY_PROJECT_RID}" }, "secondaryLocation": { - "value": "${AZURE_ENV_COSMOS_SECONDARY_LOCATION}" + "value": "${AZURE_ENV_SECONDARY_LOCATION}" }, "azureAiServiceLocation": { "value": "${AZURE_ENV_AI_SERVICE_LOCATION}" }, "vmSize": { - "value": "${AZURE_ENV_JUMPBOX_SIZE}" + "value": "${AZURE_ENV_VM_SIZE}" }, "vmAdminUsername": { - "value": "${AZURE_ENV_JUMPBOX_ADMIN_USERNAME}" + "value": "${AZURE_ENV_VM_ADMIN_USERNAME}" }, "vmAdminPassword": { - "value": "${AZURE_ENV_JUMPBOX_ADMIN_PASSWORD}" + "value": "${AZURE_ENV_VM_ADMIN_PASSWORD}" } } } \ No newline at end of file diff --git a/infra/main.waf.parameters.json b/infra/main.waf.parameters.json index 49da5e4a..3b6974fe 100644 --- a/infra/main.waf.parameters.json +++ b/infra/main.waf.parameters.json @@ -8,44 +8,44 @@ "location": { "value": "${AZURE_LOCATION}" }, - "gptModelDeploymentType": { + "deploymentType": { "value": "${AZURE_ENV_MODEL_DEPLOYMENT_TYPE}" }, "gptModelName": { - "value": "${AZURE_ENV_MODEL_NAME}" + "value": "${AZURE_ENV_GPT_MODEL_NAME}" }, - "gptModelCapacity": { - "value": "${AZURE_ENV_MODEL_CAPACITY}" + "gptDeploymentCapacity": { + "value": "${AZURE_ENV_GPT_MODEL_CAPACITY}" }, "gptModelVersion": { - "value": "${AZURE_ENV_MODEL_VERSION}" + "value": "${AZURE_ENV_GPT_MODEL_VERSION}" }, - "imageVersion": { + "imageTag": { "value": "${AZURE_ENV_IMAGETAG=latest}" }, - "acrName": { - "value": "${AZURE_ENV_ACR_NAME=cmsacontainerreg.azurecr.io}" + "containerRegistryEndpoint": { + "value": "${AZURE_ENV_CONTAINER_REGISTRY_ENDPOINT=cmsacontainerreg.azurecr.io}" }, "existingLogAnalyticsWorkspaceId": { - "value": "${AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID}" + "value": "${AZURE_ENV_LOG_ANALYTICS_WORKSPACE_RID}" }, - "azureExistingAIProjectResourceId": { - "value": "${AZURE_EXISTING_AI_PROJECT_RESOURCE_ID}" + "existingFoundryProjectResourceId": { + "value": "${AZURE_ENV_FOUNDRY_PROJECT_RID}" }, "secondaryLocation": { - "value": "${AZURE_ENV_COSMOS_SECONDARY_LOCATION}" + "value": "${AZURE_ENV_SECONDARY_LOCATION}" }, "azureAiServiceLocation": { "value": "${AZURE_ENV_AI_SERVICE_LOCATION}" }, "vmSize": { - "value": "${AZURE_ENV_JUMPBOX_SIZE}" + "value": "${AZURE_ENV_VM_SIZE}" }, "vmAdminUsername": { - "value": "${AZURE_ENV_JUMPBOX_ADMIN_USERNAME}" + "value": "${AZURE_ENV_VM_ADMIN_USERNAME}" }, "vmAdminPassword": { - "value": "${AZURE_ENV_JUMPBOX_ADMIN_PASSWORD}" + "value": "${AZURE_ENV_VM_ADMIN_PASSWORD}" }, "enableMonitoring": { "value": true @@ -53,7 +53,7 @@ "enablePrivateNetworking": { "value": true }, - "enableScaling": { + "enableScalability": { "value": true } } diff --git a/infra/main_custom.bicep b/infra/main_custom.bicep index aa4a7553..97239df6 100644 --- a/infra/main_custom.bicep +++ b/infra/main_custom.bicep @@ -57,13 +57,13 @@ var replicaRegionPairs = { var replicaLocation = replicaRegionPairs[resourceGroup().location] @description('Optional. AI model deployment token capacity. Defaults to 150K tokens per minute.') -param gptModelCapacity int = 150 +param gptDeploymentCapacity int = 150 @description('Optional. Enable monitoring for the resources. This will enable Application Insights and Log Analytics. Defaults to false.') param enableMonitoring bool = false @description('Optional. Enable scaling for the container apps. Defaults to false.') -param enableScaling bool = false +param enableScalability bool = false @description('Optional. Enable redundancy for applicable resources. Defaults to false.') param enableRedundancy bool = false @@ -95,7 +95,7 @@ param enableTelemetry bool = true @minLength(1) @description('Optional. GPT model deployment type. Defaults to GlobalStandard.') -param gptModelDeploymentType string = 'GlobalStandard' +param deploymentType string = 'GlobalStandard' @minLength(1) @description('Optional. Name of the GPT model to deploy. Defaults to gpt-4o.') @@ -108,14 +108,14 @@ param frontendImageName string = '' @minLength(1) @description('Optional. Set the Image tag. Defaults to latest') -param imageVersion string = 'latest' +param imageTag string = 'latest' @minLength(1) @description('Optional. Version of the GPT model to deploy. Defaults to 2024-08-06.') param gptModelVersion string = '2024-08-06' @description('Optional. Use this parameter to use an existing AI project resource ID. Defaults to empty string.') -param azureExistingAIProjectResourceId string = '' +param existingFoundryProjectResourceId string = '' @description('Optional. Use this parameter to use an existing Log Analytics workspace resource ID. Defaults to empty string.') param existingLogAnalyticsWorkspaceId string = '' @@ -147,8 +147,8 @@ var modelDeployment = { version: gptModelVersion } sku: { - name: gptModelDeploymentType - capacity: gptModelCapacity + name: deploymentType + capacity: gptDeploymentCapacity } raiPolicyName: 'Microsoft.Default' } @@ -680,7 +680,7 @@ module aiServices 'modules/ai-foundry/aifoundry.bicep' = { aiServicesPrivateDnsZoneResourceId: avmPrivateDnsZones[dnsZoneIndex.aiServices]!.outputs.resourceId } : null - existingFoundryProjectResourceId: azureExistingAIProjectResourceId + existingFoundryProjectResourceId: existingFoundryProjectResourceId disableLocalAuth: true //Should be set to true for WAF aligned configuration customSubDomainName: 'aif-${solutionSuffix}' apiProperties: { @@ -895,7 +895,7 @@ module containerAppBackend 'br/public:avm/res/app/container-app:0.19.0' = { containers: [ { name: 'cmsabackend' - image: !empty(backendImageName) ? backendImageName : 'cmsacontainerreg.azurecr.io/cmsabackend:${imageVersion}' + image: !empty(backendImageName) ? backendImageName : 'cmsacontainerreg.azurecr.io/cmsabackend:${imageTag}' env: concat( [ { @@ -1035,10 +1035,10 @@ module containerAppBackend 'br/public:avm/res/app/container-app:0.19.0' = { ingressTargetPort: 8000 ingressExternal: true scaleSettings: { - // maxReplicas: enableScaling ? 3 : 1 + // maxReplicas: enableScalability ? 3 : 1 maxReplicas: 1 // maxReplicas set to 1 (not 3) due to multiple agents created per type during WAF deployment minReplicas: 1 - rules: enableScaling + rules: enableScalability ? [ { name: 'http-scaler' @@ -1087,7 +1087,7 @@ module containerAppFrontend 'br/public:avm/res/app/container-app:0.19.0' = { value: 'prod' } ] - image: !empty(frontendImageName) ? frontendImageName : 'cmsacontainerreg.azurecr.io/cmsafrontend:${imageVersion}' + image: !empty(frontendImageName) ? frontendImageName : 'cmsacontainerreg.azurecr.io/cmsafrontend:${imageTag}' name: 'cmsafrontend' resources: { cpu: 1 @@ -1098,9 +1098,9 @@ module containerAppFrontend 'br/public:avm/res/app/container-app:0.19.0' = { ingressTargetPort: 3000 ingressExternal: true scaleSettings: { - maxReplicas: enableScaling ? 3 : 1 + maxReplicas: enableScalability ? 3 : 1 minReplicas: 1 - rules: enableScaling + rules: enableScalability ? [ { name: 'http-scaler'