Skip to content

Conversation

@eerhardt
Copy link
Member

@eerhardt eerhardt commented Feb 9, 2026

Description

Add AzureNatGatewayResource and AzurePublicIPAddressResource as standalone top-level Azure provisioning resources. A NAT Gateway provides deterministic outbound IP addresses for subnet resources.

Key design decisions:

  • NAT Gateway is a standalone resource (builder.AddNatGateway), not a VNet child
  • A Public IP Address is auto-created inline in the NAT Gateway bicep module when no explicit PIP is provided via WithPublicIPAddress()
  • AzurePublicIPAddressResource is a public reusable type for explicit PIP scenarios
  • Cross-module references use BicepOutputReference + AsProvisioningParameter
  • Advanced config (idle timeout, zones) available via ConfigureInfrastructure

New public API:

  • AzureNatGatewayResource (.Id, .NameOutput)
  • AzurePublicIPAddressResource (.Id, .NameOutput)
  • AddNatGateway() extension on IDistributedApplicationBuilder
  • AddPublicIPAddress() extension on IDistributedApplicationBuilder
  • WithPublicIPAddress() extension on IResourceBuilder
  • WithNatGateway() extension on IResourceBuilder

Contributes to #13750

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?

Add AzureNatGatewayResource and AzurePublicIPAddressResource as standalone
top-level Azure provisioning resources. A NAT Gateway provides deterministic
outbound IP addresses for subnet resources.

Key design decisions:
- NAT Gateway is a standalone resource (builder.AddNatGateway), not a VNet child
- A Public IP Address is auto-created inline in the NAT Gateway bicep module
  when no explicit PIP is provided via WithPublicIPAddress()
- AzurePublicIPAddressResource is a public reusable type for explicit PIP scenarios
- Cross-module references use BicepOutputReference + AsProvisioningParameter
- Advanced config (idle timeout, zones) available via ConfigureInfrastructure

New public API:
- AzureNatGatewayResource (.Id, .NameOutput)
- AzurePublicIPAddressResource (.Id, .NameOutput)
- AddNatGateway() extension on IDistributedApplicationBuilder
- AddPublicIPAddress() extension on IDistributedApplicationBuilder
- WithPublicIPAddress() extension on IResourceBuilder<AzureNatGatewayResource>
- WithNatGateway() extension on IResourceBuilder<AzureSubnetResource>
Copilot AI review requested due to automatic review settings February 9, 2026 18:37
@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2026

🚀 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 -- 14413

Or

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

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 Azure NAT Gateway and Public IP Address as first-class Azure provisioning resources in the Azure.Network hosting library, enabling deterministic outbound IPs for subnet resources and supporting explicit cross-module references.

Changes:

  • Introduces AzureNatGatewayResource / AzurePublicIPAddressResource and builder extensions (AddNatGateway, AddPublicIPAddress, WithPublicIPAddress, WithNatGateway).
  • Extends subnet provisioning to emit NAT gateway association via cross-module parameterized ID reference.
  • Adds unit + snapshot coverage and updates the Azure.Network README and end-to-end playground to demonstrate NAT gateway usage.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureVirtualNetworkExtensionsTests.AddSubnet_WithNatGateway_GeneratesCorrectBicep.verified.bicep Snapshot validating subnet NAT gateway ID wiring in generated bicep.
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureNatGatewayExtensionsTests.AddPublicIPAddress_GeneratesCorrectBicep.verified.bicep Snapshot validating standalone Public IP bicep generation.
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureNatGatewayExtensionsTests.AddNatGateway_WithExplicitPublicIP_GeneratesCorrectBicep.verified.bicep Snapshot validating NAT gateway referencing an explicit PIP via parameter.
tests/Aspire.Hosting.Azure.Tests/Snapshots/AzureNatGatewayExtensionsTests.AddNatGateway_GeneratesCorrectBicep.verified.bicep Snapshot validating NAT gateway auto-creates an inline PIP.
tests/Aspire.Hosting.Azure.Tests/AzureVirtualNetworkExtensionsTests.cs Adds test for subnet + NAT gateway bicep output.
tests/Aspire.Hosting.Azure.Tests/AzureNatGatewayExtensionsTests.cs New tests for NAT gateway/PIP resources and association behavior.
src/Aspire.Hosting.Azure.Network/README.md Documents NAT gateway/PIP usage and adds NAT gateway link.
src/Aspire.Hosting.Azure.Network/AzureVirtualNetworkExtensions.cs Adds WithNatGateway extension for subnets.
src/Aspire.Hosting.Azure.Network/AzureSubnetResource.cs Adds NatGateway modeling and emits NatGatewayId provisioning parameter.
src/Aspire.Hosting.Azure.Network/AzurePublicIPAddressResource.cs New provisioning resource type exposing Id/NameOutput.
src/Aspire.Hosting.Azure.Network/AzurePublicIPAddressExtensions.cs Adds AddPublicIPAddress builder extension + default infra config.
src/Aspire.Hosting.Azure.Network/AzureNatGatewayResource.cs New provisioning resource type exposing Id/NameOutput and PIP association list.
src/Aspire.Hosting.Azure.Network/AzureNatGatewayExtensions.cs Adds AddNatGateway / WithPublicIPAddress and default infra config (inline PIP when none).
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/vnet.module.bicep Updates sample vnet module to accept NAT gateway ID and apply to subnet.
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/nat.module.bicep Adds sample NAT gateway module (with inline PIP).
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/aspire-manifest.json Wires vnet module param to nat module output in sample manifest.
playground/AzureVirtualNetworkEndToEnd/AzureVirtualNetworkEndToEnd.AppHost/Program.cs Demonstrates NAT gateway creation and subnet association in the sample apphost.

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 — clean API design that follows the existing Azure.Network resource patterns (VNet, PrivateEndpoint). NAT Gateway as a standalone top-level resource with opt-in subnet association is the right call.

Minor note: the auto-created PIP in ConfigureNatGateway is missing the aspire-resource-name tag (already flagged by the bot reviewer) — not blocking but worth addressing for naming consistency.

Add Tag to auto-created Public IP Address.
@eerhardt eerhardt enabled auto-merge (squash) February 9, 2026 22:59
@eerhardt eerhardt merged commit a30335e into dotnet:main Feb 10, 2026
672 of 675 checks passed
@eerhardt eerhardt deleted the AddNATGateway branch February 10, 2026 17:57
@dotnet-policy-service dotnet-policy-service bot added this to the 13.2 milestone Feb 10, 2026
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.

3 participants