From 7e0f96f06c7e127f577b70cdaa3b788ada2c6e8c Mon Sep 17 00:00:00 2001 From: Rafi-Microsoft Date: Wed, 6 May 2026 13:59:09 +0530 Subject: [PATCH 1/7] docs: add Bicep CLI prerequisite to local deployment guide Adds Bicep CLI (v0.33.0+) to the local deployment prerequisites so users provisioning this accelerator locally have the required Bicep version installed before running 'azd up' / 'az deployment'. Work item: AB#42634 --- docs/deploymentguide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/deploymentguide.md b/docs/deploymentguide.md index e987506..4e9d0c7 100644 --- a/docs/deploymentguide.md +++ b/docs/deploymentguide.md @@ -25,6 +25,7 @@ To deploy this solution accelerator, ensure you have access to an [Azure subscri |------|----------------|--------------| | Azure CLI | 2.61.0+ | [Install Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) | | Azure Developer CLI (azd) | 1.15.0+ | [Install azd](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd) | +| Bicep CLI | 0.33.0+ | [Install Bicep](https://learn.microsoft.com/azure/azure-resource-manager/bicep/install) | | Git | Latest | [Install Git](https://git-scm.com/downloads) | | PowerShell | 7.0+ | [Install PowerShell](https://learn.microsoft.com/powershell/scripting/install/installing-powershell) | From b85823630f5182ea0d4182b2f4b85d9dd445fbc0 Mon Sep 17 00:00:00 2001 From: Rafi-Microsoft Date: Wed, 6 May 2026 19:49:27 +0530 Subject: [PATCH 2/7] docs: Add Bicep CLI (v0.33.0+) version pinning alongside azd/PowerShell --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f9e6dba..4827f68 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,8 @@ Follow the deployment guide to deploy this solution to your own Azure subscripti > **Note:** This solution accelerator requires **Azure Developer CLI (azd) version 1.15.0 or higher**. [Download azd here](https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/install-azd). +> **Note:** This solution accelerator also requires **Bicep CLI version 0.33.0 or higher** for compiling infrastructure templates. [Install Bicep](https://learn.microsoft.com/azure/azure-resource-manager/bicep/install). + [**📘 Click here to launch the Deployment Guide**](./docs/deploymentguide.md)
From 92366301a7a6888ab27a16ba28126563ca38ecef Mon Sep 17 00:00:00 2001 From: Rafi-Microsoft Date: Wed, 6 May 2026 20:06:30 +0530 Subject: [PATCH 3/7] docs: Add Bicep CLI version pinning to prerequisites table --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4827f68..d0d1ed8 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ Follow the deployment guide to deploy this solution to your own Azure subscripti | **Microsoft Purview** | Existing tenant-level Purview account (or ability to create one) | | **Azure CLI** | Version 2.61.0 or later | | **Azure Developer CLI** | Version 1.15.0 or later | + | **Bicep CLI** | Version 0.33.0 or later | | **Quota** | Sufficient Azure OpenAI quota ([check here](./docs/quota_check.md)) | > **Note:** Fabric automation is optional. To disable all Fabric automation, set `fabricCapacityPreset = 'none'` and `fabricWorkspacePreset = 'none'` in `infra/main.bicepparam`. From 13277a13c82e4ce619eed2d8b6f54d26600b4b20 Mon Sep 17 00:00:00 2001 From: Saswato-Microsoft Date: Mon, 11 May 2026 20:59:11 +0530 Subject: [PATCH 4/7] feat: add support for Bring Your Own Log Analytics Workspace in deployment --- docs/deploymentguide.md | 17 +++++++- docs/parameter_guide.md | 43 +++++++++++++++++++ infra/main.bicep | 82 ++++++++++++++++++++++++++++++++++++ infra/main.bicepparam | 7 ++++ infra/main.json | 92 +++++++++++++++++++++++++++++++++++++++-- 5 files changed, 235 insertions(+), 6 deletions(-) diff --git a/docs/deploymentguide.md b/docs/deploymentguide.md index 4e9d0c7..0cf2629 100644 --- a/docs/deploymentguide.md +++ b/docs/deploymentguide.md @@ -239,6 +239,7 @@ After setting these variables, run `azd up` normally. The deployment will attach | `postgreSqlNetworkIsolation` | PostgreSQL private networking toggle (defaults to `networkIsolation`) | `networkIsolation` | | `useExistingVNet` | Reuse an existing VNet | `false` | | `existingVnetResourceId` | Existing VNet resource ID (when `useExistingVNet=true`) | `` | +| `existingLogAnalyticsWorkspaceResourceId` | Existing Log Analytics workspace to receive Foundry app + PostgreSQL + Fabric capacity diagnostics. May live in another subscription within the same tenant. | `` | | `vmUserName` | Jump box VM admin username | `VM_ADMIN_USERNAME` env var or `testvmuser` | | `vmAdminPassword` | Jump box VM admin password | `VM_ADMIN_PASSWORD` env var | @@ -268,8 +269,20 @@ To check and adjust quota settings, follow the [Quota Check Guide](./quota_check
Reusing Existing Resources -**Log Analytics Workspace:** -See [Parameter Guide](./parameter_guide.md) for Log Analytics reuse guidance. +**Log Analytics Workspace (BYO observability):** + +By default the wrapper does not create a Log Analytics workspace or Application Insights, so the deployed Foundry application and wrapper-managed resources (PostgreSQL Flexible Server, Fabric capacity) have no telemetry sink. If you already have a centralized workspace, point the deployment at it: + +```powershell +azd env set EXISTING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID "/subscriptions//resourceGroups//providers/Microsoft.OperationalInsights/workspaces/" +``` + +When set, the deployment will: +1. Create an Application Insights component in the deployment resource group, linked to your existing workspace. +2. Route PostgreSQL diagnostic logs and metrics to your workspace. +3. Route Fabric capacity diagnostic logs and metrics to your workspace. + +The workspace may live in a different resource group or subscription within the same tenant. The identity running `azd up` needs **Log Analytics Contributor** on the workspace's subscription. See the **Observability — Bring Your Own Log Analytics Workspace** section in the [Parameter Guide](./parameter_guide.md) for the full output reference (App Insights resource ID, connection string, instrumentation key).
diff --git a/docs/parameter_guide.md b/docs/parameter_guide.md index b62882f..14b0676 100644 --- a/docs/parameter_guide.md +++ b/docs/parameter_guide.md @@ -82,6 +82,49 @@ param fabricCapacitySku = 'F2' // adjust SKU as needed --- +## Observability — Bring Your Own Log Analytics Workspace + +By default the wrapper sets `deployLogAnalytics = false`, so the AI Landing Zone does not create a new Log Analytics workspace and Application Insights is not provisioned. If you already have a centralized Log Analytics workspace (for example one shared across the platform), you can wire the deployed Foundry application and the wrapper-managed resources (PostgreSQL Flexible Server, Fabric capacity) to it. + +### How it works + +When you set `existingLogAnalyticsWorkspaceResourceId`: + +1. An **Application Insights** component is created in the deployment resource group and linked to your existing workspace via `WorkspaceResourceId`. Its name follows the same `appInsightsName` convention (`appi-`). +2. **PostgreSQL Flexible Server** diagnostic settings (all logs + AllMetrics) are routed to your workspace. +3. **Fabric capacity** diagnostic settings (all logs + AllMetrics) are routed to your workspace. +4. The connection string and instrumentation key are exposed as deployment outputs so post-provision automation (or your application configuration) can pick them up. + +> **Note:** This is wrapper-side wiring. The upstream AI Landing Zone submodule does not natively support a BYO Log Analytics workspace, so leave `deployLogAnalytics = false` and `deployAppInsights = true` (the defaults) when using BYO so the LAZ does not create its own workspace + Application Insights pair. + +### Setting it via azd env + +```powershell +azd env set EXISTING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID "/subscriptions//resourceGroups//providers/Microsoft.OperationalInsights/workspaces/" +``` + +Or set it directly in `infra/main.bicepparam`: + +```bicep +param existingLogAnalyticsWorkspaceResourceId = '/subscriptions//resourceGroups//providers/Microsoft.OperationalInsights/workspaces/' +``` + +### Outputs + +| Output | Description | +|--------|-------------| +| `existingLogAnalyticsWorkspaceResourceIdOut` | Echo of the supplied workspace resource ID | +| `byoApplicationInsightsResourceId` | Resource ID of the App Insights component created against the BYO workspace | +| `byoApplicationInsightsName` | Name of the App Insights component | +| `byoApplicationInsightsConnectionString` | Connection string for app instrumentation | +| `byoApplicationInsightsInstrumentationKey` | Instrumentation key for legacy SDKs | + +### Permissions + +The identity running the deployment needs **Log Analytics Contributor** (or equivalent) on the existing workspace to attach diagnostic settings and link the new Application Insights component. + +--- + ## Table of Contents 1. [Basic Parameters](#basic-parameters) 2. [Deployment Toggles](#deployment-toggles) diff --git a/infra/main.bicep b/infra/main.bicep index cf81bf7..ef23974 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -111,6 +111,9 @@ param aiFoundryStorageAccountResourceId string = '' param aiFoundryCosmosDBAccountResourceId string = '' param keyVaultResourceId string = '' +@description('Optional. Full ARM resource ID of an existing Log Analytics workspace to use for observability of the deployed Foundry application and wrapper-managed resources (PostgreSQL, Fabric capacity). When provided, an Application Insights component is created in the deployment resource group and linked to this workspace, and diagnostic settings on the wrapper-managed resources are routed to it. Leave empty to skip BYO behavior. Format: /subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.OperationalInsights/workspaces/{name}.') +param existingLogAnalyticsWorkspaceResourceId string = '' + @description('Identity options.') param useUAI bool = false param useCAppAPIKey bool = false @@ -405,6 +408,49 @@ var postgreSqlPrivateEndpoints = postgreSqlNetworkIsolation ? [ } ] : [] +// ---------------------------------------------------------------------- +// BYO Log Analytics Workspace (observability for the Foundry application +// and wrapper-managed resources). When existingLogAnalyticsWorkspaceResourceId +// is provided, an Application Insights component is created in this +// resource group and linked to that workspace, and diagnostic settings on +// wrapper-managed resources (PostgreSQL, Fabric capacity) are routed to it. +// ---------------------------------------------------------------------- +var byoLogAnalyticsEnabled = !empty(existingLogAnalyticsWorkspaceResourceId) +var byoCreateAppInsights = byoLogAnalyticsEnabled && deployAppInsights && !deployLogAnalytics + +resource byoAppInsights 'Microsoft.Insights/components@2020-02-02' = if (byoCreateAppInsights) { + name: appInsightsName + location: effectiveLocation + kind: 'web' + tags: deploymentTags + properties: { + Application_Type: 'web' + WorkspaceResourceId: existingLogAnalyticsWorkspaceResourceId + DisableIpMasking: false + publicNetworkAccessForIngestion: 'Enabled' + publicNetworkAccessForQuery: 'Enabled' + } +} + +var postgreSqlDiagnosticSettings = (deployPostgreSql && byoLogAnalyticsEnabled) ? [ + { + name: 'send-to-byo-law' + workspaceResourceId: existingLogAnalyticsWorkspaceResourceId + logCategoriesAndGroups: [ + { + categoryGroup: 'allLogs' + enabled: true + } + ] + metricCategories: [ + { + category: 'AllMetrics' + enabled: true + } + ] + } +] : [] + module postgreSqlFlexibleServer 'br/public:avm/res/db-for-postgre-sql/flexible-server:0.15.2' = if (deployPostgreSql) { name: 'postgresql-flexible' params: { @@ -424,6 +470,7 @@ module postgreSqlFlexibleServer 'br/public:avm/res/db-for-postgre-sql/flexible-s version: postgreSqlVersion storageSizeGB: postgreSqlStorageSizeGB privateEndpoints: postgreSqlPrivateEndpoints + diagnosticSettings: postgreSqlDiagnosticSettings tags: deploymentTags } } @@ -465,6 +512,33 @@ module fabricCapacity 'modules/fabric-capacity.bicep' = if (effectiveFabricCapac } } +resource fabricCapacityResource 'Microsoft.Fabric/capacities@2023-11-01' existing = if (effectiveFabricCapacityMode == 'create' && byoLogAnalyticsEnabled) { + name: capacityName + dependsOn: [ + fabricCapacity + ] +} + +resource fabricCapacityDiagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (effectiveFabricCapacityMode == 'create' && byoLogAnalyticsEnabled) { + name: 'send-to-byo-law' + scope: fabricCapacityResource + properties: { + workspaceId: existingLogAnalyticsWorkspaceResourceId + logs: [ + { + categoryGroup: 'allLogs' + enabled: true + } + ] + metrics: [ + { + category: 'AllMetrics' + enabled: true + } + ] + } +} + // ======================================== // OUTPUTS - Pass through from AI Landing Zone // ======================================== @@ -532,3 +606,11 @@ output desiredFabricWorkspaceName string = effectiveFabricWorkspaceName // Purview outputs (for post-provision scripts) output purviewAccountResourceId string = purviewAccountResourceId output purviewCollectionName string = !empty(purviewCollectionName) ? purviewCollectionName : (!empty(environmentName) ? 'collection-${environmentName}' : 'collection-${baseName}') + +// Observability outputs (BYO Log Analytics Workspace) +output existingLogAnalyticsWorkspaceResourceIdOut string = existingLogAnalyticsWorkspaceResourceId +output byoApplicationInsightsResourceId string = byoCreateAppInsights ? byoAppInsights.id : '' +output byoApplicationInsightsName string = byoCreateAppInsights ? byoAppInsights.name : '' +#disable-next-line outputs-should-not-contain-secrets +output byoApplicationInsightsConnectionString string = byoCreateAppInsights ? byoAppInsights.properties.ConnectionString : '' +output byoApplicationInsightsInstrumentationKey string = byoCreateAppInsights ? byoAppInsights.properties.InstrumentationKey : '' diff --git a/infra/main.bicepparam b/infra/main.bicepparam index 88e6bb0..3f85894 100644 --- a/infra/main.bicepparam +++ b/infra/main.bicepparam @@ -23,6 +23,13 @@ param keyVaultResourceId = '' param useExistingVNet = false param existingVnetResourceId = readEnvironmentVariable('EXISTING_VNET_RESOURCE_ID', '') +// BYO Log Analytics Workspace for observability of the deployed Foundry +// application and wrapper-managed resources (PostgreSQL, Fabric capacity). +// When provided, an Application Insights component is created in this RG and +// linked to this workspace. Leave empty to skip BYO behavior. +// Format: /subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.OperationalInsights/workspaces/{name} +param existingLogAnalyticsWorkspaceResourceId = readEnvironmentVariable('EXISTING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID', '') + // Optional additional Entra object IDs to grant Search roles. param aiSearchAdditionalAccessObjectIds = [] diff --git a/infra/main.json b/infra/main.json index ffd08db..4ec7c8d 100644 --- a/infra/main.json +++ b/infra/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "10203842773715246176" + "version": "0.43.1.21952", + "templateHash": "11455293291109344813" }, "description": "Deploys AI Landing Zone with Fabric capacity extension" }, @@ -354,6 +354,13 @@ "type": "string", "defaultValue": "" }, + "existingLogAnalyticsWorkspaceResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Full ARM resource ID of an existing Log Analytics workspace to use for observability of the deployed Foundry application and wrapper-managed resources (PostgreSQL, Fabric capacity). When provided, an Application Insights component is created in the deployment resource group and linked to this workspace, and diagnostic settings on the wrapper-managed resources are routed to it. Leave empty to skip BYO behavior. Format: /subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.OperationalInsights/workspaces/{name}." + } + }, "useUAI": { "type": "bool", "defaultValue": false, @@ -825,6 +832,9 @@ "effectiveKeyVaultResourceId": "[if(not(empty(parameters('keyVaultResourceId'))), parameters('keyVaultResourceId'), resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName')))]", "effectivePostgreSqlAdminPassword": "[if(equals(parameters('postgreSqlAdminPassword'), '$(secretOrRandomPassword)'), format('{0}!{1}', uniqueString(subscription().id, resourceGroup().id, parameters('postgreSqlServerName')), replace(parameters('generatedPostgreSqlAdminPassword'), '-', '')), parameters('postgreSqlAdminPassword'))]", "postgreSqlPrivateEndpoints": "[if(parameters('postgreSqlNetworkIsolation'), createArray(createObject('name', variables('postgreSqlPrivateEndpointName'), 'subnetResourceId', format('{0}/subnets/{1}', variables('effectiveVnetResourceId'), parameters('peSubnetName')), 'privateDnsZoneGroup', createObject('privateDnsZoneGroupConfigs', createArray(createObject('privateDnsZoneResourceId', resourceId('Microsoft.Network/privateDnsZones', variables('postgreSqlPrivateDnsZoneName'))))))), createArray())]", + "byoLogAnalyticsEnabled": "[not(empty(parameters('existingLogAnalyticsWorkspaceResourceId')))]", + "byoCreateAppInsights": "[and(and(variables('byoLogAnalyticsEnabled'), parameters('deployAppInsights')), not(parameters('deployLogAnalytics')))]", + "postgreSqlDiagnosticSettings": "[if(and(parameters('deployPostgreSql'), variables('byoLogAnalyticsEnabled')), createArray(createObject('name', 'send-to-byo-law', 'workspaceResourceId', parameters('existingLogAnalyticsWorkspaceResourceId'), 'logCategoriesAndGroups', createArray(createObject('categoryGroup', 'allLogs', 'enabled', true())), 'metricCategories', createArray(createObject('category', 'AllMetrics', 'enabled', true())))), createArray())]", "effectiveAiSearchResourceId": "[if(not(empty(parameters('aiSearchResourceId'))), parameters('aiSearchResourceId'), resourceId('Microsoft.Search/searchServices', parameters('searchServiceName')))]", "effectiveStorageAccountResourceId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]", "effectiveFabricWorkspaceName": "[if(equals(variables('effectiveFabricWorkspaceMode'), 'byo'), if(not(empty(parameters('fabricWorkspaceName'))), parameters('fabricWorkspaceName'), if(not(empty(parameters('environmentName'))), format('workspace-{0}', parameters('environmentName')), format('workspace-{0}', parameters('baseName')))), if(not(empty(parameters('environmentName'))), format('workspace-{0}', parameters('environmentName')), format('workspace-{0}', parameters('baseName'))))]", @@ -2409,6 +2419,22 @@ "postgreSqlPrivateDnsZone" ] }, + "byoAppInsights": { + "condition": "[variables('byoCreateAppInsights')]", + "type": "Microsoft.Insights/components", + "apiVersion": "2020-02-02", + "name": "[parameters('appInsightsName')]", + "location": "[variables('effectiveLocation')]", + "kind": "web", + "tags": "[parameters('deploymentTags')]", + "properties": { + "Application_Type": "web", + "WorkspaceResourceId": "[parameters('existingLogAnalyticsWorkspaceResourceId')]", + "DisableIpMasking": false, + "publicNetworkAccessForIngestion": "Enabled", + "publicNetworkAccessForQuery": "Enabled" + } + }, "postgreSqlFlexibleServerResource": { "condition": "[parameters('deployPostgreSql')]", "existing": true, @@ -2438,6 +2464,41 @@ "value": "[variables('effectivePostgreSqlAdminPassword')]" } }, + "fabricCapacityResource": { + "condition": "[and(equals(variables('effectiveFabricCapacityMode'), 'create'), variables('byoLogAnalyticsEnabled'))]", + "existing": true, + "type": "Microsoft.Fabric/capacities", + "apiVersion": "2023-11-01", + "name": "[variables('capacityName')]", + "dependsOn": [ + "fabricCapacity" + ] + }, + "fabricCapacityDiagnostics": { + "condition": "[and(equals(variables('effectiveFabricCapacityMode'), 'create'), variables('byoLogAnalyticsEnabled'))]", + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[resourceId('Microsoft.Fabric/capacities', variables('capacityName'))]", + "name": "send-to-byo-law", + "properties": { + "workspaceId": "[parameters('existingLogAnalyticsWorkspaceResourceId')]", + "logs": [ + { + "categoryGroup": "allLogs", + "enabled": true + } + ], + "metrics": [ + { + "category": "AllMetrics", + "enabled": true + } + ] + }, + "dependsOn": [ + "fabricCapacity" + ] + }, "postgreSqlFlexibleServer": { "condition": "[parameters('deployPostgreSql')]", "type": "Microsoft.Resources/deployments", @@ -2491,6 +2552,9 @@ "privateEndpoints": { "value": "[variables('postgreSqlPrivateEndpoints')]" }, + "diagnosticSettings": { + "value": "[variables('postgreSqlDiagnosticSettings')]" + }, "tags": { "value": "[parameters('deploymentTags')]" } @@ -5114,8 +5178,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.42.1.51946", - "templateHash": "12325469206187179338" + "version": "0.43.1.21952", + "templateHash": "2514295757830674592" } }, "parameters": { @@ -5353,6 +5417,26 @@ "purviewCollectionName": { "type": "string", "value": "[if(not(empty(parameters('purviewCollectionName'))), parameters('purviewCollectionName'), if(not(empty(parameters('environmentName'))), format('collection-{0}', parameters('environmentName')), format('collection-{0}', parameters('baseName'))))]" + }, + "existingLogAnalyticsWorkspaceResourceIdOut": { + "type": "string", + "value": "[parameters('existingLogAnalyticsWorkspaceResourceId')]" + }, + "byoApplicationInsightsResourceId": { + "type": "string", + "value": "[if(variables('byoCreateAppInsights'), resourceId('Microsoft.Insights/components', parameters('appInsightsName')), '')]" + }, + "byoApplicationInsightsName": { + "type": "string", + "value": "[if(variables('byoCreateAppInsights'), parameters('appInsightsName'), '')]" + }, + "byoApplicationInsightsConnectionString": { + "type": "string", + "value": "[if(variables('byoCreateAppInsights'), reference('byoAppInsights').ConnectionString, '')]" + }, + "byoApplicationInsightsInstrumentationKey": { + "type": "string", + "value": "[if(variables('byoCreateAppInsights'), reference('byoAppInsights').InstrumentationKey, '')]" } } } \ No newline at end of file From d734b5593c7663649ab9691e9df06c578a80c2e2 Mon Sep 17 00:00:00 2001 From: Saswato-Microsoft Date: Tue, 12 May 2026 11:10:56 +0530 Subject: [PATCH 5/7] fix: adding additional comments for existingLogAnalyticsWorkspaceResourceId Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- infra/main.bicep | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/infra/main.bicep b/infra/main.bicep index ef23974..c45cd43 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -411,9 +411,11 @@ var postgreSqlPrivateEndpoints = postgreSqlNetworkIsolation ? [ // ---------------------------------------------------------------------- // BYO Log Analytics Workspace (observability for the Foundry application // and wrapper-managed resources). When existingLogAnalyticsWorkspaceResourceId -// is provided, an Application Insights component is created in this -// resource group and linked to that workspace, and diagnostic settings on -// wrapper-managed resources (PostgreSQL, Fabric capacity) are routed to it. +// is provided, diagnostic settings on wrapper-managed resources +// (PostgreSQL, Fabric capacity) are routed to that workspace. An +// Application Insights component is created in this resource group and +// linked to that workspace only when BYO Log Analytics is enabled, +// deployAppInsights is true, and deployLogAnalytics is false. // ---------------------------------------------------------------------- var byoLogAnalyticsEnabled = !empty(existingLogAnalyticsWorkspaceResourceId) var byoCreateAppInsights = byoLogAnalyticsEnabled && deployAppInsights && !deployLogAnalytics From da1efb8f74b6b97be9af14f794ccbee3adde2a44 Mon Sep 17 00:00:00 2001 From: Saswato-Microsoft Date: Tue, 12 May 2026 13:42:10 +0530 Subject: [PATCH 6/7] fix: update permissions and outputs for BYO Log Analytics and Application Insights integration Co-authored-by: Copilot --- docs/deploymentguide.md | 2 +- docs/parameter_guide.md | 8 +++++++- infra/main.bicep | 1 + infra/main.bicepparam | 7 +++++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/deploymentguide.md b/docs/deploymentguide.md index 0cf2629..596e479 100644 --- a/docs/deploymentguide.md +++ b/docs/deploymentguide.md @@ -282,7 +282,7 @@ When set, the deployment will: 2. Route PostgreSQL diagnostic logs and metrics to your workspace. 3. Route Fabric capacity diagnostic logs and metrics to your workspace. -The workspace may live in a different resource group or subscription within the same tenant. The identity running `azd up` needs **Log Analytics Contributor** on the workspace's subscription. See the **Observability — Bring Your Own Log Analytics Workspace** section in the [Parameter Guide](./parameter_guide.md) for the full output reference (App Insights resource ID, connection string, instrumentation key). +The workspace may live in a different resource group or subscription within the same tenant. The identity running `azd up` needs **`Microsoft.Insights/diagnosticSettings/write`** on the workspace itself (covered by the built-in **Log Analytics Contributor** role scoped to the workspace or its resource group — subscription-wide rights are not required). See the **Observability — Bring Your Own Log Analytics Workspace** section in the [Parameter Guide](./parameter_guide.md) for the full output reference (App Insights resource ID, connection string, instrumentation key) and notes on deployment-history exposure of those values. diff --git a/docs/parameter_guide.md b/docs/parameter_guide.md index 14b0676..2220286 100644 --- a/docs/parameter_guide.md +++ b/docs/parameter_guide.md @@ -119,9 +119,15 @@ param existingLogAnalyticsWorkspaceResourceId = '/subscriptions//resourc | `byoApplicationInsightsConnectionString` | Connection string for app instrumentation | | `byoApplicationInsightsInstrumentationKey` | Instrumentation key for legacy SDKs | +> **Sensitive outputs:** The connection string and instrumentation key are bootstrap credentials for sending telemetry to your Application Insights resource. They are emitted as deployment outputs so post-provision scripts and `azd` env can wire them into application configuration. Anyone with read access to the deployment history (subscription/RG `Microsoft.Resources/deployments/read`) can retrieve these values — keep that access scoped appropriately. + ### Permissions -The identity running the deployment needs **Log Analytics Contributor** (or equivalent) on the existing workspace to attach diagnostic settings and link the new Application Insights component. +The identity running the deployment needs permission to attach diagnostic settings to the workspace and to create the Application Insights component: + +- **`Microsoft.Insights/diagnosticSettings/write`** on the BYO Log Analytics workspace (or its resource group). The built-in **Log Analytics Contributor** role on the workspace (or its RG) covers this — there is no need to grant subscription-wide rights. +- **`Microsoft.Insights/components/write`** on the deployment resource group (covered by **Contributor** on the deployment RG, which the deployment identity already needs to provision the rest of the stack). +- The PostgreSQL Flexible Server and Fabric capacity that emit diagnostics are wrapper-managed in the deployment RG, so no additional cross-resource permissions are required. --- diff --git a/infra/main.bicep b/infra/main.bicep index c45cd43..cd13390 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -615,4 +615,5 @@ output byoApplicationInsightsResourceId string = byoCreateAppInsights ? byoAppIn output byoApplicationInsightsName string = byoCreateAppInsights ? byoAppInsights.name : '' #disable-next-line outputs-should-not-contain-secrets output byoApplicationInsightsConnectionString string = byoCreateAppInsights ? byoAppInsights.properties.ConnectionString : '' +#disable-next-line outputs-should-not-contain-secrets output byoApplicationInsightsInstrumentationKey string = byoCreateAppInsights ? byoAppInsights.properties.InstrumentationKey : '' diff --git a/infra/main.bicepparam b/infra/main.bicepparam index 3f85894..300cd0b 100644 --- a/infra/main.bicepparam +++ b/infra/main.bicepparam @@ -25,8 +25,11 @@ param existingVnetResourceId = readEnvironmentVariable('EXISTING_VNET_RESOURCE_I // BYO Log Analytics Workspace for observability of the deployed Foundry // application and wrapper-managed resources (PostgreSQL, Fabric capacity). -// When provided, an Application Insights component is created in this RG and -// linked to this workspace. Leave empty to skip BYO behavior. +// When provided, diagnostic settings on the wrapper-managed resources are +// routed to this workspace. An Application Insights component is also +// created in this RG and linked to the workspace, but only when +// deployAppInsights is true and deployLogAnalytics is false (the wrapper +// defaults). Leave empty to skip BYO behavior. // Format: /subscriptions/{subId}/resourceGroups/{rg}/providers/Microsoft.OperationalInsights/workspaces/{name} param existingLogAnalyticsWorkspaceResourceId = readEnvironmentVariable('EXISTING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID', '') From c3f8a15a79f473f99509a61f9e533c8c5565a279 Mon Sep 17 00:00:00 2001 From: Harmanpreet-Microsoft Date: Tue, 12 May 2026 18:28:26 +0000 Subject: [PATCH 7/7] fix: remove fabric capacity resources and diagnostics for BYO Log Analytics --- infra/main.bicep | 29 +---------------------------- infra/main.json | 43 ++++--------------------------------------- 2 files changed, 5 insertions(+), 67 deletions(-) diff --git a/infra/main.bicep b/infra/main.bicep index cd13390..64dc47d 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -412,7 +412,7 @@ var postgreSqlPrivateEndpoints = postgreSqlNetworkIsolation ? [ // BYO Log Analytics Workspace (observability for the Foundry application // and wrapper-managed resources). When existingLogAnalyticsWorkspaceResourceId // is provided, diagnostic settings on wrapper-managed resources -// (PostgreSQL, Fabric capacity) are routed to that workspace. An +// (currently PostgreSQL) are routed to that workspace. An // Application Insights component is created in this resource group and // linked to that workspace only when BYO Log Analytics is enabled, // deployAppInsights is true, and deployLogAnalytics is false. @@ -514,33 +514,6 @@ module fabricCapacity 'modules/fabric-capacity.bicep' = if (effectiveFabricCapac } } -resource fabricCapacityResource 'Microsoft.Fabric/capacities@2023-11-01' existing = if (effectiveFabricCapacityMode == 'create' && byoLogAnalyticsEnabled) { - name: capacityName - dependsOn: [ - fabricCapacity - ] -} - -resource fabricCapacityDiagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (effectiveFabricCapacityMode == 'create' && byoLogAnalyticsEnabled) { - name: 'send-to-byo-law' - scope: fabricCapacityResource - properties: { - workspaceId: existingLogAnalyticsWorkspaceResourceId - logs: [ - { - categoryGroup: 'allLogs' - enabled: true - } - ] - metrics: [ - { - category: 'AllMetrics' - enabled: true - } - ] - } -} - // ======================================== // OUTPUTS - Pass through from AI Landing Zone // ======================================== diff --git a/infra/main.json b/infra/main.json index 4ec7c8d..6004a18 100644 --- a/infra/main.json +++ b/infra/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.43.1.21952", - "templateHash": "11455293291109344813" + "version": "0.43.8.12551", + "templateHash": "1222454929578026913" }, "description": "Deploys AI Landing Zone with Fabric capacity extension" }, @@ -2464,41 +2464,6 @@ "value": "[variables('effectivePostgreSqlAdminPassword')]" } }, - "fabricCapacityResource": { - "condition": "[and(equals(variables('effectiveFabricCapacityMode'), 'create'), variables('byoLogAnalyticsEnabled'))]", - "existing": true, - "type": "Microsoft.Fabric/capacities", - "apiVersion": "2023-11-01", - "name": "[variables('capacityName')]", - "dependsOn": [ - "fabricCapacity" - ] - }, - "fabricCapacityDiagnostics": { - "condition": "[and(equals(variables('effectiveFabricCapacityMode'), 'create'), variables('byoLogAnalyticsEnabled'))]", - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[resourceId('Microsoft.Fabric/capacities', variables('capacityName'))]", - "name": "send-to-byo-law", - "properties": { - "workspaceId": "[parameters('existingLogAnalyticsWorkspaceResourceId')]", - "logs": [ - { - "categoryGroup": "allLogs", - "enabled": true - } - ], - "metrics": [ - { - "category": "AllMetrics", - "enabled": true - } - ] - }, - "dependsOn": [ - "fabricCapacity" - ] - }, "postgreSqlFlexibleServer": { "condition": "[parameters('deployPostgreSql')]", "type": "Microsoft.Resources/deployments", @@ -5178,8 +5143,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.43.1.21952", - "templateHash": "2514295757830674592" + "version": "0.43.8.12551", + "templateHash": "11293123033508500089" } }, "parameters": {