Skip to content

feat(ec2): regional NAT Gateway#36538

Open
badmintoncryer wants to merge 46 commits intoaws:mainfrom
badmintoncryer:regional-natgw
Open

feat(ec2): regional NAT Gateway#36538
badmintoncryer wants to merge 46 commits intoaws:mainfrom
badmintoncryer:regional-natgw

Conversation

@badmintoncryer
Copy link
Copy Markdown
Contributor

@badmintoncryer badmintoncryer commented Dec 31, 2025

Issue # (if applicable)

Closes #36198

Reason for this change

AWS NAT Gateway now supports regional availability in 2025 November.

https://aws.amazon.com/about-aws/whats-new/2025/11/aws-nat-gateway-regional-availability/

https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateways-regional.html

Description of changes

  • Add NatProvider.regionalGateway() static method to create Regional NAT Gateway providers
    • Implement RegionalNatGatewayProvider class that creates a single NAT gateway covering all AZs with availabilityMode: 'regional'
    • Support configuration options:
      • maxDrainDuration: Maximum wait time before forcibly releasing IP addresses
      • allocationId / eip: Use an existing Elastic IP allocation
      • availabilityZoneAddresses: Manual control over per-AZ EIP allocation
    • Update determineNatGatewayCount() to always return 1 for Regional NAT Gateway regardless of AZ count

Describe any new or updated permissions being added

None

Description of how you validated changes

Add both unit and integ tests.

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@aws-cdk-automation aws-cdk-automation requested a review from a team December 31, 2025 17:04
@github-actions github-actions bot added the p2 label Dec 31, 2025
@badmintoncryer badmintoncryer marked this pull request as draft December 31, 2025 17:04
@github-actions github-actions bot added the distinguished-contributor [Pilot] contributed 50+ PRs to the CDK label Dec 31, 2025
Copy link
Copy Markdown
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

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

(This review is outdated)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 1, 2026

⚠️ Experimental Feature: This security report is currently in experimental phase. Results may include false positives and the rules are being actively refined.
This security report is NOT a review blocker. Please try merge from main to avoid findings unrelated to the PR.


TestsPassed ✅SkippedFailed
Security Guardian Results48 ran48 passed
TestResult
No test annotations available

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 1, 2026

⚠️ Experimental Feature: This security report is currently in experimental phase. Results may include false positives and the rules are being actively refined.
This security report is NOT a review blocker. Please try merge from main to avoid findings unrelated to the PR.


TestsPassed ✅SkippedFailed
Security Guardian Results with resolved templates48 ran48 passed
TestResult
No test annotations available

* Required for zonal NAT gateways, not used for regional NAT gateways.
*/
readonly natSubnets: PublicSubnet[];
readonly natSubnets?: PublicSubnet[];
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Because RegionalNatGateway.configureNat() doesn't use natSubnets, I made natSubnets optional.

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.

Cleaner if it doesn't break type declarations and/or requires deprecation.

export interface ConfigureRegionalNatOptions {
  readonly vpc: Vpc;
  readonly privateSubnets: PrivateSubnet[];
}

export interface ConfigureNatOptions extends ConfigureRegionalNatOptions {
  readonly natSubnets: PublicSubnet[];
}

* Maximum amount of time to wait before forcibly releasing IP addresses
* if connections are still in progress.
*
* @default Duration.seconds(350)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines +221 to +239
/**
* The allocation ID of the Elastic IP address to use for this NAT gateway.
*
* Cannot be specified together with `eip`.
* Ignored when `availabilityZoneAddresses` is specified.
*
* @default - A new EIP is automatically allocated by AWS
*/
readonly allocationId?: string;

/**
* Reference to an existing EIP to use for this NAT gateway.
*
* Cannot be specified together with `allocationId`.
* Ignored when `availabilityZoneAddresses` is specified.
*
* @default - A new EIP is automatically allocated by AWS
*/
readonly eip?: IEIPRef;
Copy link
Copy Markdown
Contributor Author

@badmintoncryer badmintoncryer Jan 1, 2026

Choose a reason for hiding this comment

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

