Skip to content

BYO-Vnet - #2269

Open
Jacob Struiksma (JacobStruiksma) wants to merge 5 commits into
microsoft:devfrom
JacobStruiksma:feature/byo-vnet-v15
Open

BYO-Vnet#2269
Jacob Struiksma (JacobStruiksma) wants to merge 5 commits into
microsoft:devfrom
JacobStruiksma:feature/byo-vnet-v15

Conversation

@JacobStruiksma

Copy link
Copy Markdown
Contributor

🛠️ Description

Adds bring-your-own virtual network support for FinOps hubs using private networking. The deployment can now use an existing VNet and subnets, configure subnet delegation and private endpoint networking, optionally deploy a NAT Gateway for controlled outbound access, and optionally create private DNS zones for centralized DNS scenarios.

Fixes #2268

📷 Screenshots

Not applicable. This change updates the deployment experience and infrastructure configuration.

📋 Checklist

🔬 How did you test this change?

  • 🤏 Lint tests
  • 🤞 PS -WhatIf / az validate
  • 👍 Manually deployed + verified
  • 💪 Unit tests
  • 🙌 Integration tests

📦 Deploy to test?

  • Hubs + ADX (managed)
  • Hubs + Fabric (manual) — URI:
  • Hubs (manual)
  • Hubs (no data)
  • Workbooks
  • Alerts

🙋‍♀️ Do any of the following that apply?

  • 🚨 This is a breaking change.
  • 🤏 The change is less than 20 lines of code.

📑 Did you update docs/changelog.md?

  • ✅ Updated changelog (required for dev PRs)
  • ➡️ Will add log in a future PR (feature branch PRs only)
  • ❎ Log not needed (small/internal change)

📖 Did you update documentation?

  • ✅ Public docs in docs (required for dev)
  • ✅ Public docs in docs-mslearn (required for dev)
  • ✅ Internal dev docs in docs-wiki (required for dev)
  • ✅ Internal dev docs in src (required for dev)
  • ➡️ Will add docs in a future PR (feature branch PRs only)
  • ❎ Docs not needed (small/internal change)

- Changed the date in the FinOps hub template from 08/11/2026 to 08/12/2026.
- Enhanced the parameters in the FinOps hub template to include detailed descriptions for private endpoint subnet names, NAT Gateway deployment, and private DNS zone creation.
- Updated the conditions for creating private DNS zone groups in the deployment JSON to ensure they are only created when necessary.
- Added new parameters for subnet names and NAT Gateway options in the Bicep templates, ensuring they are properly utilized in the hub deployment.
- Refactored the hub types and internal functions to accommodate the new parameters and improve clarity on private routing configurations.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds bring-your-own virtual network (BYO VNet) support for private routing in FinOps hubs, including configurable subnet names and optional private DNS zone creation for enterprise DNS setups.

Changes:

  • Introduces virtualNetworkMode (new/existing) and existingVirtualNetworkResourceId to support existing VNets.
  • Adds configurable subnet name parameters for private endpoints, scripts, and Data Explorer.
  • Adds createPrivateDnsZones and gates private DNS zone + zone-group resources accordingly.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/templates/finops-hub/modules/hub.bicep Adds new networking parameters and passes them into hub construction.
