From b30551b179a11cd3b1a6cc48c998797160c08dd4 Mon Sep 17 00:00:00 2001 From: balvinder Date: Thu, 4 Dec 2025 23:08:01 +0530 Subject: [PATCH 1/3] feat: adding support for regional nat gateway --- examples/regional-nat/README.md | 87 ++++++++++++++++++++++++++++++++ examples/regional-nat/main.tf | 40 +++++++++++++++ examples/regional-nat/outputs.tf | 76 ++++++++++++++++++++++++++++ examples/regional-nat/version.tf | 10 ++++ main.tf | 58 +++++++++++++++------ outputs.tf | 4 +- variables.tf | 17 +++++++ versions.tf | 2 +- 8 files changed, 275 insertions(+), 19 deletions(-) create mode 100644 examples/regional-nat/README.md create mode 100644 examples/regional-nat/main.tf create mode 100644 examples/regional-nat/outputs.tf create mode 100644 examples/regional-nat/version.tf diff --git a/examples/regional-nat/README.md b/examples/regional-nat/README.md new file mode 100644 index 000000000..b9cb944b4 --- /dev/null +++ b/examples/regional-nat/README.md @@ -0,0 +1,87 @@ +# Regional NAT Gateway Example + +This example demonstrates how to use the **Regional NAT Gateway** feature in the Terraform AWS VPC module. Regional NAT Gateways provide a highly available NAT solution that automatically scales across multiple Availability Zones within your VPC. + +## Key Features of Regional NAT Gateway + +- **Single NAT Gateway**: One NAT Gateway serves all Availability Zones in your VPC +- **Automatic High Availability**: Automatically expands and contracts across AZs based on workload distribution +- **No Public Subnets Required**: Regional NAT Gateways operate without requiring public subnets (though we include them here for demonstration) +- **Simplified Management**: Single NAT Gateway ID for consistent route entries across all subnets +- **Increased Capacity**: Supports up to 32 Elastic IP addresses per AZ (compared to 8 for zonal NAT Gateways) + +## Architecture + +This example creates: + +- **VPC**: Single VPC with CIDR block `10.0.0.0/16` +- **Private Subnets**: 3 private subnets (one per Availability Zone) +- **Public Subnets**: 3 public subnets (one per Availability Zone) +- **Database Subnets**: 3 database subnets (one per Availability Zone) +- **Regional NAT Gateway**: Single NAT Gateway that automatically scales across all AZs +- **Internet Gateway**: For outbound internet connectivity + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example may create resources which can cost money (AWS Elastic IP, NAT Gateway, etc.). Run `terraform destroy` when you don't need these resources. + +## Configuration + +The key configuration for Regional NAT Gateway is: + +```hcl +enable_nat_gateway = true +nat_gateway_connectivity_type = "regional" +``` + +## Comparison: Regional vs Zonal NAT Gateway + +### Regional NAT Gateway (This Example) +- **Count**: 1 NAT Gateway for entire VPC +- **Route Tables**: One route table per private subnet (all route to the same NAT Gateway) +- **Subnet Requirement**: No public subnets required +- **Use Case**: Simplified management, automatic scaling, high availability across all AZs + +### Zonal NAT Gateway (Traditional) +- **Count**: 1 NAT Gateway per AZ (or per subnet) +- **Route Tables**: Route tables match NAT Gateway count +- **Subnet Requirement**: Requires public subnets +- **Use Case**: Fine-grained control, per-AZ NAT Gateways + +## Important Notes + +1. **Expansion Timing**: When deploying workloads in a new AZ, the regional NAT Gateway typically takes 15-20 minutes (up to 60 minutes) to expand to that AZ. During this period, traffic may be temporarily routed through existing AZs. + +2. **Private Connectivity**: Regional NAT Gateways do not support private connectivity. For workloads requiring private connectivity, continue using zonal NAT Gateways. + +3. **Availability**: This feature is available in all commercial AWS Regions, except for AWS GovCloud (US) Regions and China Regions. + +4. **Cost Considerations**: Regional NAT Gateways are charged per hour and per GB processed, similar to zonal NAT Gateways, but you only pay for one NAT Gateway instead of multiple. + +## Outputs + +After applying this configuration, you can see: +- Single NAT Gateway ID in `natgw_ids` output (list with one element) +- All private route tables route to the same NAT Gateway +- One Elastic IP allocated for the regional NAT Gateway + +## Requirements + +| Name | Version | +|------|---------| +| terraform | >= 1.0 | +| aws | >= 6.24.0 (required for regional NAT gateway support) | + +## References + +- [AWS Regional NAT Gateway Documentation](https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateways-regional.html) +- [AWS Blog: Introducing Amazon VPC Regional NAT Gateway](https://aws.amazon.com/blogs/networking-and-content-delivery/introducing-amazon-vpc-regional-nat-gateway/) + diff --git a/examples/regional-nat/main.tf b/examples/regional-nat/main.tf new file mode 100644 index 000000000..82752e81b --- /dev/null +++ b/examples/regional-nat/main.tf @@ -0,0 +1,40 @@ +variable "region" { + default = "ap-south-1" +} + +provider "aws" { + region = var.region +} + +data "aws_availability_zones" "available" {} + +locals { + name = "ex-${basename(path.cwd)}" + + vpc_cidr = "10.0.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + tags = { + Example = local.name + } +} + +module "vpc" { + source = "../../" + name = local.name + cidr = local.vpc_cidr + + azs = local.azs + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 4)] + database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 8)] + + enable_dns_hostnames = true + enable_dns_support = true + + # Regional NAT Gateway Configuration + # Requires Terraform AWS provider >= 6.24.0 + enable_nat_gateway = true + nat_gateway_connectivity_type = "regional" + tags = local.tags +} diff --git a/examples/regional-nat/outputs.tf b/examples/regional-nat/outputs.tf new file mode 100644 index 000000000..b80436bae --- /dev/null +++ b/examples/regional-nat/outputs.tf @@ -0,0 +1,76 @@ +################################################################################ +# VPC Outputs +################################################################################ + +output "vpc_id" { + description = "The ID of the VPC" + value = module.vpc.vpc_id +} + +output "vpc_cidr_block" { + description = "The CIDR block of the VPC" + value = module.vpc.vpc_cidr_block +} + +################################################################################ +# Subnet Outputs +################################################################################ + +output "private_subnets" { + description = "List of IDs of private subnets" + value = module.vpc.private_subnets +} + +output "private_subnets_cidr_blocks" { + description = "List of cidr_blocks of private subnets" + value = module.vpc.private_subnets_cidr_blocks +} + +output "private_route_table_ids" { + description = "List of IDs of private route tables" + value = module.vpc.private_route_table_ids +} + +output "public_subnets" { + description = "List of IDs of public subnets" + value = module.vpc.public_subnets +} + +output "database_subnets" { + description = "List of IDs of database subnets" + value = module.vpc.database_subnets +} + +################################################################################ +# NAT Gateway Outputs +################################################################################ + +output "natgw_ids" { + description = "List of NAT Gateway IDs (will contain a single regional NAT Gateway)" + value = module.vpc.natgw_ids +} + +output "nat_public_ips" { + description = "List of public Elastic IPs created for AWS NAT Gateway" + value = module.vpc.nat_public_ips +} + +output "nat_ids" { + description = "List of allocation ID of Elastic IPs created for AWS NAT Gateway" + value = module.vpc.nat_ids +} + +output "private_nat_gateway_route_ids" { + description = "List of IDs of the private nat gateway route (all route to the same regional NAT Gateway)" + value = module.vpc.private_nat_gateway_route_ids +} + +################################################################################ +# Internet Gateway Outputs +################################################################################ + +output "igw_id" { + description = "The ID of the Internet Gateway" + value = module.vpc.igw_id +} + diff --git a/examples/regional-nat/version.tf b/examples/regional-nat/version.tf new file mode 100644 index 000000000..66bc86cfb --- /dev/null +++ b/examples/regional-nat/version.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 6.24.0" + } + } +} diff --git a/main.tf b/main.tf index 31deb5988..6d06d8054 100644 --- a/main.tf +++ b/main.tf @@ -320,9 +320,13 @@ resource "aws_subnet" "private" { ) } -# There are as many routing tables as the number of NAT gateways +# There are as many routing tables as the number of NAT gateways (or private subnets for regional NAT gateway) +locals { + private_route_table_count = local.create_private_subnets && local.max_subnet_length > 0 ? (local.nat_gateway_is_regional ? local.len_private_subnets : local.nat_gateway_count) : 0 +} + resource "aws_route_table" "private" { - count = local.create_private_subnets && local.max_subnet_length > 0 ? local.nat_gateway_count : 0 + count = local.private_route_table_count region = var.region @@ -330,7 +334,10 @@ resource "aws_route_table" "private" { tags = merge( { - "Name" = var.single_nat_gateway ? "${var.name}-${var.private_subnet_suffix}" : format( + "Name" = local.nat_gateway_is_regional ? format( + "${var.name}-${var.private_subnet_suffix}-%s", + element(var.azs, count.index), + ) : var.single_nat_gateway ? "${var.name}-${var.private_subnet_suffix}" : format( "${var.name}-${var.private_subnet_suffix}-%s", element(var.azs, count.index), ) @@ -348,7 +355,7 @@ resource "aws_route_table_association" "private" { subnet_id = element(aws_subnet.private[*].id, count.index) route_table_id = element( aws_route_table.private[*].id, - var.single_nat_gateway ? 0 : count.index, + local.nat_gateway_is_regional ? count.index : (var.single_nat_gateway ? 0 : count.index), ) } @@ -515,13 +522,13 @@ resource "aws_route" "database_internet_gateway" { } resource "aws_route" "database_nat_gateway" { - count = local.create_database_route_table && !var.create_database_internet_gateway_route && var.create_database_nat_gateway_route && var.enable_nat_gateway ? var.single_nat_gateway ? 1 : local.len_database_subnets : 0 + count = local.create_database_route_table && !var.create_database_internet_gateway_route && var.create_database_nat_gateway_route && var.enable_nat_gateway ? (local.nat_gateway_is_regional ? length(aws_route_table.database[*].id) : (var.single_nat_gateway ? 1 : local.len_database_subnets)) : 0 region = var.region route_table_id = element(aws_route_table.database[*].id, count.index) destination_cidr_block = "0.0.0.0/0" - nat_gateway_id = element(aws_nat_gateway.this[*].id, count.index) + nat_gateway_id = local.nat_gateway_is_regional ? aws_nat_gateway.regional[0].id : element(aws_nat_gateway.this[*].id, count.index) timeouts { create = "5m" @@ -529,13 +536,13 @@ resource "aws_route" "database_nat_gateway" { } resource "aws_route" "database_dns64_nat_gateway" { - count = local.create_database_route_table && !var.create_database_internet_gateway_route && var.create_database_nat_gateway_route && var.enable_nat_gateway && var.enable_ipv6 && var.private_subnet_enable_dns64 ? var.single_nat_gateway ? 1 : local.len_database_subnets : 0 + count = local.create_database_route_table && !var.create_database_internet_gateway_route && var.create_database_nat_gateway_route && var.enable_nat_gateway && var.enable_ipv6 && var.private_subnet_enable_dns64 ? (local.nat_gateway_is_regional ? length(aws_route_table.database[*].id) : (var.single_nat_gateway ? 1 : local.len_database_subnets)) : 0 region = var.region route_table_id = element(aws_route_table.database[*].id, count.index) destination_ipv6_cidr_block = "64:ff9b::/96" - nat_gateway_id = element(aws_nat_gateway.this[*].id, count.index) + nat_gateway_id = local.nat_gateway_is_regional ? aws_nat_gateway.regional[0].id : element(aws_nat_gateway.this[*].id, count.index) timeouts { create = "5m" @@ -1186,7 +1193,7 @@ resource "aws_egress_only_internet_gateway" "this" { } resource "aws_route" "private_ipv6_egress" { - count = local.create_vpc && var.create_egress_only_igw && var.enable_ipv6 && local.len_private_subnets > 0 ? local.nat_gateway_count : 0 + count = local.create_vpc && var.create_egress_only_igw && var.enable_ipv6 && local.len_private_subnets > 0 ? (local.nat_gateway_is_regional ? local.private_route_table_count : local.nat_gateway_count) : 0 region = var.region @@ -1200,7 +1207,8 @@ resource "aws_route" "private_ipv6_egress" { ################################################################################ locals { - nat_gateway_count = var.single_nat_gateway ? 1 : var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length + nat_gateway_is_regional = var.nat_gateway_connectivity_type == "regional" + nat_gateway_count = local.nat_gateway_is_regional ? 1 : var.single_nat_gateway ? 1 : var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length nat_gateway_ips = var.reuse_nat_ips ? var.external_nat_ip_ids : aws_eip.nat[*].id } @@ -1213,7 +1221,7 @@ resource "aws_eip" "nat" { tags = merge( { - "Name" = format( + "Name" = local.nat_gateway_is_regional ? var.name : format( "${var.name}-%s", element(var.azs, var.single_nat_gateway ? 0 : count.index), ) @@ -1226,7 +1234,7 @@ resource "aws_eip" "nat" { } resource "aws_nat_gateway" "this" { - count = local.create_vpc && var.enable_nat_gateway ? local.nat_gateway_count : 0 + count = local.create_vpc && var.enable_nat_gateway && !local.nat_gateway_is_regional ? local.nat_gateway_count : 0 region = var.region @@ -1253,14 +1261,32 @@ resource "aws_nat_gateway" "this" { depends_on = [aws_internet_gateway.this] } +resource "aws_nat_gateway" "regional" { + count = local.create_vpc && var.enable_nat_gateway && local.nat_gateway_is_regional ? 1 : 0 + + region = var.region + vpc_id = aws_vpc.this[0].id + + connectivity_type = "public" + availability_mode = "regional" + + tags = merge( + { + "Name" = var.name + }, + var.tags, + var.nat_gateway_tags, + ) +} + resource "aws_route" "private_nat_gateway" { - count = local.create_vpc && var.enable_nat_gateway && var.create_private_nat_gateway_route ? local.nat_gateway_count : 0 + count = local.create_vpc && var.enable_nat_gateway && var.create_private_nat_gateway_route ? (local.nat_gateway_is_regional ? local.private_route_table_count : local.nat_gateway_count) : 0 region = var.region route_table_id = element(aws_route_table.private[*].id, count.index) destination_cidr_block = var.nat_gateway_destination_cidr_block - nat_gateway_id = element(aws_nat_gateway.this[*].id, count.index) + nat_gateway_id = local.nat_gateway_is_regional ? aws_nat_gateway.regional[0].id : element(aws_nat_gateway.this[*].id, count.index) timeouts { create = "5m" @@ -1268,13 +1294,13 @@ resource "aws_route" "private_nat_gateway" { } resource "aws_route" "private_dns64_nat_gateway" { - count = local.create_vpc && var.enable_nat_gateway && var.enable_ipv6 && var.private_subnet_enable_dns64 ? local.nat_gateway_count : 0 + count = local.create_vpc && var.enable_nat_gateway && var.enable_ipv6 && var.private_subnet_enable_dns64 ? (local.nat_gateway_is_regional ? local.private_route_table_count : local.nat_gateway_count) : 0 region = var.region route_table_id = element(aws_route_table.private[*].id, count.index) destination_ipv6_cidr_block = "64:ff9b::/96" - nat_gateway_id = element(aws_nat_gateway.this[*].id, count.index) + nat_gateway_id = local.nat_gateway_is_regional ? aws_nat_gateway.regional[0].id : element(aws_nat_gateway.this[*].id, count.index) timeouts { create = "5m" diff --git a/outputs.tf b/outputs.tf index 1d1d2783a..4b016f9a8 100644 --- a/outputs.tf +++ b/outputs.tf @@ -521,12 +521,12 @@ output "nat_public_ips" { output "natgw_ids" { description = "List of NAT Gateway IDs" - value = aws_nat_gateway.this[*].id + value = concat(aws_nat_gateway.this[*].id, aws_nat_gateway.regional[*].id) } output "natgw_interface_ids" { description = "List of Network Interface IDs assigned to NAT Gateways" - value = aws_nat_gateway.this[*].network_interface_id + value = concat(aws_nat_gateway.this[*].network_interface_id, aws_nat_gateway.regional[*].network_interface_id) } ################################################################################ diff --git a/variables.tf b/variables.tf index ea23a3e52..409966e0f 100644 --- a/variables.tf +++ b/variables.tf @@ -1234,6 +1234,23 @@ variable "one_nat_gateway_per_az" { default = false } +variable "nat_gateway_connectivity_type" { + description = <<-EOT + Connectivity type for the NAT Gateway. Valid values are: + - 'zonal' (default): Traditional AZ-specific NAT gateways that require public subnets + - 'regional': A single NAT Gateway that automatically scales across all AZs (does not require public subnets) + + Regional NAT Gateway support requires Terraform AWS provider >= 6.24.0. + When using 'regional' mode, only one NAT Gateway is created for the entire VPC. + EOT + type = string + default = "zonal" + validation { + condition = contains(["zonal", "regional"], var.nat_gateway_connectivity_type) + error_message = "The nat_gateway_connectivity_type must be either 'zonal' or 'regional'." + } +} + variable "reuse_nat_ips" { description = "Should be true if you don't want EIPs to be created for your NAT Gateways and will instead pass them in via the 'external_nat_ip_ids' variable" type = bool diff --git a/versions.tf b/versions.tf index aaf26b899..66bc86cfb 100644 --- a/versions.tf +++ b/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.24.0" } } } From ba1e12e14b8e850fbcade182cee52afa8f69fbec Mon Sep 17 00:00:00 2001 From: balvinder Date: Thu, 4 Dec 2025 23:17:14 +0530 Subject: [PATCH 2/3] feat: adding support for regional nat gateway --- README.md | 6 ++++-- examples/regional-nat/README.md | 1 - examples/regional-nat/main.tf | 16 ++++++++-------- examples/regional-nat/outputs.tf | 1 - main.tf | 6 +++--- variables.tf | 2 +- wrappers/main.tf | 1 + wrappers/versions.tf | 2 +- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 96e8267a0..61b58ab65 100644 --- a/README.md +++ b/README.md @@ -241,13 +241,13 @@ Full contributing [guidelines are covered here](.github/contributing.md). | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.0 | -| [aws](#requirement\_aws) | >= 6.0 | +| [aws](#requirement\_aws) | >= 6.24.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 6.0 | +| [aws](#provider\_aws) | >= 6.24.0 | ## Modules @@ -272,6 +272,7 @@ No modules. | [aws_iam_role.vpc_flow_log_cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | | [aws_iam_role_policy_attachment.vpc_flow_log_cloudwatch](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_internet_gateway.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource | +| [aws_nat_gateway.regional](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway) | resource | | [aws_nat_gateway.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway) | resource | | [aws_network_acl.database](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource | | [aws_network_acl.elasticache](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_acl) | resource | @@ -487,6 +488,7 @@ No modules. | [map\_public\_ip\_on\_launch](#input\_map\_public\_ip\_on\_launch) | Specify true to indicate that instances launched into the subnet should be assigned a public IP address. Default is `false` | `bool` | `false` | no | | [name](#input\_name) | Name to be used on all the resources as identifier | `string` | `""` | no | | [nat\_eip\_tags](#input\_nat\_eip\_tags) | Additional tags for the NAT EIP | `map(string)` | `{}` | no | +| [nat\_gateway\_connectivity\_type](#input\_nat\_gateway\_connectivity\_type) | Connectivity type for the NAT Gateway. Valid values are:
- 'zonal' (default): Traditional AZ-specific NAT gateways that require public subnets
- 'regional': A single NAT Gateway that automatically scales across all AZs (does not require public subnets)