The allocationId of the L1 construct can accept not only string but also IEIPRef. I wanted to make L2 similarly accept both of these types.

As implementation approaches, there are two options: (i) define the L2 argument as a union, or (ii) provide separate arguments for string and IEIPRef types. Since I was unsure whether union definitions are allowed in L2 arguments due to any type problem in go language, I adopted approach (ii). I will modify it to implementation (i) if necessary.

(i) union type

redaonly eip?: string | IETPRef;

(ii) separate argument

readonly allocationId?: string;
redaonly eip?: IETPRef;

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.

  1. Union type is against the guidelines.
  2. readonly eip?: CfnEIP seems the right type declaration (CfnEIP)

Copy link
Copy Markdown
Contributor Author

@badmintoncryer badmintoncryer Feb 7, 2026

Choose a reason for hiding this comment

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

Due to a recent L1 fix, CfnXxx now extends IXxxRef, and all L2 constructs also extend IXxxRef. While there is currently no L2 construct for EIP, if we use IEipRef as the argument type, it will work seamlessly even when an L2 construct is implemented in the future, without requiring any code changes. For this reason, I believe it would be preferable to use IEipRef as the argument type. What do you think?

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.

Agree. Thanks for clarifying!

- Created assets JSON for the integration test of the regional NAT gateway.
- Added CloudFormation template for the regional NAT gateway integration test.
- Generated tree structure JSON for the regional NAT gateway stack, detailing VPC, subnets, NAT gateways, and associated resources.
@aws-cdk-automation aws-cdk-automation dismissed their stale review January 1, 2026 06:51

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@lpizzinidev
Copy link
Copy Markdown
Contributor

@badmintoncryer
Sorry for the late reply.

I'm considering using type casting as a workaround

Doesn't look right. A middle ground solution could be:

  • Keep the original interface with readonly natSubnets: PublicSubnet[]; required parameter
  • Pass an empty list in createNatGateways for RegionalNatGatewayProvider
  • Add another warning in RegionalNatGatewayProvider.configureNat if for some reason natSubnets is non-empty and ignore the value. Note: I would do this even if we decide to make the parameter optional.

That would save some ?? and maintain the current interface. Thoughts?

Copy link
Copy Markdown
Contributor

@lpizzinidev lpizzinidev left a comment

Choose a reason for hiding this comment

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

Watch out for the build error:

aws-cdk-lib: /codebuild/output/src2783507564/src/actions-runner/_work/aws-cdk/aws-cdk/packages/aws-cdk-lib/aws-ec2/lib/nat.ts
aws-cdk-lib:   18:1  error  Imports "Duration" are only used as type                                  @typescript-eslint/consistent-type-imports
aws-cdk-lib:   19:1  error  All imports in the declaration are only used as types. Use `import type`  @typescript-eslint/consistent-type-imports
aws-cdk-lib: /codebuild/output/src2783507564/src/actions-runner/_work/aws-cdk/aws-cdk/packages/aws-cdk-lib/aws-ec2/lib/vpc.ts
aws-cdk-lib:   33:1  error  Imports "ConfigureNatOptions" are only used as type  @typescript-eslint/consistent-type-imports
aws-cdk-lib: ✖ 3 problems (3 errors, 0 warnings)
aws-cdk-lib:   3 errors and 0 warnings potentially fixable with the `--fix` option.

Seems like a lint issue so should be easy to fix.

@aws-cdk-automation aws-cdk-automation removed the pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. label Feb 23, 2026
@badmintoncryer
Copy link
Copy Markdown
Contributor Author

@lpizzinidev Thanks. I've resolved CI failure.

Copy link
Copy Markdown
Contributor

@lpizzinidev lpizzinidev left a comment

Choose a reason for hiding this comment

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

Ty!

@aws-cdk-automation aws-cdk-automation added the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Feb 25, 2026
@badmintoncryer
Copy link
Copy Markdown
Contributor Author

@lpizzinidev Thanks!!

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

distinguished-contributor [Pilot] contributed 50+ PRs to the CDK effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2 pr/needs-maintainer-review This PR needs a review from a Core Team Member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(ec2): Support regional NAT gateways in Vpc construct

3 participants