Skip to content

Add initial Aspire.Hosting.Azure.Network integration#13108

Merged
eerhardt merged 19 commits intodotnet:mainfrom
eerhardt:AzureVNetInit
Feb 5, 2026
Merged

Add initial Aspire.Hosting.Azure.Network integration#13108
eerhardt merged 19 commits intodotnet:mainfrom
eerhardt:AzureVNetInit

Conversation

@eerhardt
Copy link
Member

@eerhardt eerhardt commented Nov 22, 2025

Description

This is the first round of supporting Azure virtual networks in Aspire. Currently it supports:

  • Creating a virtual network
  • Creating subnets
  • Creating private endpoints to Storage blobs and queues

Future PRs will enable:

  1. More private endpoint support. This is just the core / first resource.
  2. Being able to add NAT Gateways and public IPs.

This pull request introduces a new Azure Virtual Network end-to-end sample to the repository, demonstrating how to configure a virtual network, subnets, private endpoints, and secure storage access for containerized applications. It also adds support for Azure Network and Private DNS provisioning packages, and makes minor improvements to existing storage modules.

New Azure Virtual Network End-to-End Sample:

  • Added the /playground/AzureVirtualNetworkEndToEnd/ folder, containing AzureVirtualNetworkEndToEnd.ApiService and AzureVirtualNetworkEndToEnd.AppHost projects to showcase VNet, subnets, private endpoints, and secure storage integration for container apps.
  • Implemented infrastructure-as-code modules for container app deployment (api-containerapp.module.bicep), managed identity (api-identity.module.bicep), and storage role assignments (api-roles-storage.module.bicep) to automate resource provisioning and access control. [1] [2] [3]
  • Added example application code and configuration files for the API service and AppHost, demonstrating usage of Azure Blob and Queue storage within a secured network environment. [1] [2] [3] [4] [5] [6] [7]

Support for Azure Network and Private DNS provisioning:

  • Included Azure.Provisioning.Network and Azure.Provisioning.PrivateDns package references in Directory.Packages.props to enable automated VNet and DNS zone management.

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

@github-actions
Copy link
Contributor

github-actions bot commented Nov 22, 2025

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 13108

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 13108"

@eerhardt eerhardt marked this pull request as ready for review February 4, 2026 00:23
Copilot AI review requested due to automatic review settings February 4, 2026 00:23
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an initial Aspire.Hosting.Azure.Network hosting integration to provision Azure Virtual Networks, Subnets, and Private Endpoints (initially for Storage blobs/queues), including Container Apps Environment subnet integration and related test/playground updates.

Changes:

  • Introduces new Azure Network hosting package with VNet/Subnet resources, subnet delegation support, and Private Endpoint + Private DNS Zone/VNet link provisioning.
  • Updates Azure Storage provisioning to emit id outputs and automatically lock down public network access when a private endpoint is configured.
  • Adds unit tests + snapshots and an end-to-end playground demonstrating VNet + private endpoints + Container Apps environment subnet usage.

Reviewed changes

