diff --git a/.gitignore b/.gitignore index 035048ee2..198952770 100644 --- a/.gitignore +++ b/.gitignore @@ -383,3 +383,7 @@ env/ # Auto-generated build artifacts src/templates/finops-hub-copilot-studio/knowledge/query-catalog.md +.gate/ +todo/ +done/ +release/scloud-occurrence-report.md diff --git a/docs-mslearn/toolkit/changelog.md b/docs-mslearn/toolkit/changelog.md index dc22e673f..85207d70f 100644 --- a/docs-mslearn/toolkit/changelog.md +++ b/docs-mslearn/toolkit/changelog.md @@ -3,7 +3,7 @@ title: FinOps toolkit changelog description: Review the latest features and enhancements in the FinOps toolkit, including updates to FinOps hubs, Power BI reports, and more. author: MSBrett ms.author: brettwil -ms.date: 04/29/2026 +ms.date: 05/12/2026 ms.topic: reference ms.service: finops ms.subservice: finops-toolkit @@ -55,6 +55,7 @@ _Released April 2026_ ### [FinOps hubs](hubs/finops-hubs-overview.md) v14 - **Added** + - Added [Microsoft Sovereign Cloud](/azure/azure-sovereign-clouds/microsoft-sovereign-cloud) support with environment-aware DNS suffix handling for Azure Government, Azure China, and other sovereign environments ([#2081](https://github.com/microsoft/finops-toolkit/pull/2081)). - Added ability to ingest recommendations from Azure Advisor and custom Azure Resource Graph queries ([#2011](https://github.com/microsoft/finops-toolkit/issues/2011)). - Custom recommendations include stopped VMs, unattached disks, underutilized resources, and more. - Added [Copilot Studio agent template](hubs/configure-ai-copilot-studio.md) with instructions, schema reference, query catalog, and weekly report guide for creating a FinOps Hub Agent in Microsoft Copilot Studio using the Kusto Query MCP Server. @@ -65,6 +66,10 @@ _Released April 2026_ - Data Explorer SKU and retention settings are now only visible when Azure Data Explorer mode is selected. - Documented the `__.parquet` filename convention, full-folder replacement requirement, and manifest content rules for ingesting custom FOCUS datasets to prevent silent data loss ([#2096](https://github.com/microsoft/finops-toolkit/issues/2096)). - **Fixed** + - Fixed hardcoded Kusto DNS suffix to use an environment-aware lookup map with correct values for all supported clouds ([#2081](https://github.com/microsoft/finops-toolkit/pull/2081)). + - Fixed incorrect Azure China ADX DNS suffix (`kusto.chinacloudapi.cn` → `kusto.windows.cn`) ([#2081](https://github.com/microsoft/finops-toolkit/pull/2081)). + - Fixed `createUiDefinition.json` storage URL validation to accept sovereign cloud storage suffixes ([#2081](https://github.com/microsoft/finops-toolkit/pull/2081)). + - Fixed `gitapp.hub.com` typo in ADF linked service URL ([#2081](https://github.com/microsoft/finops-toolkit/pull/2081)). - Fixed Init-DataFactory deployment script failing when an Event Grid subscription is already provisioning by checking subscription status before attempting subscribe/unsubscribe and polling separately for completion ([#1996](https://github.com/microsoft/finops-toolkit/issues/1996)). - Fixed `msexports_ExecuteETL` pipeline failing on empty export files by adding a row count check ([#1535](https://github.com/microsoft/finops-toolkit/issues/1535)). - Fixed Data Explorer dashboard cost and savings KPIs producing invalid sums in multi-billing-currency tenants by adding a Currency parameter that scopes tile queries to a single currency ([#2093](https://github.com/microsoft/finops-toolkit/issues/2093)). diff --git a/src/templates/finops-hub/createUiDefinition.json b/src/templates/finops-hub/createUiDefinition.json index a2af4f504..da1f029b8 100644 --- a/src/templates/finops-hub/createUiDefinition.json +++ b/src/templates/finops-hub/createUiDefinition.json @@ -166,11 +166,11 @@ "name": "remoteHubStorageUri", "type": "Microsoft.Common.TextBox", "label": "Remote hub storage URI", - "toolTip": "Data Lake storage endpoint from the remote hub storage account. Copy from the storage account Settings > Endpoints > Data Lake storage. Example: https://myremotehub.dfs.core.windows.net/", + "toolTip": "Data Lake storage endpoint from the remote hub storage account. Copy from the storage account Settings > Endpoints > Data Lake storage. Example: https://myremotehub.dfs.core.windows.net/ (endpoint suffix varies by cloud)", "constraints": { "required": "[equals(basics('analyticsBackend').analyticsEngine, 'remote')]", - "regex": "^https://.*\\.dfs\\.core\\.windows\\.net/?$", - "validationMessage": "Must be a valid Data Lake storage endpoint URL in the format: https://storageaccount.dfs.core.windows.net/" + "regex": "^https://.*\\.dfs\\.core\\.[a-z.]+/?$", + "validationMessage": "Must be a valid Data Lake storage endpoint URL (e.g., https://storageaccount.dfs.core.windows.net/ for Azure public cloud)" }, "visible": "[equals(basics('analyticsBackend').analyticsEngine, 'remote')]" }, diff --git a/src/templates/finops-hub/modules/Microsoft.FinOpsHubs/Analytics/app.bicep b/src/templates/finops-hub/modules/Microsoft.FinOpsHubs/Analytics/app.bicep index b880e7108..84a29d95c 100644 --- a/src/templates/finops-hub/modules/Microsoft.FinOpsHubs/Analytics/app.bicep +++ b/src/templates/finops-hub/modules/Microsoft.FinOpsHubs/Analytics/app.bicep @@ -143,7 +143,13 @@ var useFabric = !empty(fabricQueryUri) var useAzure = !useFabric && !empty(clusterName) // cSpell:ignore ftkver, privatelink -var dataExplorerPrivateDnsZoneName = replace('privatelink.${app.hub.location}.${replace(environment().suffixes.storage, 'core', 'kusto')}', '..', '.') +var dataExplorerDnsSuffixLookup = { + AzureCloud: 'kusto.windows.net' + AzureUSGovernment: 'kusto.usgovcloudapi.net' + AzureChinaCloud: 'kusto.windows.cn' +} +var dataExplorerDnsSuffix = dataExplorerDnsSuffixLookup[?environment().name] ?? replace(environment().suffixes.storage, 'core', 'kusto') +var dataExplorerPrivateDnsZoneName = replace('privatelink.${app.hub.location}.${dataExplorerDnsSuffix}', '..', '.') // Actual = Minimum(ClusterMaximumConcurrentOperations, Number of nodes in cluster * Maximum(1, Core count per node * CoreUtilizationCoefficient)) var ingestionCapacity = { @@ -219,7 +225,7 @@ var dataExplorerIngestionCapacity = useFabric // WORKAROUND: Direct property access fails on cluster updates due to ARM bug // See: https://github.com/Azure/azure-resource-manager-templates/issues/[issue-number] -var dataExplorerUri = useFabric ? fabricQueryUri : 'https://${cluster.name}.${app.hub.location}.kusto.windows.net' +var dataExplorerUri = useFabric ? fabricQueryUri : 'https://${cluster.name}.${app.hub.location}.${dataExplorerDnsSuffix}' //============================================================================== // Resources @@ -546,7 +552,7 @@ resource dataFactoryVNet 'Microsoft.DataFactory/factories/managedVirtualNetworks #disable-next-line BCP318 // Null safety warning for conditional resource access // Null safety warning for conditional resource access // Null safety warning for conditional resource access privateLinkResourceId: cluster.id fqdns: [ - 'https://${replace(clusterName, '_', '-')}.${app.hub.location}.kusto.windows.net' + 'https://${cluster.name}.${app.hub.location}.${dataExplorerDnsSuffix}' ] } } @@ -594,19 +600,14 @@ resource linkedService_dataExplorer 'Microsoft.DataFactory/factories/linkedservi } } -// GitHub repository linked service for FTK open data +// GitHub repository linked service for FTK release files resource linkedService_ftkRepo 'Microsoft.DataFactory/factories/linkedservices@2018-06-01' = { name: 'ftkRepo' parent: dataFactory properties: { type: 'HttpServer' - parameters: { - filePath: { - type: 'string' - } - } typeProperties: { - url: '@concat(\'https://gitapp.hub.com/microsoft/finops-toolkit/\', linkedService().filePath)' + url: 'https://github.com/microsoft/finops-toolkit/' enableServerCertificateValidation: true authenticationType: 'Anonymous' }