From c7d0d22eae254a28205ea3da2a38c3d4c70a01d5 Mon Sep 17 00:00:00 2001 From: Waleed Khaled Date: Tue, 9 Jun 2026 20:57:49 +0400 Subject: [PATCH] feat: allow azure vnet subnet name to be a parameter --- .../AzureKubernetesEnvironmentExtensions.cs | 16 ++++++- .../AzureSubnetResource.cs | 46 ++++++++++++++++--- .../AzureVirtualNetworkExtensions.cs | 34 ++++++++++++++ 3 files changed, 88 insertions(+), 8 deletions(-) diff --git a/src/Aspire.Hosting.Azure.Kubernetes/AzureKubernetesEnvironmentExtensions.cs b/src/Aspire.Hosting.Azure.Kubernetes/AzureKubernetesEnvironmentExtensions.cs index 1c95d0ab87c..a950263fbba 100644 --- a/src/Aspire.Hosting.Azure.Kubernetes/AzureKubernetesEnvironmentExtensions.cs +++ b/src/Aspire.Hosting.Azure.Kubernetes/AzureKubernetesEnvironmentExtensions.cs @@ -5,6 +5,7 @@ #pragma warning disable ASPIREAZURE001 // AzureEnvironmentResource.ProvisionInfrastructureStepName for pipeline ordering #pragma warning disable ASPIREAZURE003 // AzureSubnetResource used in WithSubnet extensions +using System.Diagnostics; using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Azure; using Aspire.Hosting.Azure.Kubernetes; @@ -763,7 +764,20 @@ private static void ConfigureAksInfrastructure(AzureResourceInfrastructure infra { existingSubnet = SubnetResource.FromExisting(subnetIdentifier); existingSubnet.Parent = existingVnet; - existingSubnet.Name = subnet.SubnetName; + + if (subnet.SubnetName is not null) + { + existingSubnet.Name = subnet.SubnetName; + } + else if (subnet.SubnetNameParameter is not null) + { + existingSubnet.Name = subnet.SubnetNameParameter.AsProvisioningParameter(infrastructure); + } + else + { + throw new UnreachableException("Subnet name must be set."); + } + infrastructure.Add(existingSubnet); subnetExistingByKey[subnetIdentifier] = existingSubnet; } diff --git a/src/Aspire.Hosting.Azure.Network/AzureSubnetResource.cs b/src/Aspire.Hosting.Azure.Network/AzureSubnetResource.cs index e72ce6143da..3822feab9d4 100644 --- a/src/Aspire.Hosting.Azure.Network/AzureSubnetResource.cs +++ b/src/Aspire.Hosting.Azure.Network/AzureSubnetResource.cs @@ -22,6 +22,7 @@ namespace Aspire.Hosting.Azure; public class AzureSubnetResource : Resource, IResourceWithParent { // Backing field holds either string or ParameterResource + private readonly object _subnetName; private readonly object _addressPrefix; /// @@ -34,7 +35,7 @@ public class AzureSubnetResource : Resource, IResourceWithParent - /// Gets the subnet name. + /// Initializes a new instance of the class with parameterized subnet name and address prefix. /// - public string SubnetName { get; } + /// The name of the resource. + /// The parameter resource containing the subnet name. + /// The parameter resource containing the address prefix for the subnet. + /// The parent Virtual Network resource. + public AzureSubnetResource(string name, ParameterResource subnetName, ParameterResource addressPrefix, AzureVirtualNetworkResource parent) + : base(name) + { + _subnetName = subnetName ?? throw new ArgumentNullException(nameof(subnetName)); + _addressPrefix = addressPrefix ?? throw new ArgumentNullException(nameof(addressPrefix)); + Parent = parent ?? throw new ArgumentNullException(nameof(parent)); + } + + /// + /// Gets the subnet name, or null if the subnet name is provided via a . + /// + public string? SubnetName => _subnetName as string; /// /// Gets the address prefix for the subnet (e.g., "10.0.1.0/24"), or null if the address prefix is provided via a . /// public string? AddressPrefix => _addressPrefix as string; + /// + /// Gets the parameter resource containing the subnet name, or null if the subnet name is provided as a literal string. + /// + public ParameterResource? SubnetNameParameter => _subnetName as ParameterResource; + /// /// Gets the parameter resource containing the address prefix for the subnet, or null if the address prefix is provided as a literal string. /// @@ -97,10 +118,21 @@ private static string ThrowIfNullOrEmpty([NotNull] string? argument, [CallerArgu /// internal SubnetResource ToProvisioningEntity(AzureResourceInfrastructure infra, ProvisionableResource? dependsOn) { - var subnet = new SubnetResource(Infrastructure.NormalizeBicepIdentifier(Name)) + var subnet = new SubnetResource(Infrastructure.NormalizeBicepIdentifier(Name)); + + // Set the subnet name from either the literal string or the parameter + if (_subnetName is string subnetName) + { + subnet.Name = subnetName; + } + else if (_subnetName is ParameterResource subnetNameParameter) { - Name = SubnetName, - }; + subnet.Name = subnetNameParameter.AsProvisioningParameter(infra); + } + else + { + throw new UnreachableException("SubnetName must be set either as a string or a ParameterResource."); + } // Set the address prefix from either the literal string or the parameter if (_addressPrefix is string addressPrefix) diff --git a/src/Aspire.Hosting.Azure.Network/AzureVirtualNetworkExtensions.cs b/src/Aspire.Hosting.Azure.Network/AzureVirtualNetworkExtensions.cs index 9d477033a11..0fb5615d2dd 100644 --- a/src/Aspire.Hosting.Azure.Network/AzureVirtualNetworkExtensions.cs +++ b/src/Aspire.Hosting.Azure.Network/AzureVirtualNetworkExtensions.cs @@ -239,6 +239,40 @@ public static IResourceBuilder AddSubnet( return AddSubnetCore(builder, subnet); } + /// + /// Adds an Azure Subnet to the Virtual Network with parameterized address prefix and subnet name. + /// + /// The Virtual Network resource builder. + /// The name of the subnet resource. + /// The parameter resource containing the address prefix for the subnet (e.g., "10.0.1.0/24"). + /// The parameter resource containing the subnet name in Azure. + /// A reference to the . + /// + /// This example adds a subnet with parameterized address prefix and subnet name: + /// + /// var subnetName = builder.AddParameter("subnetName"); + /// var subnetPrefix = builder.AddParameter("subnetPrefix"); + /// var vnet = builder.AddAzureVirtualNetwork("vnet"); + /// var subnet = vnet.AddSubnet("my-subnet", subnetPrefix, subnetName); + /// + /// + [AspireExportIgnore(Reason = "Polyglot app hosts use the internal addSubnet dispatcher export.")] + public static IResourceBuilder AddSubnet( + this IResourceBuilder builder, + [ResourceName] string name, + IResourceBuilder addressPrefix, + IResourceBuilder subnetName) + { + ArgumentNullException.ThrowIfNull(builder); + ArgumentException.ThrowIfNullOrEmpty(name); + ArgumentNullException.ThrowIfNull(addressPrefix); + ArgumentNullException.ThrowIfNull(subnetName); + + var subnet = new AzureSubnetResource(name, subnetName.Resource, addressPrefix.Resource, builder.Resource); + + return AddSubnetCore(builder, subnet); + } + /// /// Adds an Azure subnet resource to an Azure Virtual Network resource. ///