Regional NAT Gateway support requires Terraform AWS provider >= 6.24.0.
When using 'regional' mode, only one NAT Gateway is created for the entire VPC. | `string` | `"zonal"` | no | | [nat\_gateway\_destination\_cidr\_block](#input\_nat\_gateway\_destination\_cidr\_block) | Used to pass a custom destination route for private NAT Gateway. If not specified, the default 0.0.0.0/0 is used as a destination route | `string` | `"0.0.0.0/0"` | no | | [nat\_gateway\_tags](#input\_nat\_gateway\_tags) | Additional tags for the NAT gateways | `map(string)` | `{}` | no | | [one\_nat\_gateway\_per\_az](#input\_one\_nat\_gateway\_per\_az) | Should be true if you want only one NAT Gateway per availability zone. Requires `var.azs` to be set, and the number of `public_subnets` created to be greater than or equal to the number of availability zones specified in `var.azs` | `bool` | `false` | no | diff --git a/examples/regional-nat/README.md b/examples/regional-nat/README.md index b9cb944b4..5a595a0fd 100644 --- a/examples/regional-nat/README.md +++ b/examples/regional-nat/README.md @@ -84,4 +84,3 @@ After applying this configuration, you can see: - [AWS Regional NAT Gateway Documentation](https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateways-regional.html) - [AWS Blog: Introducing Amazon VPC Regional NAT Gateway](https://aws.amazon.com/blogs/networking-and-content-delivery/introducing-amazon-vpc-regional-nat-gateway/) - diff --git a/examples/regional-nat/main.tf b/examples/regional-nat/main.tf index 82752e81b..cc5ea295f 100644 --- a/examples/regional-nat/main.tf +++ b/examples/regional-nat/main.tf @@ -9,24 +9,24 @@ provider "aws" { data "aws_availability_zones" "available" {} locals { - name = "ex-${basename(path.cwd)}" + name = "ex-${basename(path.cwd)}" vpc_cidr = "10.0.0.0/16" azs = slice(data.aws_availability_zones.available.names, 0, 3) tags = { - Example = local.name + Example = local.name } } module "vpc" { source = "../../" - name = local.name - cidr = local.vpc_cidr + name = local.name + cidr = local.vpc_cidr - azs = local.azs - private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] - public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 4)] + azs = local.azs + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)] + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 4)] database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 8)] enable_dns_hostnames = true @@ -36,5 +36,5 @@ module "vpc" { # Requires Terraform AWS provider >= 6.24.0 enable_nat_gateway = true nat_gateway_connectivity_type = "regional" - tags = local.tags + tags = local.tags } diff --git a/examples/regional-nat/outputs.tf b/examples/regional-nat/outputs.tf index b80436bae..8a478e9ef 100644 --- a/examples/regional-nat/outputs.tf +++ b/examples/regional-nat/outputs.tf @@ -73,4 +73,3 @@ output "igw_id" { description = "The ID of the Internet Gateway" value = module.vpc.igw_id } - diff --git a/main.tf b/main.tf index 6d06d8054..456df7e41 100644 --- a/main.tf +++ b/main.tf @@ -337,7 +337,7 @@ resource "aws_route_table" "private" { "Name" = local.nat_gateway_is_regional ? format( "${var.name}-${var.private_subnet_suffix}-%s", element(var.azs, count.index), - ) : var.single_nat_gateway ? "${var.name}-${var.private_subnet_suffix}" : format( + ) : var.single_nat_gateway ? "${var.name}-${var.private_subnet_suffix}" : format( "${var.name}-${var.private_subnet_suffix}-%s", element(var.azs, count.index), ) @@ -1208,8 +1208,8 @@ resource "aws_route" "private_ipv6_egress" { locals { nat_gateway_is_regional = var.nat_gateway_connectivity_type == "regional" - nat_gateway_count = local.nat_gateway_is_regional ? 1 : var.single_nat_gateway ? 1 : var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length - nat_gateway_ips = var.reuse_nat_ips ? var.external_nat_ip_ids : aws_eip.nat[*].id + nat_gateway_count = local.nat_gateway_is_regional ? 1 : var.single_nat_gateway ? 1 : var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length + nat_gateway_ips = var.reuse_nat_ips ? var.external_nat_ip_ids : aws_eip.nat[*].id } resource "aws_eip" "nat" { diff --git a/variables.tf b/variables.tf index 409966e0f..3cd6f9776 100644 --- a/variables.tf +++ b/variables.tf @@ -1239,7 +1239,7 @@ variable "nat_gateway_connectivity_type" { Connectivity type for the NAT Gateway. Valid values are: - 'zonal' (default): Traditional AZ-specific NAT gateways that require public subnets - 'regional': A single NAT Gateway that automatically scales across all AZs (does not require public subnets) - + Regional NAT Gateway support requires Terraform AWS provider >= 6.24.0. When using 'regional' mode, only one NAT Gateway is created for the entire VPC. EOT diff --git a/wrappers/main.tf b/wrappers/main.tf index bef0c73fc..5d87c013e 100644 --- a/wrappers/main.tf +++ b/wrappers/main.tf @@ -232,6 +232,7 @@ module "wrapper" { map_public_ip_on_launch = try(each.value.map_public_ip_on_launch, var.defaults.map_public_ip_on_launch, false) name = try(each.value.name, var.defaults.name, "") nat_eip_tags = try(each.value.nat_eip_tags, var.defaults.nat_eip_tags, {}) + nat_gateway_connectivity_type = try(each.value.nat_gateway_connectivity_type, var.defaults.nat_gateway_connectivity_type, "zonal") nat_gateway_destination_cidr_block = try(each.value.nat_gateway_destination_cidr_block, var.defaults.nat_gateway_destination_cidr_block, "0.0.0.0/0") nat_gateway_tags = try(each.value.nat_gateway_tags, var.defaults.nat_gateway_tags, {}) one_nat_gateway_per_az = try(each.value.one_nat_gateway_per_az, var.defaults.one_nat_gateway_per_az, false) diff --git a/wrappers/versions.tf b/wrappers/versions.tf index aaf26b899..66bc86cfb 100644 --- a/wrappers/versions.tf +++ b/wrappers/versions.tf @@ -4,7 +4,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 6.0" + version = ">= 6.24.0" } } } From 89dc190bf722ec9828fa4db8033e0b728b91d520 Mon Sep 17 00:00:00 2001 From: balvinder Date: Thu, 4 Dec 2025 23:39:18 +0530 Subject: [PATCH 3/3] fixing tflint issues --- examples/regional-nat/main.tf | 9 +++------ examples/regional-nat/variables.tf | 0 2 files changed, 3 insertions(+), 6 deletions(-) create mode 100644 examples/regional-nat/variables.tf diff --git a/examples/regional-nat/main.tf b/examples/regional-nat/main.tf index cc5ea295f..80c93547f 100644 --- a/examples/regional-nat/main.tf +++ b/examples/regional-nat/main.tf @@ -1,15 +1,12 @@ -variable "region" { - default = "ap-south-1" -} - provider "aws" { - region = var.region + region = local.region } data "aws_availability_zones" "available" {} locals { - name = "ex-${basename(path.cwd)}" + region = "ap-south-1" + name = "ex-${basename(path.cwd)}" vpc_cidr = "10.0.0.0/16" azs = slice(data.aws_availability_zones.available.names, 0, 3) diff --git a/examples/regional-nat/variables.tf b/examples/regional-nat/variables.tf new file mode 100644 index 000000000..e69de29bb