Copilot reviewed 66 out of 66 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/Aspire.Hosting.Azure.Tests/Snapshots/ExistingAzureResourceTests.SupportsExistingStorageAccountWithResourceGroupAndStaticArguments.verified.bicep Snapshot update: adds id output for existing Storage account
tests/Aspire.Hosting.Azure.Tests/Snapshots/ExistingAzureResourceTests.SupportsExistingStorageAccountWithResourceGroup.verified.bicep Snapshot update: adds id output for existing Storage account
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureVirtualNetworkExtensionsTests.AddAzureVirtualNetwork_WithSubnets_GeneratesBicep.verified.bicep New snapshot for VNet + subnets provisioning
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureStoragePrivateEndpointLockdownTests.AddAzureStorage_WithPrivateEndpoint_GeneratesCorrectBicep.verified.bicep New snapshot for Storage lockdown behavior when using private endpoints
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureStorageExtensionsTests.ResourceNamesBicepValid.verified.bicep Snapshot update: adds Storage id output
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureStorageExtensionsTests.AddAzureStorageViaRunModeAllowSharedKeyAccessOverridesDefaultFalse.verified.bicep Snapshot update: adds Storage id output
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureStorageExtensionsTests.AddAzureStorageViaRunMode.verified.bicep Snapshot update: adds Storage id output
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureStorageExtensionsTests.AddAzureStorageViaPublishModeEnableAllowSharedKeyAccessOverridesDefaultFalse.verified.bicep Snapshot update: adds Storage id output
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureStorageExtensionsTests.AddAzureStorageViaPublishMode.verified.bicep Snapshot update: adds Storage id output
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzurePrivateEndpointExtensionsTests.AddPrivateEndpoint_ReusesDnsZone_ForSameZoneName.verified.bicep New snapshot for Private DNS zone + VNet link reuse
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzurePrivateEndpointExtensionsTests.AddPrivateEndpoint_ReusesDnsZone_ForSameZoneName#pe2.verified.bicep New snapshot for second private endpoint referencing existing DNS zone
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzurePrivateEndpointExtensionsTests.AddPrivateEndpoint_ReusesDnsZone_ForSameZoneName#pe1.verified.bicep New snapshot for first private endpoint referencing existing DNS zone
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzurePrivateEndpointExtensionsTests.AddPrivateEndpoint_GeneratesBicep.verified.bicep New snapshot for blob private endpoint module
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzurePrivateEndpointExtensionsTests.AddPrivateEndpoint_ForQueues_GeneratesBicep.verified.bicep New snapshot for queue private endpoint module
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureEnvironmentResourceTests.AzurePublishingContext_CapturesParametersAndOutputsCorrectly_WithSnapshot#01.verified.bicep Snapshot update: adds Storage id output in publishing context
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureContainerAppEnvironmentExtensionsTests.WithSubnet_ConfiguresVnetConfiguration.verified.bicep New snapshot: ACA environment vnetConfiguration uses subnet id output
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureContainerAppEnvironmentExtensionsTests.WithSubnet_ConfiguresVnetConfiguration#vnet.verified.bicep New snapshot: VNet + delegated subnet for ACA environment
tests/Aspire.Hosting.Azure.Tests/AzureVirtualNetworkExtensionsTests.cs New tests for VNet/subnet resource behavior and Bicep generation
tests/Aspire.Hosting.Azure.Tests/AzureStoragePrivateEndpointLockdownTests.cs New tests validating Storage lockdown + override via ConfigureInfrastructure
tests/Aspire.Hosting.Azure.Tests/AzurePrivateEndpointExtensionsTests.cs New tests for private endpoints, annotations, and DNS zone reuse
tests/Aspire.Hosting.Azure.Tests/AzureContainerAppEnvironmentExtensionsTests.cs Adds test for .WithSubnet(...) configuring ACA environment vnet integration
tests/Aspire.Hosting.Azure.Tests/Aspire.Hosting.Azure.Tests.csproj Adds test project reference to new Azure.Network package
src/Aspire.Hosting.Azure/PrivateEndpointTargetAnnotation.cs New annotation to mark resources as private-endpoint targets for lockdown
src/Aspire.Hosting.Azure/IAzurePrivateEndpointTarget.cs New interface contract for private-endpoint-capable Azure resources
src/Aspire.Hosting.Azure/IAzureDelegatedSubnetResource.cs New interface contract for resources requiring subnet service delegation
src/Aspire.Hosting.Azure/DelegatedSubnetAnnotation.cs New annotation to carry subnet reference for delegated-subnet resources
src/Aspire.Hosting.Azure.Storage/AzureStorageResource.cs Adds Id output reference property for Storage resource
src/Aspire.Hosting.Azure.Storage/AzureStorageExtensions.cs Emits Storage id output and applies lockdown defaults when PE annotation is present
src/Aspire.Hosting.Azure.Storage/AzureQueueStorageResource.cs Implements IAzurePrivateEndpointTarget for queue endpoint targeting
src/Aspire.Hosting.Azure.Storage/AzureBlobStorageResource.cs Implements IAzurePrivateEndpointTarget for blob endpoint targeting
src/Aspire.Hosting.Azure.Network/README.md New README for Azure.Network package (usage + private endpoint behavior)
src/Aspire.Hosting.Azure.Network/AzureVirtualNetworkResource.cs New VNet provisioning resource with outputs and existing-resource support
src/Aspire.Hosting.Azure.Network/AzureVirtualNetworkExtensions.cs Adds AddAzureVirtualNetwork, subnet creation, and delegated subnet wiring (WithSubnet)
src/Aspire.Hosting.Azure.Network/AzureSubnetServiceDelegationAnnotation.cs Internal annotation to define subnet delegations
src/Aspire.Hosting.Azure.Network/AzureSubnetResource.cs New subnet resource and provisioning translation + subnet id output
src/Aspire.Hosting.Azure.Network/AzurePrivateEndpointResource.cs New private endpoint provisioning resource with outputs and existing-resource support
src/Aspire.Hosting.Azure.Network/AzurePrivateEndpointExtensions.cs Adds AddPrivateEndpoint and shared Private DNS Zone/VNet link orchestration
src/Aspire.Hosting.Azure.Network/AzurePrivateDnsZoneVNetLinkResource.cs New resource type representing DNS zone ↔ VNet link relationship
src/Aspire.Hosting.Azure.Network/AzurePrivateDnsZoneResource.cs New Private DNS Zone provisioning resource with link creation and outputs
src/Aspire.Hosting.Azure.Network/Aspire.Hosting.Azure.Network.csproj New package project for Azure Network hosting integration
src/Aspire.Hosting.Azure.AppContainers/AzureContainerAppExtensions.cs Adds ACA environment VNet integration via DelegatedSubnetAnnotation
src/Aspire.Hosting.Azure.AppContainers/AzureContainerAppEnvironmentResource.cs Implements IAzureDelegatedSubnetResource (ACA delegated subnet service name)
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/vnet.module.bicep Playground: VNet + subnets module
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/storage.module.bicep Playground: Storage module with lockdown outputs (id, dataLakeEndpoint, etc.)
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/privatelink-queue-core-windows-net.module.bicep Playground: private DNS zone module (queue)
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/privatelink-blob-core-windows-net.module.bicep Playground: private DNS zone module (blob)
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/private-endpoints-queues-pe.module.bicep Playground: private endpoint module (queue)
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/private-endpoints-blobs-pe.module.bicep Playground: private endpoint module (blob)
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/env.module.bicep Playground: Container Apps environment module with subnet id parameter
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/env-acr.module.bicep Playground: ACR module used by ACA environment
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/aspire-manifest.json Playground: generated manifest wiring VNet, DNS zones, PEs, storage, and app
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/appsettings.json Playground: AppHost appsettings
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/api-roles-storage.module.bicep Playground: role assignment module referencing storage by name/id
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/api-identity.module.bicep Playground: managed identity module for API
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/api-containerapp.module.bicep Playground: container app module consuming storage endpoints
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/Properties/launchSettings.json Playground: AppHost launch profiles
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/Program.cs Playground: AppHost wiring VNet, subnets, PEs, and references
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/AzureVirtualNetworkEndToEnd.AppHost.csproj Playground: AppHost project file including new Azure.Network reference
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.ApiService/appsettings.json Playground: API service appsettings
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.ApiService/Properties/launchSettings.json Playground: API service launch profile
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.ApiService/Program.cs Playground: API service using blob container + keyed queue clients
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.ApiService/AzureVirtualNetworkEndToEnd.ApiService.csproj Playground: API service project file
playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/storage2.module.bicep Playground update: Storage module adds HNS flag, endpoints, and id output
playground/AzureStorageEndToEnd/AzureStorageEndToEnd.AppHost/storage.module.bicep Playground update: Storage module adds HNS flag, endpoints, and id output
Directory.Packages.props Adds central package versions for Azure.Provisioning.Network and Azure.Provisioning.PrivateDns
Aspire.slnx Adds new Azure.Network package + new VNet end-to-end playground projects to solution