src/templates/finops-hub/modules/fx/hub-types.bicep Extends hub types/config with network mode, subnet names, DNS toggle, and resolves subnet/VNet IDs for new vs existing modes.
src/templates/finops-hub/modules/fx/hub-app.bicep Gates private DNS zone and zone-group resources behind createPrivateDnsZones.
src/templates/finops-hub/modules/Microsoft.FinOpsHubs/Core/infrastructure.bicep Creates VNet only in new mode, adjusts subnet naming, NAT, DNS dependencies, and outputs for existing mode.
src/templates/finops-hub/modules/Microsoft.FinOpsHubs/Analytics/app.bicep Gates private DNS zone resources/groups behind createPrivateDnsZones.
src/templates/finops-hub/main.bicep Exposes/passes through new networking parameters to the hub module.
src/templates/finops-hub/createUiDefinition.json Adds UI fields for subnet names/mode/DNS toggle/existing VNet ID and updates visibility rules.
docs/hubs.md Updates guidance to mention new vs existing VNet options for private networking.
docs/deploy/finops-hub-latest.json Updates generated ARM conditions to honor createPrivateDnsZones.
docs-mslearn/toolkit/hubs/template.md Documents new parameters and subnet usage under private access.
docs-mslearn/toolkit/hubs/private-networking.md Adds detailed guidance for new vs existing VNet mode and BYO subnet requirements.
docs-mslearn/toolkit/changelog.md Notes BYO VNet support, configurable subnets, and createPrivateDnsZones.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +963 to 981
"name": "virtualNetworkMode",
"type": "Microsoft.Common.DropDown",
"label": "Virtual network mode",
"toolTip": "Choose whether FinOps hubs should create a new virtual network and subnets or use an existing virtual network.",
"defaultValue": "New",
"constraints": {
"validations": [
"allowedValues": [
{
"regex": "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\/([8-9]|1[0-9]|2[0-6])$",
"message": "Address prefix must be a valid IPv4 address in the format 'XXX.XXX.XXX.XXX/YY' where YY is between 8 and 26 (minimum /26 subnet size required)."
"label": "New",
"description": "Create a new virtual network and subnets.",
"value": "new"
},
{
"label": "Existing",
"description": "Use an existing virtual network and existing subnets.",
"value": "existing"
}
]
},
// cSpell:ignore privatelink
func dnsZoneIdName(type string) IdNameObject => idName('privatelink.${type}.${environment().suffixes.storage}', 'Microsoft.Network/privateDnsZones')

func resolvedNetworkId(enablePublicAccess bool, virtualNetworkMode string, existingVirtualNetworkResourceId string, networkName string) string => enablePublicAccess ? '' : (virtualNetworkMode == 'existing' ? existingVirtualNetworkResourceId : resourceId('Microsoft.Network/virtualNetworks', networkName))
Comment on lines +251 to +252
networkId: resolvedNetworkId(enablePublicAccess, virtualNetworkMode, existingVirtualNetworkResourceId, networkName)
networkName: enablePublicAccess ? '' : last(split(resolvedNetworkId(enablePublicAccess, virtualNetworkMode, existingVirtualNetworkResourceId, networkName), '/'))
Comment on lines +268 to +272
dataExplorer: enablePublicAccess ? '' : '${resolvedNetworkId(enablePublicAccess, virtualNetworkMode, existingVirtualNetworkResourceId, networkName)}/subnets/${dataExplorerSubnetName}'
dataFactory: enablePublicAccess ? '' : '${resolvedNetworkId(enablePublicAccess, virtualNetworkMode, existingVirtualNetworkResourceId, networkName)}/subnets/${privateEndpointSubnetName}'
keyVault: enablePublicAccess ? '' : '${resolvedNetworkId(enablePublicAccess, virtualNetworkMode, existingVirtualNetworkResourceId, networkName)}/subnets/${privateEndpointSubnetName}'
scripts: enablePublicAccess ? '' : '${resolvedNetworkId(enablePublicAccess, virtualNetworkMode, existingVirtualNetworkResourceId, networkName)}/subnets/${scriptSubnetName}'
storage: enablePublicAccess ? '' : '${resolvedNetworkId(enablePublicAccess, virtualNetworkMode, existingVirtualNetworkResourceId, networkName)}/subnets/${privateEndpointSubnetName}'
@MSBrett

Copy link
Copy Markdown
Contributor

Thank you for the work on this and for validating the deployment scenario. After reviewing the scope, I don't think we should add support for deploying FinOps hubs into a customer-managed virtual network.

The ownership boundary is important for us: the FinOps Toolkit needs to exclusively create and manage the FinOps hub virtual network, its three subnets, private DNS, routing, and related resources so deployments and upgrades remain deterministic. Supporting an existing VNet would make customer-specific subnet delegation, NSGs, routes, egress, DNS, permissions, and lifecycle behavior part of the product support matrix. We do not want to take on that support contract.

For customers that require private access from an existing network, the recommended architecture is:

  1. Deploy FinOps hubs with private access so the Toolkit creates and manages its isolated hub VNet and internal private endpoints.
  2. Create customer-managed private endpoints for the hub services in the customer's own VNet, with DNS managed in that customer network.
  3. Use VNet peering only as a secondary option when customer-managed private endpoints are not suitable.

This keeps customer networking under customer ownership without allowing external resources or configuration inside the Toolkit-managed VNet.

We captured this intended ownership model and customer-private-endpoint architecture in #2230, related to #2156. That documentation PR was closed rather than merged, so the guidance still needs to be landed separately; we should correct that documentation gap rather than add BYO-VNet support here.

This is a product-scope decision rather than a request to revise the implementation. My recommendation is to close this PR and #2268 as not planned. Thank you again for the contribution and for surfacing the enterprise networking requirement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs: Review 👀 PR that is ready to be reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bring your own virtual network (byo-vnet)

5 participants