Copy link
Member

@karolz-ms karolz-ms left a comment

Choose a reason for hiding this comment

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

Looks great overall, just a few questions

@mitchdenny
Copy link
Member

Review Feedback

1. Consider adding ParameterResource overload for AddSubnet (follow-up PR)

Currently AddSubnet only accepts a hardcoded string addressPrefix:

public static IResourceBuilder<AzureSubnetResource> AddSubnet(
    this IResourceBuilder<AzureVirtualNetworkResource> builder,
    [ResourceName] string name,
    string addressPrefix,  // <-- hardcoded string
    string? subnetName = null)

Use case: When deploying to multiple environments (test, production) that are peered to a corporate network, you may need different subnet address ranges per environment to avoid conflicts. A parameter-based overload would allow operators to configure the address prefix at deployment time:

var subnetPrefix = builder.AddParameter("subnetPrefix");
var subnet = vnet.AddSubnet("pe-subnet", subnetPrefix);

This can be addressed in a follow-up PR.


2. E2E Deployment Tests

It would be valuable to add end-to-end deployment tests that validate the VNet/private endpoint functionality works in a real Azure environment.

Challenge: Validating that resources are accessible on the private network is non-trivial since the endpoints are not publicly reachable by design.

Possible approach: Create an Azure Container Instance (ACI) within the VNet and perform a remote curl over SSH or exec into the container to validate connectivity to the private endpoints. This would confirm the private DNS zones and network configuration are working correctly.

This can also be addressed in a follow-up PR once the core functionality is merged.

…hierarchy until you reach the root resource.
- Add IAzureDelegatedSubnetResource interface and DelegatedSubnetAnnotation to Aspire.Hosting.Azure
- Implement IAzureDelegatedSubnetResource on AzureContainerAppEnvironmentResource
- Add WithSubnet<T> extension method in Network package for configuring subnet delegation
- Update ACA Bicep generation to read DelegatedSubnetAnnotation and configure VnetConfiguration
- Use serviceName for delegation name in Bicep output (e.g., 'Microsoft.App/environments')
- Mark new public APIs with [Experimental("ASPIREAZURE003")]
- Add unit test verifying ACA and VNet Bicep output with subnet delegation
- Add AzurePrivateDnsZoneResource for shared DNS Zone management
- Add AzurePrivateDnsZoneVNetLinkResource for VNet-to-zone linking
- DNS Zones are cached at builder level and reused per zone name
- VNet Links tracked on DNS Zone to avoid duplicates
- PE Bicep now references existing DNS Zone instead of creating inline
- Add tests for DNS Zone reuse scenarios
- Add InternalsVisibleTo for test access to internal types
@mitchdenny
Copy link
Member

/deployment-tests

@mitchdenny
Copy link
Member

/deployment-test

Copy link
Member

@mitchdenny mitchdenny left a comment

Choose a reason for hiding this comment

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

Looks good! Nice foundation for Azure networking support.

A few suggestions for follow-up work (already noted in comments):

  • Consider adding a ParameterResource overload for AddSubnet to allow per-environment address prefixes
  • E2E deployment tests would be valuable once there's a way to validate private network connectivity (e.g., via ACI in the VNet)
  • Future consideration: Application Gateway / Azure Front Door support for the "private backend + public ingress" pattern

@eerhardt eerhardt merged commit 5805c56 into dotnet:main Feb 5, 2026
336 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the 13.2 milestone Feb 5, 2026
eerhardt added a commit to eerhardt/aspire that referenced this pull request Feb 5, 2026
eerhardt added a commit to eerhardt/aspire that referenced this pull request Feb 6, 2026
eerhardt added a commit that referenced this pull request Feb 6, 2026
* Allow subnet addressprefix to be a parameter.

Follow-up feedback from #13108

* Add parameter to virtual network
eerhardt added a commit that referenced this pull request Feb 6, 2026
* Implement IAzurePrivateEndpointTarget on more Azure resources

Follow up to #13108

Contributes to #13750

* Fix tests

* Fix Redis private dns zone name.
@eerhardt eerhardt deleted the AzureVNetInit branch February 10, 2026 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments