Choose the best Terraform patch (A/B/C/D) that implements the requested VPC networking change safely. Only respond with a single uppercase letter.

Task Description:
## Description
Add a new subnet type : tgwattach. The tgwattach subnet are usually small subnet range with no route table associated with unless you set the parameter  `tgwattach_associate_private_route_table` to true to benefit from the default route to NAT Gateway in case of an outbound VPC.

## Motivation and Context
Following AWS best practices for Transit Gateway attachement: https://docs.aws.amazon.com/vpc/latest/tgw/tgw-best-design-practices.html:
*Use a separate subnet for each transit gateway VPC attachment. For each subnet, use a small CIDR, for example /28, so that you have more addresses for EC2 resources*

These attachement subnets does not need ACLs neither route table, unless the VPC to be attached is an outbound VPC. In this case a route to NAT Gateway must be set. This is done by associating the `private` route table to those subnets with the parameter `tgwattach_associate_private_route_table` (set it to `true`or `false`)

(if ACL is required, it is possible to enhance the module and add ACLs for the tgwattach subnets)

## Breaking Changes
No breaking change noticed.

## How Has This Been Tested?
I tested the changes with a hub and spoke architecture, using a transit Gateway, three `application VPCs` (no internet gateway and NAT Gateway) and an outbound VPC (with IGW and NAT GW)
The new module is compatible with the Transit Gateway module. Attachement is performed thanks to the `tgwattach_subnets` IDs output.

---

Choice A:
main.tf
@@ -4,6 +4,7 @@ locals {
     length(var.elasticache_subnets),
     length(var.database_subnets),
     length(var.redshift_subnets),
+    length(var.tgwattach_subnets),
   )
   nat_gateway_count = var.single_nat_gateway ? 1 : var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length

@@ -578,6 +579,33 @@ resource "aws_subnet" "intra" {
   )
 }

+######################################################################################
+# Transit Gateway Attachement subnets - private subnet for Transit Gateway Attachement
+######################################################################################
+
+resource "aws_subnet" "tgwattach" {
+  count = var.create_vpc && length(var.tgwattach_subnets) > 0 ? length(var.tgwattach_subnets) : 0
+
+  vpc_id                          = local.vpc_id
+  cidr_block                      = var.tgwattach_subnets[count.index]
+  availability_zone               = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) > 0 ? element(var.azs, count.index) : null
+  availability_zone_id            = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) == 0 ? element(var.azs, count.index) : null
+  assign_ipv6_address_on_creation = var.tgwattach_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.tgwattach_subnet_assign_ipv6_address_on_creation
+
+  ipv6_cidr_block = var.enable_ipv6 && length(var.tgwattach_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.intra_subnet_ipv6_prefixes[count.index]) : null
+
+  tags = merge(
+    {
+      "Name" = format(
+        "${var.name}-${var.tgwattach_subnet_suffix}-%s",
+        element(var.azs, count.index),
+      )
+    },
+    var.tags,
+    var.tgwattach_subnet_tags,
+  )
+}
+
 ################################################################################
 # Default Network ACLs
 ################################################################################
@@ -594,6 +622,7 @@ resource "aws_default_network_acl" "this" {
       aws_subnet.public[*].id,
       aws_subnet.private[*].id,
       aws_subnet.intra[*].id,
+      aws_subnet.tgwattach[*].id,
       aws_subnet.database[*].id,
       aws_subnet.redshift[*].id,
       aws_subnet.elasticache[*].id,
@@ -603,6 +632,7 @@ resource "aws_default_network_acl" "this" {
       aws_network_acl.public[*].subnet_ids,
       aws_network_acl.private[*].subnet_ids,
       aws_network_acl.intra[*].subnet_ids,
+      # aws_network_acl.tgwattach[*].subnet_ids,
       aws_network_acl.database[*].subnet_ids,
       aws_network_acl.redshift[*].subnet_ids,
       aws_network_acl.elasticache[*].subnet_ids,
@@ -1148,6 +1178,16 @@ resource "aws_route_table_association" "intra" {
   route_table_id = element(aws_route_table.intra[*].id, 0)
 }

+resource "aws_route_table_association" "tgwattach" {
+  count = var.create_vpc && var.tgwattach_associate_private_route_table && length(var.tgwattach_subnets) > 0 ? length(var.tgwattach_subnets) : 0
+
+  subnet_id = element(aws_subnet.tgwattach[*].id, count.index)
+  route_table_id = element(
+    aws_route_table.private[*].id,
+    var.single_nat_gateway ? 0 : count.index,
+  )
+}
+
 resource "aws_route_table_association" "public" {
   count = var.create_vpc && length(var.public_subnets) > 0 ? length(var.public_subnets) : 0

---
outputs.tf
@@ -223,6 +223,26 @@ output "intra_subnets_ipv6_cidr_blocks" {
   value       = aws_subnet.intra[*].ipv6_cidr_block
 }

+output "tgwattach_subnets" {
+  description = "List of IDs of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].id
+}
+
+output "tgwattach_subnet_arns" {
+  description = "List of ARNs of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].arn
+}
+
+output "tgwattach_subnets_cidr_blocks" {
+  description = "List of cidr_blocks of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].cidr_block
+}
+
+output "tgwattach_subnets_ipv6_cidr_blocks" {
+  description = "List of IPv6 cidr_blocks of TGW Attachement subnets in an IPv6 enabled VPC"
+  value       = aws_subnet.tgwattach[*].ipv6_cidr_block
+}
+
 output "elasticache_subnet_group" {
   description = "ID of elasticache subnet group"
   value       = try(aws_elasticache_subnet_group.elasticache[0].id, "")
@@ -328,6 +348,11 @@ output  {
   value       = aws_route_table_association.intra[*].id
 }

+output "tgwattach_route_table_association_ids" {
+  description = "List of IDs of the TGW Attachement route table association"
+  value       = aws_route_table_association.tgwattach[*].id
+}
+
 output "public_route_table_association_ids" {
   description = "List of IDs of the public route table association"
   value       = aws_route_table_association.public[*].id
---
variables.tf
@@ -64,6 +64,12 @@ variable "intra_subnet_ipv6_prefixes" {
   default     = []
 }

+variable "tgwattach_subnet_ipv6_prefixes" {
+  description = "Assigns IPv6 TGW Attachement subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list"
+  type        = list(string)
+  default     = []
+}
+
 variable "assign_ipv6_address_on_creation" {
   description = "Assign IPv6 address on subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch"
   type        = bool
@@ -112,6 +118,12 @@ variable "intra_subnet_assign_ipv6_address_on_creation" {
   default     = null
 }

+variable "tgwattach_subnet_assign_ipv6_address_on_creation" {
+  description = "Assign IPv6 address on TGW Attachement subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch"
+  type        = bool
+  default     = null
+}
+
 variable "secondary_cidr_blocks" {
   description = "List of secondary CIDR blocks to associate with the VPC to extend the IP Address pool"
   type        = list(string)
@@ -148,6 +160,12 @@ variable "intra_subnet_suffix" {
   default     = "intra"
 }

+variable "tgwattach_subnet_suffix" {
+  description = "Suffix to append to TGW Attachement subnets name"
+  type        = string
+  default     = "tgwattach"
+}
+
 variable "database_subnet_suffix" {
   description = "Suffix to append to database subnets name"
   type        = string
@@ -208,6 +226,12 @@ variable "intra_subnets" {
   default     = []
 }

+variable "tgwattach_subnets" {
+  description = "A list of TGW Attachement subnets"
+  type        = list(string)
+  default     = []
+}
+
 variable "create_database_subnet_route_table" {
   description = "Controls if separate route table for database should be created"
   type        = bool
@@ -262,6 +286,12 @@ variable "create_database_nat_gateway_route" {
   default     = false
 }

+variable "tgwattach_associate_private_route_table" {
+  description = "Controls if the private route talbe should be attached to give internet access to the TGW Attachement subnets"
+  type        = bool
+  default     = false
+}
+
 variable "azs" {
   description = "A list of availability zones names or ids in the region"
   type        = list(string)
@@ -544,6 +574,12 @@ variable "intra_subnet_tags" {
   default     = {}
 }

+variable "tgwattach_subnet_tags" {
+  description = "Additional tags for the TGW Attachement subnets"
+  type        = map(string)
+  default     = {}
+}
+
 variable "public_acl_tags" {
   description = "Additional tags for the public subnets network ACL"
   type        = map(string)
---

---

Choice B:
main.tf
@@ -4,6 +4,7 @@ locals {
     length(var.elasticache_subnets),
     length(var.database_subnets),
     length(var.redshift_subnets),
+    length(var.tgwattach_subnets),
   )
   nat_gateway_count = var.single_nat_gateway ? 1 : var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length

@@ -578,6 +579,33 @@ resource "aws_subnet" "intra" {
   )
 }

+######################################################################################
+# Transit Gateway Attachement subnets - private subnet for Transit Gateway Attachement
+######################################################################################
+
+resource "aws_subnet" "tgwattach" {
+  count = var.create_vpc && length(var.tgwattach_subnets) > 0 ? length(var.tgwattach_subnets) : 0
+
+  vpc_id                          = local.vpc_id
+  cidr_block                      = var.tgwattach_subnets[count.index]
+  availability_zone               = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) > 0 ? element(var.azs, count.index) : null
+  availability_zone_id            = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) == 0 ? element(var.azs, count.index) : null
+  assign_ipv6_address_on_creation = var.tgwattach_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.tgwattach_subnet_assign_ipv6_address_on_creation
+
+  ipv6_cidr_block = var.enable_ipv6 && length(var.tgwattach_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.intra_subnet_ipv6_prefixes[count.index]) : null
+
+  tags = merge(
+    {
+      "Name" = format(
+        "${var.name}-${var.tgwattach_subnet_suffix}-%s",
+        element(var.azs, count.index),
+      )
+    },
+    var.tags,
+    var.tgwattach_subnet_tags,
+  )
+}
+
 ################################################################################
 # Default Network ACLs
 ################################################################################
@@ -594,6 +622,7 @@ resource "aws_default_network_acl" "this" {
       aws_subnet.public[*].id,
       aws_subnet.private[*].id,
       aws_subnet.intra[*].id,
+      aws_subnet.tgwattach[*].id,
       aws_subnet.database[*].id,
       aws_subnet.redshift[*].id,
       aws_subnet.elasticache[*].id,
@@ -603,6 +632,7 @@ resource "aws_default_network_acl" "this" {
       aws_network_acl.public[*].subnet_ids,
       aws_network_acl.private[*].subnet_ids,
       aws_network_acl.intra[*].subnet_ids,
+      # aws_network_acl.tgwattach[*].subnet_ids,
       aws_network_acl.database[*].subnet_ids,
       aws_network_acl.redshift[*].subnet_ids,
       aws_network_acl.elasticache[*].subnet_ids,
@@ -1148,6 +1178,16 @@ resource "aws_route_table_association" "intra" {
   route_table_id = element(aws_route_table.intra[*].id, 0)
 }

+resource "aws_route_table_association" "tgwattach" {
+  count = var.create_vpc && var.tgwattach_associate_private_route_table && length(var.tgwattach_subnets) > 0 ? length(var.tgwattach_subnets) : 0
+
+  subnet_id = element(aws_subnet.tgwattach[*].id, count.index)
+  route_table_id = element(
+    aws_route_table.private[*].id,
+    var.single_nat_gateway ? 0 : count.index,
+  )
+}
+
 resource "aws_route_table_association" "public" {
   count = var.create_vpc && length(var.public_subnets) > 0 ? length(var.public_subnets) : 0

---
outputs.tf
@@ -223,6 +223,26 @@ output "intra_subnets_ipv6_cidr_blocks" {
   value       = aws_subnet.intra[*].ipv6_cidr_block
 }

+output "tgwattach_subnets" {
+  description = "List of IDs of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].id
+}
+
+output "tgwattach_subnet_arns" {
+  description = "List of ARNs of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].arn
+}
+
+output "tgwattach_subnets_cidr_blocks" {
+  description = "List of cidr_blocks of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].cidr_block
+}
+
+output "tgwattach_subnets_ipv6_cidr_blocks" {
+  description = "List of IPv6 cidr_blocks of TGW Attachement subnets in an IPv6 enabled VPC"
+  value       = aws_subnet.tgwattach[*].ipv6_cidr_block
+}
+
 output "elasticache_subnet_group" {
   description = "ID of elasticache subnet group"
   value       = try(aws_elasticache_subnet_group.elasticache[0].id, "")
@@ -328,6 +348,11 @@ output "intra_route_table_association_ids" {
   value       = aws_route_table_association.intra[*].id
 }

+output "tgwattach_route_table_association_ids" {
+  description = "List of IDs of the TGW Attachement route table association"
+  value       = aws_route_table_association.tgwattach[*].id
+}
+
 output "public_route_table_association_ids" {
   description = "List of IDs of the public route table association"
   value       = aws_route_table_association.public[*].id
---
variables.tf
@@ -64,6 +64,12 @@ variable "intra_subnet_ipv6_prefixes" {
   default     = []
 }

+variable "tgwattach_subnet_ipv6_prefixes" {
+  description = "Assigns IPv6 TGW Attachement subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list"
+  type        = list(string)
+  default     = []
+}
+
 variable "assign_ipv6_address_on_creation" {
   description = "Assign IPv6 address on subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch"
   type        = bool
@@ -112,6 +118,12 @@ variable "intra_subnet_assign_ipv6_address_on_creation" {
   default     = null
 }

+variable "tgwattach_subnet_assign_ipv6_address_on_creation" {
+  description = "Assign IPv6 address on TGW Attachement subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch"
+  type        = bool
+  default     = null
+}
+
 variable "secondary_cidr_blocks" {
   description = "List of secondary CIDR blocks to associate with the VPC to extend the IP Address pool"
   type        = list(string)
@@ -148,6 +160,12 @@ variable "intra_subnet_suffix" {
   default     = "intra"
 }

+variable "tgwattach_subnet_suffix" {
+  description = "Suffix to append to TGW Attachement subnets name"
+  type        = string
+  default     = "tgwattach"
+}
+
 variable "database_subnet_suffix" {
   description = "Suffix to append to database subnets name"
   type        = string
@@ -208,6 +226,12 @@ variable "intra_subnets" {
   default     = []
 }

+variable "tgwattach_subnets" {
+  description = "A list of TGW Attachement subnets"
+  type        = list(string)
+  default     = []
+}
+
 variable "create_database_subnet_route_table" {
   description = "Controls if separate route table for database should be created"
   type        = bool
@@ -262,6 +286,12 @@ variable "create_database_nat_gateway_route" {
   default     = false
 }

+variable "tgwattach_associate_private_route_table" {
+  description = "Controls if the private route talbe should be attached to give internet access to the TGW Attachement subnets"
+  type        = bool
+  default     = false
+}
+
 variable "azs" {
   description = "A list of availability zones names or ids in the region"
   type        = list(string)
@@ -544,6 +574,12 @@ variable "intra_subnet_tags" {
   default     = {}
 }

+variable "tgwattach_subnet_tags" {
+  description = "Additional tags for the TGW Attachement subnets"
+  type        = map(string)
+  default     = {}
+}
+
 variable "public_acl_tags" {
   description = "Additional tags for the public subnets network ACL"
   type        = map(string)
---

---

Choice C:
main.tf
@@ -4,6 +4,7 @@ locals {
     length(var.elasticache_subnets),
     length(var.database_subnets),
     length(var.redshift_subnets),
+    length(var.tgwattach_subnets),
   )
   nat_gateway_count = var.single_nat_gateway ? 1 : var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length

@@ -578,6 +579,33 @@ resource "aws_subnet" "intra" {
   )
 }

+######################################################################################
+# Transit Gateway Attachement subnets - private subnet for Transit Gateway Attachement
+######################################################################################
+
+resource "aws_subnet" "tgwattach" {
+  count = var.create_vpc && length(var.tgwattach_subnets) > 0 ? length(var.tgwattach_subnets) : 0
+
+  vpc_id                          = local.vpc_id
+  cidr_block                      = var.tgwattach_subnets[count.index]
+  availability_zone               = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) > 0 ? element(var.azs, count.index) : null
+  availability_zone_id            = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) == 0 ? element(var.azs, count.index) : null
+  assign_ipv6_address_on_creation = var.tgwattach_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.tgwattach_subnet_assign_ipv6_address_on_creation
+
+  ipv6_cidr_block = var.enable_ipv6 && length(var.tgwattach_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.intra_subnet_ipv6_prefixes[count.index]) : null
+
+  tags = merge(
+    {
+      "Name" = format(
+        "${var.name}-${var.tgwattach_subnet_suffix}-%s",
+        element(var.azs, count.index),
+      )
+    },
+    var.tags,
+    var.tgwattach_subnet_tags,
+  )
+}
+
 ################################################################################
 # Default Network ACLs
 ################################################################################
@@ -594,6 +622,7 @@ resource "aws_default_network_acl" "this" {
       aws_subnet.public[*].id,
       aws_subnet.private[*].id,
       aws_subnet.intra[*].id,
+      aws_subnet.tgwattach[*].id,
       aws_subnet.database[*].id,
       aws_subnet.redshift[*].id,
       aws_subnet.elasticache[*].id,
@@ -603,6 +632,7 @@ resource "aws_default_network_acl" "this" {
       aws_network_acl.public[*].subnet_ids,
       aws_network_acl.private[*].subnet_ids,
       aws_network_acl.intra[*].subnet_ids,
+      # aws_network_acl.tgwattach[*].subnet_ids,
       aws_network_acl.database[*].subnet_ids,
       aws_network_acl.redshift[*].subnet_ids,
       aws_network_acl.elasticache[*].subnet_ids,
@@ -1148,6 +1178,16 @@ resource "aws_route_table_association" "intra" {
   route_table_id = element(aws_route_table.intra[*].id, 0)
 }

+resource "aws_route_table_association" "tgwattach" {
+  count = var.create_vpc && var.tgwattach_associate_private_route_table && length(var.tgwattach_subnets) > 0 ? length(var.tgwattach_subnets) : 0
+
+  subnet_id = element(aws_subnet.tgwattach[*].id, count.index)
+  route_table_id = element(
+    aws_route_table.private[*].id,
+    var.single_nat_gateway ? 0 : count.index,
+  )
+}
+
 resource "aws_route_table_association" "public" {
   count = ACL"
 && length(var.public_subnets) > 0 ? length(var.public_subnets) : 0

---
outputs.tf
@@ -223,6 +223,26 @@ output "intra_subnets_ipv6_cidr_blocks" {
   value       = aws_subnet.intra[*].ipv6_cidr_block
 }

+output "tgwattach_subnets" {
+  description = "List of IDs of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].id
+}
+
+output "tgwattach_subnet_arns" {
+  description = "List of ARNs of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].arn
+}
+
+output "tgwattach_subnets_cidr_blocks" {
+  description = "List of cidr_blocks of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].cidr_block
+}
+
+output "tgwattach_subnets_ipv6_cidr_blocks" {
+  description = "List of IPv6 cidr_blocks of TGW Attachement subnets in an IPv6 enabled VPC"
+  value       = aws_subnet.tgwattach[*].ipv6_cidr_block
+}
+
 output "elasticache_subnet_group" {
   description = "ID of elasticache subnet group"
   value       = try(aws_elasticache_subnet_group.elasticache[0].id, "")
@@ -328,6 +348,11 @@ output "intra_route_table_association_ids" {
   value       = aws_route_table_association.intra[*].id
 }

+output "tgwattach_route_table_association_ids" {
+  description = "List of IDs of the TGW Attachement route table association"
+  value       = aws_route_table_association.tgwattach[*].id
+}
+
 output "public_route_table_association_ids" {
   description = "List of IDs of the public route table association"
   value       = aws_route_table_association.public[*].id
---
variables.tf
@@ -64,6 +64,12 @@ variable "intra_subnet_ipv6_prefixes" {
   default     = []
 }

+variable "tgwattach_subnet_ipv6_prefixes" {
+  description = "Assigns IPv6 TGW Attachement subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list"
+  type        = list(string)
+  default     = []
+}
+
 variable "assign_ipv6_address_on_creation" {
   description = "Assign IPv6 address on subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch"
   type        = bool
@@ -112,6 +118,12 @@ variable "intra_subnet_assign_ipv6_address_on_creation" {
   default     = null
 }

+variable "tgwattach_subnet_assign_ipv6_address_on_creation" {
+  description = "Assign IPv6 address on TGW Attachement subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch"
+  type        = bool
+  default     = null
+}
+
 variable "secondary_cidr_blocks" {
   description = "List of secondary CIDR blocks to associate with the VPC to extend the IP Address pool"
   type        = list(string)
@@ -148,6 +160,12 @@ variable "intra_subnet_suffix" {
   default     = "intra"
 }

+variable "tgwattach_subnet_suffix" {
+  description = "Suffix to append to TGW Attachement subnets name"
+  type        = string
+  default     = "tgwattach"
+}
+
 variable "database_subnet_suffix" {
   description = "Suffix to append to database subnets name"
   type        = string
@@ -208,6 +226,12 @@ variable "intra_subnets" {
   default     = []
 }

+variable "tgwattach_subnets" {
+  description = "A list of TGW Attachement subnets"
+  type        = list(string)
+  default     = []
+}
+
 variable "create_database_subnet_route_table" {
   description = "Controls if separate route table for database should be created"
   type        = bool
@@ -262,6 +286,12 @@ variable "create_database_nat_gateway_route" {
   default     = false
 }

+variable "tgwattach_associate_private_route_table" {
+  description = "Controls if the private route talbe should be attached to give internet access to the TGW Attachement subnets"
+  type        = bool
+  default     = false
+}
+
 variable "azs" {
   description = "A list of availability zones names or ids in the region"
   type        = list(string)
@@ -544,6 +574,12 @@ variable "intra_subnet_tags" {
   default     = {}
 }

+variable "tgwattach_subnet_tags" {
+  description = "Additional tags for the TGW Attachement subnets"
+  type        = map(string)
+  default     = {}
+}
+
 variable "public_acl_tags" {
   description = "Additional tags for the public subnets network ACL"
   type        = map(string)
---

---

Choice D:
main.tf
@@ -4,6 +4,7 @@ locals {
     length(var.elasticache_subnets),
     length(var.database_subnets),
     length(var.redshift_subnets),
+    length(var.tgwattach_subnets),
   )
   nat_gateway_count = var.single_nat_gateway ? 1 : var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length

@@ -578,6 +579,33 @@ resource "aws_subnet" "intra" {
   )
 }

+######################################################################################
+# Transit Gateway Attachement subnets - private subnet for Transit Gateway Attachement
+######################################################################################
+
+resource "aws_subnet" "tgwattach" {
+  count = var.create_vpc && length(var.tgwattach_subnets) > 0 ? length(var.tgwattach_subnets) : 0
+
+  vpc_id                          = local.vpc_id
+  cidr_block                      = var.tgwattach_subnets[count.index]
+  availability_zone               = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) > 0 ? element(var.azs, count.index) : null
+  availability_zone_id            = length(regexall("^[a-z]{2}-", element(var.azs, count.index))) == 0 ? element(var.azs, count.index,
+ : null
+  assign_ipv6_address_on_creation = var.tgwattach_subnet_assign_ipv6_address_on_creation == null ? var.assign_ipv6_address_on_creation : var.tgwattach_subnet_assign_ipv6_address_on_creation
+
+  ipv6_cidr_block = var.enable_ipv6 && length(var.tgwattach_subnet_ipv6_prefixes) > 0 ? cidrsubnet(aws_vpc.this[0].ipv6_cidr_block, 8, var.intra_subnet_ipv6_prefixes[count.index]) : null
+
+  tags = merge(
+    {
+      "Name" = format(
+        "${var.name}-${var.tgwattach_subnet_suffix}-%s",
+        element(var.azs, count.index),
+      )
+    },
+    var.tags,
+    var.tgwattach_subnet_tags,
+  )
+}
+
 ################################################################################
 # Default Network ACLs
 ################################################################################
@@ -594,6 +622,7 @@ resource "aws_default_network_acl" "this" {
       aws_subnet.public[*].id,
       aws_subnet.private[*].id,
       aws_subnet.intra[*].id,
+      aws_subnet.tgwattach[*].id,
       aws_subnet.database[*].id,
       aws_subnet.redshift[*].id,
       aws_subnet.elasticache[*].id,
@@ -603,6 +632,7 @@ resource "aws_default_network_acl" "this" {
       aws_network_acl.public[*].subnet_ids,
       aws_network_acl.private[*].subnet_ids,
       aws_network_acl.intra[*].subnet_ids,
+      # aws_network_acl.tgwattach[*].subnet_ids,
       aws_network_acl.database[*].subnet_ids,
       aws_network_acl.redshift[*].subnet_ids,
       aws_network_acl.elasticache[*].subnet_ids,
@@ -1148,6 +1178,16 @@ resource "aws_route_table_association" "intra" {
   route_table_id = element(aws_route_table.intra[*].id, 0)
 }

+resource "aws_route_table_association" "tgwattach" {
+  count = var.create_vpc && var.tgwattach_associate_private_route_table && length(var.tgwattach_subnets) > 0 ? length(var.tgwattach_subnets) : 0
+
+  subnet_id = element(aws_subnet.tgwattach[*].id, count.index)
+  route_table_id = element(
+    aws_route_table.private[*].id,
+    var.single_nat_gateway ? 0 : count.index,
+  )
+}
+
 resource "aws_route_table_association" "public" {
   count = var.create_vpc && length(var.public_subnets) > 0 ? length(var.public_subnets) : 0

---
outputs.tf
@@ -223,6 +223,26 @@ output "intra_subnets_ipv6_cidr_blocks" {
   value       = aws_subnet.intra[*].ipv6_cidr_block
 }

+output "tgwattach_subnets" {
+  description = "List of IDs of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].id
+}
+
+output "tgwattach_subnet_arns" {
+  description = "List of ARNs of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].arn
+}
+
+output "tgwattach_subnets_cidr_blocks" {
+  description = "List of cidr_blocks of TGW Attachement subnets"
+  value       = aws_subnet.tgwattach[*].cidr_block
+}
+
+output "tgwattach_subnets_ipv6_cidr_blocks" {
+  description = "List of IPv6 cidr_blocks of TGW Attachement subnets in an IPv6 enabled VPC"
+  value       = aws_subnet.tgwattach[*].ipv6_cidr_block
+}
+
 output "elasticache_subnet_group" {
   description = "ID of elasticache subnet group"
   value       = try(aws_elasticache_subnet_group.elasticache[0].id, "")
@@ -328,6 +348,11 @@ output "intra_route_table_association_ids" {
   value       = aws_route_table_association.intra[*].id
 }

+output "tgwattach_route_table_association_ids" {
+  description = "List of IDs of the TGW Attachement route table association"
+  value       = aws_route_table_association.tgwattach[*].id
+}
+
 output "public_route_table_association_ids" {
   description = "List of IDs of the public route table association"
   value       = aws_route_table_association.public[*].id
---
variables.tf
@@ -64,6 +64,12 @@ variable "intra_subnet_ipv6_prefixes" {
   default     = []
 }

+variable "tgwattach_subnet_ipv6_prefixes" {
+  description = "Assigns IPv6 TGW Attachement subnet id based on the Amazon provided /56 prefix base 10 integer (0-256). Must be of equal length to the corresponding IPv4 subnet list"
+  type        = list(string)
+  default     = []
+}
+
 variable "assign_ipv6_address_on_creation" {
   description = "Assign IPv6 address on subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch"
   type        = bool
@@ -112,6 +118,12 @@ variable "intra_subnet_assign_ipv6_address_on_creation" {
   default     = null
 }

+variable "tgwattach_subnet_assign_ipv6_address_on_creation" {
+  description = "Assign IPv6 address on TGW Attachement subnet, must be disabled to change IPv6 CIDRs. This is the IPv6 equivalent of map_public_ip_on_launch"
+  type        = bool
+  default     = null
+}
+
 variable "secondary_cidr_blocks" {
   description = "List of secondary CIDR blocks to associate with the VPC to extend the IP Address pool"
   type        = list(string)
@@ -148,6 +160,12 @@ variable "intra_subnet_suffix" {
   default     = "intra"
 }

+variable "tgwattach_subnet_suffix" {
+  description = "Suffix to append to TGW Attachement subnets name"
+  type        = string
+  default     = "tgwattach"
+}
+
 variable "database_subnet_suffix" {
   description = "Suffix to append to database subnets name"
   type        = string
@@ -208,6 +226,12 @@ variable "intra_subnets" {
   default     = []
 }

+variable "tgwattach_subnets" {
+  description = "A list of TGW Attachement subnets"
+  type        = list(string)
+  default     = []
+}
+
 variable "create_database_subnet_route_table" {
   description = "Controls if separate route table for database should be created"
   type        = bool
@@ -262,6 +286,12 @@ variable "create_database_nat_gateway_route" {
   default     = false
 }

+variable "tgwattach_associate_private_route_table" {
+  description = "Controls if the private route talbe should be attached to give internet access to the TGW Attachement subnets"
+  type        = bool
+  default     = false
+}
+
 variable "azs" {
   description = "A list of availability zones names or ids in the region"
   type        = list(string)
@@ -544,6 +574,12 @@ variable "intra_subnet_tags" {
   default     = {}
 }

+variable "tgwattach_subnet_tags" {
+  description = "Additional tags for the TGW Attachement subnets"
+  type        = map(string)
+  default     = {}
+}
+
 variable "public_acl_tags" {
   description = "Additional tags for the public subnets network ACL"
   type        = map(string)
---

---


Choose the best Terraform patch (A/B/C/D) that implements the requested VPC networking change safely. Only respond with a single uppercase letter.

Task Description:
fix for dynamodb resource not found error in the example.

---

Choice A:
examples/complete-vpc/main.tf
@@ -208,7 +208,7 @@ data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
       test     = "StringNotEquals"
       variable = "aws:sourceVpce"

-      values = [data.aws_vpc_endpoint.dynamodb.id]
+      values = [data.vpc.vpc_id]
     }
   }
 }
---

---

Choice B:
examples/complete-vpc/main.tf
@@ -208,7 +208,7 @@ data "aws_iam_policy_document"  {
       test     = "StringNotEquals"
       variable = "aws:sourceVpce"

-      values = [data.aws_vpc_endpoint.dynamodb.id]
+      values = [data.vpc.vpc_id]
     }
   }
 }
---

---

Choice C:
examples/complete-vpc/main.tf
@@ -208,7 +208,7 @@ data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
       test     = "StringNotEquals"
       variable = "aws:sourceVpce"

-      values = [data.aws_vpc_endpoint.dynamodb.id]
+      values =      }
   }
 }
---

---

Choice D:
examples/complete-vpc/main.tf
@@ -208,7 +208,7 @@ data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
       test     = "StringNotEquals"
 -208,7      variable = "aws:sourceVpce"

-      values = [data.aws_vpc_endpoint.dynamodb.id]
+      values = [data.vpc.vpc_id]
     }
   }
 }
---

---


Choose the best Terraform patch (A/B/C/D) that implements the requested VPC networking change safely. Only respond with a single uppercase letter.

Task Description:
Tested, described reasoning in the following issue:
https://github.com/terraform-aws-modules/terraform-aws-vpc/issues/740

---

Choice A:
main.tf
@@ -1074,6 +1074,27 @@ resource "aws_route" "private_ipv6_egress" {
   egress_only_gateway_id      = element(aws_egress_only_internet_gateway.this[*].id, 0)
 }

+resource "aws_route" "private_route_table_routes" {
+  count = length(var.private_subnets) * length(var.private_route_table_routes)
+
+  route_table_id         = element(aws_route_table.private[*].id, floor(count.index / length(var.private_route_table_routes)))
+  destination_cidr_block = element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))).cidr_block
+
+  # One of the following targets must be provided
+  egress_only_gateway_id    = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "egress_only_gateway_id", null)
+  gateway_id                = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "gateway_id", null)
+  instance_id               = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "instance_id", null)
+  nat_gateway_id            = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "nat_gateway_id", null)
+  network_interface_id      = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "network_interface_id", null)
+  transit_gateway_id        = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "transit_gateway_id", null)
+  vpc_endpoint_id           = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "vpc_endpoint_id", null)
+  vpc_peering_connection_id = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "vpc_peering_connection_id", null)
+
+  timeouts {
+    create = "5m"
+  }
+}
+
 ################################################################################
 # Route table association
 ################################################################################
---
variables.tf
@@ -406,6 +406,12 @@ variable "default_route_table_routes" {
   default     = []
 }

+variable "private_route_table_routes" {
+  description = "Configuration block of private routes."
+  type        = list(map(string))
+  default     = []
+}
+
 variable "default_route_table_tags" {
    = "Additional tags for the default route table"
   type        = map(string)
---

---

Choice B:
main.tf
@@ -1074,6 +1074,27 @@ resource "aws_route" "private_ipv6_egress" {
   egress_only_gateway_id      = element(aws_egress_only_internet_gateway.this[*].id, 0)
 }

+resource "aws_route" "private_route_table_routes" {
+  count = length(var.private_subnets) * length(var.private_route_table_routes)
+
+  route_table_id         = element(aws_route_table.private[*].id, floor(count.index / length(var.private_route_table_routes)))
+  destination_cidr_block = element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))).cidr_block
+
+  # One of the following targets must be provided
+  egress_only_gateway_id    = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "egress_only_gateway_id", null)
+  gateway_id                = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "gateway_id", null)
+  instance_id               = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "instance_id", null)
+  nat_gateway_id            = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "nat_gateway_id", null)
+  network_interface_id      = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "network_interface_id", null)
+  transit_gateway_id        = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "transit_gateway_id", null)
+  vpc_endpoint_id           = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "vpc_endpoint_id", null)
+  vpc_peering_connection_id = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "vpc_peering_connection_id", null)
+
+  timeouts {
+    create = "5m"
+  }
+}
+
 ################################################################################
 # Route table association
 ################################################################################
---
variables.tf
@@ -406,6 +406,12 @@ variable "default_route_table_routes" {
   default     = []
 }

+variable "private_route_table_routes" {
+  description = "Configuration block of private routes."
+  type        = list(map(string))
+  default     = []
+}
+
 variable "default_route_table_tags" {
   description = "Additional  for the default route table"
   type        = map(string)
---

---

Choice C:
main.tf
@@ -1074,6 +1074,27 @@ resource "aws_route" "private_ipv6_egress" {
   egress_only_gateway_id      = element(aws_egress_only_internet_gateway.this[*].id, 0)
 }

+resource "aws_route" "private_route_table_routes" {
+  count = length(var.private_subnets) * length(var.private_route_table_routes)
+
+  route_table_id         = element(aws_route_table.private[*].id, floor(count.index / length(var.private_route_table_routes)))
+  destination_cidr_block = element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))).cidr_block
+
+  # One of the following targets must be provided
+  egress_only_gateway_id    = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "egress_only_gateway_id", null)
+  gateway_id                = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "gateway_id", null)
+  instance_id               = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "instance_id", null)
+  nat_gateway_id            = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "nat_gateway_id", null)
+  network_interface_id      = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "network_interface_id", null)
+  transit_gateway_id        = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "transit_gateway_id", null)
+  vpc_endpoint_id           = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "vpc_endpoint_id", null)
+  vpc_peering_connection_id = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "vpc_peering_connection_id", null)
+
+  timeouts {
+    create = "5m"
+  }
+}
+
 ################################################################################
 # Route table association
 ################################################################################
---
variables.tf
@@ -406,6 +406,12 @@ variable "default_route_table_routes" {
   default     = []
 }

+variable "private_route_table_routes" {
+  description = "Configuration block of private routes."
+  type        = list(map(string))
+  default     = []
+}
+
 variable "default_route_table_tags" {
   description = "Additional tags for the default route table"
   type        = map(string)
---

---

Choice D:
main.tf
@@ -1074,6 +1074,27 @@ resource "aws_route" "private_ipv6_egress" {
   egress_only_gateway_id      = element(aws_egress_only_internet_gateway.this[*].id, 0)
 }

+resource "aws_route" "private_route_table_routes" {
+  count = length(var.private_subnets) * length(var.private_route_table_routes)
+
+  route_table_id         = element(aws_route_table.private[*].id, floor(count.index / length(var.private_route_table_routes)))
+  destination_cidr_block = element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))).cidr_block
+
+  # One of the following targets must be provided
+  egress_only_gateway_id    = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "egress_only_gateway_id", null)
+  gateway_id                = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "gateway_id", null)
+  instance_id               = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "instance_id", null)
+  nat_gateway_id            = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "nat_gateway_id", null)
+  network_interface_id      = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "network_interface_id", null)
+  transit_gateway_id         lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "transit_gateway_id", null)
+  vpc_endpoint_id           = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "vpc_endpoint_id", null)
+  vpc_peering_connection_id = lookup(element(var.private_route_table_routes, floor(count.index / length(var.private_subnets))), "vpc_peering_connection_id", null)
+
+  timeouts {
+    create = "5m"
+  }
+}
+
 ################################################################################
 # Route table association
 ################################################################################
---
variables.tf
@@ -406,6 +406,12 @@ variable "default_route_table_routes" {
   default     = []
 }

+variable "private_route_table_routes" {
+  description = "Configuration block of private routes."
+  type        = list(map(string))
+  default     = []
+}
+
 variable "default_route_table_tags" {
   description = "Additional tags for the default route table"
   type        = map(string)
---

---


Choose the best Terraform patch (A/B/C/D) that implements the requested VPC networking change safely. Only respond with a single uppercase letter.

Task Description:
Fixed #738

---

Choice A:
outputs.tf
@@ -250,7 +250,7 @@ output "database_route_table_ids" {

 output "redshift_route_table_ids" {
   description = "List of IDs of  route tables"
-  value       = try(coalescelist(aws_route_table.redshift[*].id, aws_route_table.public[*].id, aws_route_table.private[*].id), [])
+  value       = length(aws_route_table.redshift[*].id) > 0 ? aws_route_table.redshift[*].id : (var.enable_public_redshift ? aws_route_table.public[*].id : aws_route_table.private[*].id)
 }

 output "elasticache_route_table_ids" {
---

---

Choice B:
outputs.tf
@@ -250,7 +250,7 @@ output "database_route_table_ids" {

 output "redshift_route_table_ids" {
   description = "List of IDs of redshift route tables"
-  value       = try(coalescelist(aws_route_table.redshift[*].id, aws_route_table.public[*].id, aws_route_table.private[*].id), [])
+  value       = length(aws_route_table.redshift[*].id) : 0 ? aws_route_table.redshift[*].id : (var.enable_public_redshift ? aws_route_table.public[*].id : aws_route_table.private[*].id)
 }

 output "elasticache_route_table_ids" {
---

---

Choice C:
outputs.tf
@@ -250,7 +250,7 @@ output "database_route_table_ids" {

 output "redshift_route_table_ids" {
   description = "List of IDs of redshift route tables"
-  value       = try(coalescelist(aws_route_table.redshift[*].id, aws_route_table.public[*].id, aws_route_table.private[*].id), [])
+ of value       = length(aws_route_table.redshift[*].id) > 0 ? aws_route_table.redshift[*].id : (var.enable_public_redshift ? aws_route_table.public[*].id : aws_route_table.private[*].id)
 }

 output "elasticache_route_table_ids" {
---

---

Choice D:
outputs.tf
@@ -250,7 +250,7 @@ output "database_route_table_ids" {

 output "redshift_route_table_ids" {
   description = "List of IDs of redshift route tables"
-  value       = try(coalescelist(aws_route_table.redshift[*].id, aws_route_table.public[*].id, aws_route_table.private[*].id), [])
+  value       = length(aws_route_table.redshift[*].id) > 0 ? aws_route_table.redshift[*].id : (var.enable_public_redshift ? aws_route_table.public[*].id : aws_route_table.private[*].id)
 }

 output "elasticache_route_table_ids" {
---

---


Choose the best Terraform patch (A/B/C/D) that implements the requested VPC networking change safely. Only respond with a single uppercase letter.

Task Description:
As noted in the [terraform docs][0], subnets using the default network acl
will generate a persistent diff if they are not specified to the aws_default_network_acl
resource. This module was handling subnets created by the module, but
of course is not aware of subnets created externally to the module.

The docs suggest using lifecycle ignore_changes as an option to avoid
the persistent diff, which is the approach implemented in this patch.

Fixes #736

[0]: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_network_acl#managing-subnets-in-a-default-network-acl

## Breaking Changes
<!-- Does this break backwards compatibility with the current major version? -->
<!-- If so, please provide an explanation why it is necessary. -->
None

## How Has This Been Tested?
- [x] I have tested and validated these changes using one or more of the provided `examples/*` projects
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->

1. cd examples/network-acls
2. run terraform apply
3. manually create a new subnet in the vpc
4. run terraform apply
5. view that no changes are planned

---

Choice A:
examples/complete-vpc/README.md
@@ -46,7 +46,6 @@ Note that this example may create resources which can cost money (AWS Elastic IP
 | [aws_iam_policy_document.dynamodb_endpoint_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
 | [aws_iam_policy_document.generic_endpoint_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
 | [aws_security_group.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/security_group) | data source |
-| [aws_vpc_endpoint.dynamodb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc_endpoint) | data source |

 ## Inputs

---
examples/complete-vpc/main.tf
@@ -187,12 +187,6 @@ data "aws_security_group" "default" {
   vpc_id = module.vpc.vpc_id
 }

-# Data source used to avoid race condition
-data "aws_vpc_endpoint" "dynamodb" {
-  vpc_id       = module.vpc.vpc_id
-  service_name = "com.amazonaws.${local.region}.dynamodb"
-}
-
 data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
   statement {
     effect    = "Deny"
@@ -208,7 +202,7 @@ data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
       test     = "StringNotEquals"
       variable = "aws:sourceVpce"

-      values = [data.vpc.vpc_id]
+      values = [module.vpc.vpc_id]
     }
    }
---
main.tf
@@ -587,28 +587,9 @@ resource "aws_default_network_acl" "this" {

   default_network_acl_id = aws_vpc.this[0].default_network_acl_id

-  # The value of subnet_ids should be any subnet IDs that are not set as subnet_ids
-  #   for any of the non-default network ACLs
-  subnet_ids = setsubtract(
-    compact(flatten([
-      aws_subnet.public[*].id,
-      aws_subnet.private[*].id,
-      aws_subnet.intra[*].id,
-      aws_subnet.database[*].id,
-      aws_subnet.redshift[*].id,
-      aws_subnet.elasticache[*].id,
-      aws_subnet.outpost[*].id,
-    ])),
-    compact(flatten([
-      aws_network_acl.public[*].subnet_ids,
-      aws_network_acl.private[*].subnet_ids,
-      aws_network_acl.intra[*].subnet_ids,
-      aws_network_acl.database[*].subnet_ids,
-      aws_network_acl.redshift[*].subnet_ids,
-      aws_network_acl.elasticache[*].subnet_ids,
-      aws_network_acl.outpost[*].subnet_ids,
-    ]))
-  )
+  # subnet_ids is using lifecycle ignore_changes, so it is not necessary to list
+  # any explicitly. See https://github.com/terraform-aws-modules/terraform-aws-vpc/issues/736.
+  subnet_ids = null

   dynamic "ingress" {
     for_each = var.default_network_acl_ingress
@@ -644,6 +625,10 @@ resource "aws_default_network_acl" "this" {
     var.tags,
     var.default_network_acl_tags,
   )
+
+  lifecycle {
+    ignore_changes = [subnet_ids]
+  }
 }

 ################################################################################
---

---

Choice B:
examples/complete-vpc/README.md
@@ -46,7 +46,6 @@ Note that this example may create resources which can cost money (AWS Elastic IP
 | [aws_iam_policy_document.dynamodb_endpoint_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
 | [aws_iam_policy_document.generic_endpoint_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
 | [aws_security_group.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/security_group) | data source |
-| [aws_vpc_endpoint.dynamodb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc_endpoint) | data source |

 ## Inputs

---
examples/complete-vpc/main.tf
@@ -187,12 +187,6 @@ data "aws_security_group" "default" {
   vpc_id = module.vpc.vpc_id
 }

-# Data source used to avoid race condition
-data "aws_vpc_endpoint" "dynamodb" {
-  vpc_id       = module.vpc.vpc_id
-  service_name = "com.amazonaws.${local.region}.dynamodb"
-}
-
 data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
   statement {
     effect    = "Deny"
@@ -208,7 +202,7 @@ data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
       test     = "StringNotEquals"
       variable = "aws:sourceVpce"

-      values = [data.vpc.vpc_id]
+      values = [module.vpc.vpc_id]
     }
   }
 }
---
main.tf
@@ -587,28 +587,9 @@ resource "aws_default_network_acl" "this" {

   default_network_acl_id = aws_vpc.this[0].default_network_acl_id

-  # The value of subnet_ids should be any subnet IDs that are not set as subnet_ids
-  #   for any of the non-default network ACLs
-  subnet_ids = setsubtract(
-    compact(flatten([
-      aws_subnet.public[*].id,
-      aws_subnet.private[*].id,
-      aws_subnet.intra[*].id,
-      aws_subnet.database[*].id,
-      aws_subnet.redshift[*].id,
-      aws_subnet.elasticache[*].id,
-      aws_subnet.outpost[*].id,
-    ])),
-    compact(flatten([
-      aws_network_acl.public[*].subnet_ids,
-      aws_network_acl.private[*].subnet_ids,
-      aws_network_acl.intra[*].subnet_ids,
-      aws_network_acl.database[*].subnet_ids,
-      aws_network_acl.redshift[*].subnet_ids,
-      aws_network_acl.elasticache[*].subnet_ids,
-      aws_network_acl.outpost[*].subnet_ids,
-    ]))
-  )
+  # subnet_ids is using lifecycle ignore_changes, so it is not necessary to list
+  # any explicitly. See https://github.com/terraform-aws-modules/terraform-aws-vpc/issues/736.
+ {
 subnet_ids = null

   dynamic "ingress" {
     for_each = var.default_network_acl_ingress
@@ -644,6 +625,10 @@ resource "aws_default_network_acl" "this" {
     var.tags,
     var.default_network_acl_tags,
   )
+
+  lifecycle {
+    ignore_changes = [subnet_ids]
+  }
 }

 ################################################################################
---

---

Choice C:
examples/complete-vpc/README.md
@@ -46,7 +46,6 @@ Note that this example may create resources which can cost money (AWS Elastic IP
 | [aws_iam_policy_document.dynamodb_endpoint_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
 | [aws_iam_policy_document.generic_endpoint_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
 | [aws_security_group.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/security_group) | data source |
-| [aws_vpc_endpoint.dynamodb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc_endpoint) | data source |

 ## Inputs

---
examples/complete-vpc/main.tf
@@ -187,12 +187,6 @@ data "aws_security_group" "default" {
   vpc_id = module.vpc.vpc_id
 }

-# Data source used to avoid race condition
-data "aws_vpc_endpoint" "dynamodb" {
-  vpc_id       = module.vpc.vpc_id
-  service_name = "com.amazonaws.${local.region}.dynamodb"
-}
-
 data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
   statement {
     effect    = "Deny"
@@ -208,7 +202,7 @@ data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
       test     = "StringNotEquals"
       variable = "aws:sourceVpce"

-      values = [data.vpc.vpc_id]
+      values = [module.vpc.vpc_id]
     }
   }
 }
---
main.tf
@@ -587,28 +587,9 @@ resource "aws_default_network_acl" "this" {

   default_network_acl_id = aws_vpc.this[0].default_network_acl_id

-  # The value of subnet_ids should be any subnet IDs that are not set as subnet_ids
-  #   for any of the non-default network ACLs
-  subnet_ids = setsubtract(
-    compact(flatten([
-      aws_subnet.public[*].id,
-      aws_subnet.private[*].id,
-      aws_subnet.intra[*].id,
-      aws_subnet.database[*].id,
-      aws_subnet.redshift[*].id,
-      aws_subnet.elasticache[*].id,
-      aws_subnet.outpost[*].id,
-    ])),
-    compact(flatten([
-      aws_network_acl.public[*].subnet_ids,
-      aws_network_acl.private[*].subnet_ids,
-      aws_network_acl.intra[*].subnet_ids,
-      aws_network_acl.database[*].subnet_ids,
-      aws_network_acl.redshift[*].subnet_ids,
-      aws_network_acl.elasticache[*].subnet_ids,
-      aws_network_acl.outpost[*].subnet_ids,
-    ]))
-  )
+  # subnet_ids is using lifecycle ignore_changes, so it is not necessary to list
+  # any explicitly. See https://github.com/terraform-aws-modules/terraform-aws-vpc/issues/736.
+  subnet_ids = null

   dynamic "ingress" {
     for_each = var.default_network_acl_ingress
@@ -644,6 +625,10 @@ resource "aws_default_network_acl" -587,28 {
     var.tags,
     var.default_network_acl_tags,
   )
+
+  lifecycle {
+    ignore_changes = [subnet_ids]
+  }
 }

 ################################################################################
---

---

Choice D:
examples/complete-vpc/README.md
@@ -46,7 +46,6 @@ Note that this example may create resources which can cost money (AWS Elastic IP
 | [aws_iam_policy_document.dynamodb_endpoint_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
 | [aws_iam_policy_document.generic_endpoint_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
 | [aws_security_group.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/security_group) | data source |
-| [aws_vpc_endpoint.dynamodb](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc_endpoint) | data source |

 ## Inputs

---
examples/complete-vpc/main.tf
@@ -187,12 +187,6 @@ data "aws_security_group" "default" {
   vpc_id = module.vpc.vpc_id
 }

-# Data source used to avoid race condition
-data "aws_vpc_endpoint" "dynamodb" {
-  vpc_id       = module.vpc.vpc_id
-  service_name = "com.amazonaws.${local.region}.dynamodb"
-}
-
 data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
   statement {
     effect    = "Deny"
@@ -208,7 +202,7 @@ data "aws_iam_policy_document" "dynamodb_endpoint_policy" {
       test     = "StringNotEquals"
       variable = "aws:sourceVpce"

-      values = [data.vpc.vpc_id]
+      values = [module.vpc.vpc_id]
     }
   }
 }
---
main.tf
@@ -587,28 +587,9 @@ resource "aws_default_network_acl" "this" {

   default_network_acl_id = aws_vpc.this[0].default_network_acl_id

-  # The value of subnet_ids should be any subnet IDs that are not set as subnet_ids
-  #   for any of the non-default network ACLs
-  subnet_ids = setsubtract(
-    compact(flatten([
-      aws_subnet.public[*].id,
-      aws_subnet.private[*].id,
-      aws_subnet.intra[*].id,
-      aws_subnet.database[*].id,
-      aws_subnet.redshift[*].id,
-      aws_subnet.elasticache[*].id,
-      aws_subnet.outpost[*].id,
-    ])),
-    compact(flatten([
-      aws_network_acl.public[*].subnet_ids,
-      aws_network_acl.private[*].subnet_ids,
-      aws_network_acl.intra[*].subnet_ids,
-      aws_network_acl.database[*].subnet_ids,
-      aws_network_acl.redshift[*].subnet_ids,
-      aws_network_acl.elasticache[*].subnet_ids,
-      aws_network_acl.outpost[*].subnet_ids,
-    ]))
-  )
+  # subnet_ids is using lifecycle ignore_changes, so it is not necessary to list
+  # any explicitly. See https://github.com/terraform-aws-modules/terraform-aws-vpc/issues/736.
+  subnet_ids = null

   dynamic "ingress" {
     for_each = var.default_network_acl_ingress
@@ -644,6 +625,10 @@ resource "aws_default_network_acl" "this" {
     var.tags,
     var.default_network_acl_tags,
   )
+
+  lifecycle {
+    ignore_changes = [subnet_ids]
+  }
 }

 ################################################################################
---

---


Choose the best Terraform patch (A/B/C/D) that implements the requested VPC networking change safely. Only respond with a single uppercase letter.

Task Description:
## Description

- Update `.releaserc.json` to ensure conventional-commit standards are used by semantic-releaser
- Update `.pre-commit-config.yaml` versions to latest and ensure `end-of-file-fixer` hook is used
- Add `pr-title.yml` GitHub workflow for ensuring PR titles follow conventional-commit standards
- Fix `release.yml` GitHub workflow to ensure release process does not run on forks; ref https://github.com/terraform-aws-modules/meta/issues/25
- Add `stale-actions.yaml` to ensure issues and pull requests are routinely cleaned up; copie from EKS repository

## Motivation and Context

- Ensure organization configurations are aligned and standardized; most of these changes are copied from the current EKS repository

## Breaking Changes

- No

## How Has This Been Tested?

- CI checks only

---

Choice A:
.github/workflows/pr-title.yml
@@ -0,0 +1,52 @@
+name: 'Validate PR title'
+
+on:
+  pull_request_target:
+    types:
+      - opened
+      - edited
+      - synchronize
+
+jobs:
+  main:
+    name: Validate PR title
+    runs-on: ubuntu-latest
+    steps:
+      # Please look up the latest version from
+      # https://github.com/amannn/action-semantic-pull-request/releases
+      - uses: amannn/action-semantic-pull-request@v3.4.6
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          # Configure which types are allowed.
+          # Default: https://github.com/commitizen/conventional-commit-types
+          types: |
+            fix
+            feat
+            docs
+            ci
+            chore
+          # Configure that a scope must always be provided.
+          requireScope: false
+          # Configure additional validation for the subject based on a regex.
+          # This example ensures the subject starts with an uppercase character.
+          subjectPattern: ^[A-Z].+$
+          # If `subjectPattern` is configured, you can use this property to override
+          # the default error message that is shown when the pattern doesn't match.
+          # The variables `subject` and `title` can be used within the message.
+          subjectPatternError: |
+            The subject "{subject}" found in the pull request title "{title}"
+            didn't match the configured pattern. Please ensure that the subject
+            starts with an uppercase character.
+          # For work-in-progress PRs you can typically use draft pull requests
+          # from Github. However, private repositories on the free plan don't have
+          # this option and therefore this action allows you to opt-in to using the
+          # special "[WIP]" prefix to indicate this state. This will avoid the
+          # validation of the PR title and the pull request checks remain pending.
+          # Note that a second check will be reported if this is enabled.
+          wip: true
+          # When using "Squash and merge" on a PR with only one commit, GitHub
+          # will suggest using that commit message instead of the PR title for the
+          # merge commit, and it's easy to commit this by mistake. Enable this option
+          # to also validate the commit message for one commit PRs.
+          validateSingleCommit: false
---
.github/workflows/release.yml
@@ -7,13 +7,17 @@ on:
       - main
       - master
     paths:
+      - '**/*.tpl'
       - '**/*.py'
       - '**/*.tf'
+      - '.github/workflows/release.yml'

 jobs:
   release:
     name: Release
     runs-on: ubuntu-latest
+    # Skip running release workflow on forks
+    if: github.repository_owner == 'terraform-aws-modules'
     steps:
       - name: Checkout
         uses: actions/checkout@v2
@@ -28,5 +32,6 @@ jobs:
           extra_plugins: |
             @semantic-release/changelog@6.0.0
             @semantic-release/git@10.0.0
+            conventional-changelog-conventionalcommits@4.6.3
         env:
           GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN }}
---
.github/workflows/stale-actions.yaml
@@ -0,0 +1,32 @@
+name: 'Mark or close stale issues and PRs'
+on:
+  schedule:
+    - cron: '0 0 * * *'
+
+jobs:
+  stale:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/stale@v4
+        with:
+          repo-token: ${{ secrets.GITHUB_TOKEN }}
+          # Staling issues and PR's
+          days-before-stale: 30
+          stale-issue-label: stale
+          stale-pr-label: stale
+          stale-issue-message: |
+            This issue has been automatically marked as stale because it has been open 30 days
+            with no activity. Remove stale label or comment or this issue will be closed in 10 days
+          stale-pr-message: |
+            This PR has been automatically marked as stale because it has been open 30 days
+            with no activity. Remove stale label or comment or this PR will be closed in 10 days
+          # Not stale if have this labels or part of milestone
+          exempt-issue-labels: bug,wip,on-hold
+          exempt-pr-labels: bug,wip,on-hold
+          exempt-all-milestones: true
+          # Close issue operations
+          check-merge-conflict
+ Label will be automatically removed if the issues are no longer closed nor locked.
+          days-before-close: 10
+          delete-branch: true
+          close-issue-message: This issue was automatically closed because of stale in 10 days
+          close-pr-message: This PR was automatically closed because of stale in 10 days
---
.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
   - repo: https://github.com/antonbabenko/pre-commit-terraform
-    rev: v1.58.0
+    rev: v1.62.3
     hooks:
       - id: terraform_fmt
       - id: terraform_validate
@@ -23,6 +23,7 @@ repos:
           - '--args=--only=terraform_standard_module_structure'
           - '--args=--only=terraform_workspace_remote'
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.0.1
+    rev: v4.1.0
     hooks:
       - id: check-merge-conflict
+      - id: end-of-file-fixer
---
.releaserc.json
@@ -5,13 +5,22 @@
   ],
   "ci": false,
   "plugins": [
-    "@semantic-release/commit-analyzer",
-    "@semantic-release/release-notes-generator",
+    [
+      "@semantic-release/commit-analyzer",
+      {
+        "preset": "conventionalcommits"
+      }
+    ],
+    [
+      "@semantic-release/release-notes-generator",
+      {
+        "preset": "conventionalcommits"
+      }
+    ],
     [
       "@semantic-release/github",
       {
-        "successComment":
-        "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:",
+        "successComment": "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:",
         "labels": false,
         "releasedLabels": false
       }
---
examples/manage-default-vpc/main.tf
@@ -19,4 +19,3 @@ module "vpc" {
   default_vpc_name                 = "default"
   default_vpc_enable_dns_hostnames = true
 }
-
---
examples/manage-default-vpc/outputs.tf
@@ -8,4 +8,3 @@ output "default_vpc_cidr_block" {
   description = "The CIDR block of the VPC"
   value       = module.vpc.default_vpc_cidr_block
 }
-
---
examples/secondary-cidr-blocks/outputs.tf
@@ -31,4 +31,3 @@ output "nat_public_ips" {
   description = "List of public Elastic IPs created for AWS NAT Gateway"
   value       = module.vpc.nat_public_ips
 }
-
---
examples/simple-vpc/outputs.tf
@@ -32,4 +32,3 @@ output "azs" {
   description = "A list of availability zones specified as argument to this module"
   value       = module.vpc.azs
 }
-
---
examples/vpc-flow-logs/outputs.tf
@@ -55,4 +55,3 @@ output "vpc_flow_logs_s3_bucket_vpc_flow_log_destination_type" {
   description = "The type of the destination for VPC Flow Logs"
   value       = module.vpc_with_flow_logs_s3_bucket.vpc_flow_log_destination_type
 }
-
---
examples/vpc-separate-private-route-tables/outputs.tf
@@ -35,4 +35,3 @@ output "nat_public_ips" {
   description = "List of public Elastic IPs created for AWS NAT Gateway"
   value       = module.vpc.nat_public_ips
 }
-
---

---

Choice B:
.github/workflows/pr-title.yml
@@ -0,0 +1,52 @@
+name: 'Validate PR title'
+
+on:
+  pull_request_target:
+    types:
+      - opened
+      - edited
+      - synchronize
+
+jobs:
+  main:
+    name: Validate PR title
+    runs-on: ubuntu-latest
+    steps:
+      # Please look up the latest version from
+      # https://github.com/amannn/action-semantic-pull-request/releases
+      - uses: amannn/action-semantic-pull-request@v3.4.6
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          # Configure which types are allowed.
+          # Default: https://github.com/commitizen/conventional-commit-types
+          types: |
+            fix
+            feat
+            docs
+            ci
+            chore
+          # Configure that a scope must always be provided.
+          requireScope: false
+          # Configure additional validation for the subject based on a regex.
+          # This example ensures the subject starts with an uppercase character.
+          subjectPattern: ^[A-Z].+$
+          # If `subjectPattern` is configured, you can use this property to override
+          # the default error message that is shown when the pattern doesn't match.
+          # The variables `subject` and `title` can be used within the message.
+          subjectPatternError: |
+            The subject "{subject}" found in the pull request title "{title}"
+            didn't match the configured pattern. Please ensure that the subject
+            starts with an uppercase character.
+          # For work-in-progress PRs you can typically use draft pull requests
+          # from Github. However, private repositories on the free plan don't have
+          # this option and therefore this action allows you to opt-in to using the
+          # special "[WIP]" prefix to indicate this state. This will avoid the
+          # validation of the PR title and the pull request checks remain pending.
+          # Note that a second check will be reported if this is enabled.
+          wip: true
+          # When using "Squash and merge" on a PR with only one commit, GitHub
+          # will suggest using that commit message instead of the PR title for the
+          # merge commit, and it's easy to commit this by mistake. Enable this option
+          # to also validate the commit message for one commit PRs.
+          validateSingleCommit: false
---
.github/workflows/release.yml
@@ -7,13 +7,17 @@ on:
       - main
       - master
     paths:
+      - '**/*.tpl'
       - '**/*.py'
       - '**/*.tf'
+      - '.github/workflows/release.yml'

 jobs:
   release:
     name: Release
     runs-on: ubuntu-latest
+    # Skip running release workflow on forks
+    if: github.repository_owner == 'terraform-aws-modules'
     steps:
       - name: Checkout
         uses: actions/checkout@v2
@@ -28,5 +32,6 @@ jobs:
           extra_plugins: |
             @semantic-release/changelog@6.0.0
             @semantic-release/git@10.0.0
+            conventional-changelog-conventionalcommits@4.6.3
         env:
           GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN }}
---
.github/workflows/stale-actions.yaml
@@ -0,0 +1,32 @@
+name: 'Mark or close stale issues and PRs'
+on:
+  schedule:
+    - cron: '0 0 * * *'
+
+jobs:
+  stale:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/stale@v4
+        with:
+          repo-token: ${{ secrets.GITHUB_TOKEN }}
+          # Staling issues and PR's
+          days-before-stale: 30
+          stale-issue-label: stale
+          stale-pr-label: stale
+          stale-issue-message: |
+            This issue has been automatically marked as stale because it has been open 30 days
+            with no activity. Remove stale label or comment or this issue will be closed in 10 days
+          stale-pr-message: |
+            This PR has been automatically marked as stale because it has been open 30 days
+            with no activity. Remove stale label or comment or this PR will be closed in 10 days
+          # Not stale if have this labels or part of milestone
+          exempt-issue-labels: bug,wip,on-hold
+          exempt-pr-labels: bug,wip,on-hold
+          exempt-all-milestones: true
+          # Close issue operations
+          # Label will be automatically removed if the issues are no longer closed nor locked.
+          days-before-close: 10
+          delete-branch: true
+          close-issue-message: This issue was automatically closed because of stale in 10 days
+          close-pr-message: This PR was automatically closed because of stale in 10 days
---
.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
   - repo: https://github.com/antonbabenko/pre-commit-terraform
-    rev: v1.58.0
+    rev: v1.62.3
     hooks:
       - id: terraform_fmt
       - id: terraform_validate
@@ -23,6 +23,7 @@ repos:
           - '--args=--only=terraform_standard_module_structure'
           - '--args=--only=terraform_workspace_remote'
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.0.1
+    rev: v4.1.0
     hooks:
       - id: check-merge-conflict
+      - id: end-of-file-fixer
---
.releaserc.json
@@ -5,13 +5,22 @@
   ],
   "ci": false,
   "plugins": [
-    "@semantic-release/commit-analyzer",
-    "@semantic-release/release-notes-generator",
+    [
+      "@semantic-release/commit-analyzer",
+      {
+        "preset": "conventionalcommits"
+      }
+    ],
+    [
+      "@semantic-release/release-notes-generator",
+      {
+        "preset": "conventionalcommits"
+      }
+    ],
     [
       "@semantic-release/github",
       {
-        "successComment":
-        "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:",
+        "successComment": "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:",
         "labels": false,
         "releasedLabels": false
       }
---
examples/manage-default-vpc/main.tf
@@ -19,4 +19,3 @@ module "vpc" {
   default_vpc_name                 = "default"
   default_vpc_enable_dns_hostnames = true
 }
-
---
examples/manage-default-vpc/outputs.tf
@@ -8,4 +8,3 @@ output "default_vpc_cidr_block" {
   description = "The CIDR block of the VPC"
   value       = module.vpc.default_vpc_cidr_block
 }
-
---
examples/secondary-cidr-blocks/outputs.tf
@@ -31,4 +31,3 @@ output "nat_public_ips" {
   description = "List of public Elastic IPs created for AWS NAT Gateway"
   value       = module.vpc.nat_public_ips
 }
-
---
examples/simple-vpc/outputs.tf
@@ -32,4 +32,3 @@ output "azs" {
   description = "A list of availability zones specified as argument to this module"
   value       = module.vpc.azs
 }
-
---
examples/vpc-flow-logs/outputs.tf
@@ -55,4 +55,3 @@ output "vpc_flow_logs_s3_bucket_vpc_flow_log_destination_type" {
   description = "The type of the destination for VPC Flow Logs"
   value       = module.vpc_with_flow_logs_s3_bucket.vpc_flow_log_destination_type
 }
-
---
examples/vpc-separate-private-route-tables/outputs.tf
@@ -35,4 +35,3 @@ output "nat_public_ips" {
   description = "List of public Elastic IPs created for AWS NAT Gateway"
   value       = module.vpc.nat_public_ips
 }
-
---

---

Choice C:
.github/workflows/pr-title.yml
@@ -0,0 +1,52 @@
+name: 'Validate PR title'
+
+on:
+  pull_request_target:
+    types:
+      - opened
+      - edited
+      - synchronize
+
+jobs:
+  main:
+    name: Validate PR title
+    runs-on: ubuntu-latest
+    steps:
+      # Please look up the latest version from
+      # https://github.com/amannn/action-semantic-pull-request/releases
+      - uses: amannn/action-semantic-pull-request@v3.4.6
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          # Configure which types are allowed.
+          # Default: https://github.com/commitizen/conventional-commit-types
+          types: |
+            fix
+            feat
+            docs
+            ci
+            chore
+          # Configure that a scope must always be provided.
+          requireScope: false
+          # Configure additional validation for the subject based on a regex.
+          # This example ensures the subject starts with an uppercase character.
+          subjectPattern: ^[A-Z].+$
+          # If `subjectPattern` is configured, you can use this property to override
+          # the default error message that is shown when the pattern doesn't match.
+          # The variables `subject` and `title` can be used within the message.
+          subjectPatternError: |
+            The subject "{subject}" found in the pull request title "{title}"
+            didn't match the configured pattern. Please ensure that the subject
+            starts with an uppercase character.
+          # For work-in-progress PRs you can typically use draft pull requests
+          # from Github. However, private repositories on the free plan don't have
+          # this option and therefore this action allows you to opt-in to using the
+          # special "[WIP]" prefix to indicate this state. This will avoid the
+          # validation of the PR title and the pull request checks remain pending.
+          # Note that a second check will be reported if this is enabled.
+          wip: true
+          # When using "Squash and merge" on a PR with only one commit, GitHub
+          # will suggest using that commit message instead of the PR title for the
+          # merge commit, and it's easy to commit this by mistake. Enable this option
+          # to also validate the commit message for one commit PRs.
+          validateSingleCommit: false
---
.github/workflows/release.yml
@@ -7,13 +7,17 @@ on:
       - main
       - master
     paths:
+      - '**/*.tpl'
       - '**/*.py'
       - '**/*.tf'
+      - '.github/workflows/release.yml'

 jobs:
   release:
     name: Release
     runs-on: ubuntu-latest
+    # Skip running release workflow on forks
+    if: github.repository_owner == 'terraform-aws-modules'
     steps:
       - name: Checkout
         uses: actions/checkout@v2
@@ -28,5 +32,6 @@ jobs:
           extra_plugins: |
             @semantic-release/changelog@6.0.0
             @semantic-release/git@10.0.0
+            conventional-changelog-conventionalcommits@4.6.3
         env:
           GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN }}
---
.github/workflows/stale-actions.yaml
@@ -0,0 +1,32 @@
+name: 'Mark or close stale issues and PRs'
+on:
+  schedule:
+    - cron: '0 0 * * *'
+
+jobs:
+  stale:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/stale@v4
+        with:
+          repo-token: ${{ secrets.GITHUB_TOKEN }}
+          # Staling issues and PR's
+          days-before-stale: 30
+          stale-issue-label: stale
+          stale-pr-label: stale
+          stale-issue-message: |
+            This issue has been automatically marked as stale because it has been open 30 days
+            with no activity. Remove stale label or comment or this issue will be closed in 10 days
+          stale-pr-message: |
+            This PR has been automatically marked as stale because it has been open 30 days
+            with no activity. Remove stale label or comment or this PR will be closed in 10 days
+          # Not stale if have this labels or part of milestone
+          exempt-issue-labels: bug,wip,on-hold
+          exempt-pr-labels: bug,wip,on-hold
+          exempt-all-milestones: true
+          # Close issue operations
+          # Label will be automatically removed if the issues are no longer closed nor locked.
+          days-before-close: 10
+          delete-branch: true
+          close-issue-message: This issue was automatically closed because of stale in 10 days
+          close-pr-message: This PR was automatically closed because of stale in 10 days
---
.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
   - repo: https://github.com/antonbabenko/pre-commit-terraform
-    rev: v1.58.0
+    rev: v1.62.3
     hooks:
       - id: terraform_fmt
       - id: terraform_validate
@@ -23,6 +23,7 @@ repos:
           - '--args=--only=terraform_standard_module_structure'
           - '--args=--only=terraform_workspace_remote'
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.0.1
+    rev: v4.1.0
     hooks:
       - id: check-merge-conflict
+      - id: end-of-file-fixer
---
.releaserc.json
@@ -5,13 +5,22 @@
   ],
   "ci": false,
   "plugins": [
-    "@semantic-release/commit-analyzer",
-    "@semantic-release/release-notes-generator",
+    [
+      "@semantic-release/commit-analyzer",
+      {
+        "preset": "conventionalcommits"
+      }
+    ],
+    [
+      "@semantic-release/release-notes-generator",
+      {
+        "preset": "conventionalcommits"
+      }
+    ],
     [
       "@semantic-release/github",
       {
-        "successComment":
-        "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:",
+        "successComment": "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:",
         "labels": false,
         "releasedLabels": false
       }
---
examples/manage-default-vpc/main.tf
@@ -19,4 +19,3 @@ module "vpc" {
   default_vpc_name                 = "default"
   default_vpc_enable_dns_hostnames = true
 }
-
---
examples/manage-default-vpc/outputs.tf
@@ -8,4 +8,3 @@ output "default_vpc_cidr_block" {
   description = "The CIDR block of the VPC"
   value       = module.vpc.default_vpc_cidr_block
 }
-
---
examples/secondary-cidr-blocks/outputs.tf
@@ -31,4 +31,3 @@ output "nat_public_ips" {
   description = "List of public Elastic IPs created for AWS NAT Gateway"
   value       = module.vpc.nat_public_ips
 }
-
---
examples/simple-vpc/outputs.tf
@@ -32,4 +32,3 @@ output "azs" {
   description = "A list of availability zones specified as argument to this module"
   value       = module.vpc.azs
 }
-
---
examples/vpc-flow-logs/outputs.tf
@@ -55,4 +55,3 @@ output "vpc_flow_logs_s3_bucket_vpc_flow_log_destination_type" {
   description = "The type of the destination for VPC Flow Logs"
   value       = module.vpc_with_flow_logs_s3_bucket.vpc_flow_log_destination_type
 }
-
---
examples/vpc-separate-private-route-tables/outputs.tf
@@ -35,4 +35,3 @@ output "nat_public_ips" {
   description = "List of public Elastic IPs created for AWS NAT Gateway"
   value       = module.vpc.nat_public_ips
 }
-
---

---

Choice D:
.github/workflows/pr-title.yml
@@ -0,0 +1,52 @@
+name: 'Validate PR title'
+
+on:
+  pull_request_target:
+    types:
+      - opened
+      - edited
+      - synchronize
+
+jobs:
+  main:
+    name: Validate PR title
+    runs-on: ubuntu-latest
+    steps:
+      # Please look up the latest version from
+      # https://github.com/amannn/action-semantic-pull-request/releases
+      - uses: amannn/action-semantic-pull-request@v3.4.6
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          # Configure which types are allowed.
+          # Default: https://github.com/commitizen/conventional-commit-types
+          types: |
+            fix
+            feat
+            docs
+            ci
+            chore
+          # Configure that a scope must always be provided.
+          requireScope: false
+          # Configure additional validation for the subject based on a regex.
+          # This example ensures the subject starts with an uppercase character.
+          subjectPattern: ^[A-Z].+$
+          # If `subjectPattern` is configured, you can use this property to override
+          # the default error message that is shown when the pattern doesn't match.
+          # The variables `subject` and `title` can be used within the message.
+          subjectPatternError: |
+            The subject "{subject}" found in the pull request title "{title}"
+            didn't match the configured pattern. Please ensure that the subject
+            starts with an uppercase character.
+          # For work-in-progress PRs you can typically use draft pull requests
+          # from Github. However, private repositories on the free plan don't have
+          # this option and therefore this action allows you to opt-in to using the
+          # special "[WIP]" prefix to indicate this state. This will avoid the
+          # validation of the PR title and the pull request checks remain pending.
+          # Note that a second check will be reported if this is enabled.
+          wip: true
+          # When using "Squash and merge" on a PR with only one commit, GitHub
+          # will suggest using that commit message instead of the PR title for the
+          # merge commit, and it's easy to commit this by mistake. Enable this option
+          # to also validate the commit message for one commit PRs.
+          validateSingleCommit: false
---
.github/workflows/release.yml
@@ -7,13 +7,17 @@ on:
       - main
       - master
     paths:
+      - '**/*.tpl'
       - '**/*.py'
       - '**/*.tf'
+      - '.github/workflows/release.yml'

 jobs:
   release:
     name: Release
     runs-on: ubuntu-latest
+    # Skip running release workflow on forks
+    if: github.repository_owner == 'terraform-aws-modules'
     steps:
       - name: Checkout
         uses: actions/checkout@v2
@@ -28,5 +32,6 @@ jobs:
           extra_plugins: |
             @semantic-release/changelog@6.0.0
             @semantic-release/git@10.0.0
+            conventional-changelog-conventionalcommits@4.6.3
         env:
           GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN }}
---
.github/workflows/stale-actions.yaml
@@ -0,0 +1,32 @@
+name: 'Mark or close stale issues and PRs'
+on:
+  schedule:
+    - cron: '0 0 * * *'
+
+jobs:
+  stale:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/stale@v4
+        with:
+          repo-token: ${{ secrets.GITHUB_TOKEN }}
+          # Staling issues and PR's
+          days-before-stale: 30
+          stale-issue-label: stale
+          stale-pr-label: stale
+          stale-issue-message: |
+            This issue has been automatically marked as stale because it has been open 30 days
+            with no activity. Remove stale label or comment or this issue will be closed in 10 days
+          stale-pr-message: |
+            This PR has been automatically marked as stale because it has been open 30 days
+            with no activity. Remove stale label or comment or this PR will be closed in 10 days
+          # Not stale if have this labels or part of milestone
+          exempt-issue-labels: bug,wip,on-hold
+          exempt-pr-labels: bug,wip,on-hold
+          exempt-all-milestones: true
+          # Close issue operations
+          # Label will be automatically removed if the issues are no longer closed nor locked.
+          days-before-close: 10
+          delete-branch: true
+          close-issue-message: This issue was automatically closed because of stale in 10 days
+          close-pr-message: This PR was automatically closed because of stale in 10 days
---
.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
   - repo: https://github.com/antonbabenko/pre-commit-terraform
-    rev: v1.58.0
+    rev: v1.62.3
     hooks:
       - id: terraform_fmt
       - id: terraform_validate
@@ -23,6 +23,7 @@ repos:
           - '--args=--only=terraform_standard_module_structure'
           - '--args=--only=terraform_workspace_remote'
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.0.1
+    rev: v4.1.0
     hooks:
       - id: check-merge-conflict
+      - id: end-of-file-fixer
---
.releaserc.json
@@ -5,13 +5,22 @@
   ],
   "ci": false,
   "plugins": [
-    "@semantic-release/commit-analyzer",
-    "@semantic-release/release-notes-generator",
+    [
+      "@semantic-release/commit-analyzer",
+      {
+        "preset": "conventionalcommits"
+      }
+    ],
+    [
+      "@semantic-release/release-notes-generator",
+      {
+        "preset": "conventionalcommits"
+      }
+    ],
     [
       "@semantic-release/github",
       {
-        "successComment":
-        "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:",
+        "successComment": "This ${issue.pull_request ? 'PR is included' : 'issue has been resolved'} in version ${nextRelease.version} :tada:",
         "labels": false,
         "releasedLabels": false
       }
---
examples/manage-default-vpc/main.tf
@@ -19,4 +19,3 @@ module "vpc" {
   default_vpc_name                 = "default"
   default_vpc_enable_dns_hostnames = true
 }
-
---
examples/manage-default-vpc/outputs.tf
@@ -8,4 +8,3 @@ output "default_vpc_cidr_block" {
   description = "The CIDR block of the VPC"
   value       = module.vpc.default_vpc_cidr_block
 }
-
---
examples/secondary-cidr-blocks/outputs.tf
@@ -31,4 +31,3 @@ output "nat_public_ips" {
   description = "List of public Elastic IPs created for AWS NAT Gateway"
   value       = module.vpc.nat_public_ips
 }
-
---
examples/simple-vpc/outputs.tf
@@ -32,4 +32,3 @@ output "azs" {
   description = "A list of availability zones specified as argument to this module"
   value       = module.vpc.azs
 }
-
---
examples/vpc-flow-logs/outputs.tf
@@ -55,4 +55,3 @@ output "vpc_flow_logs_s3_bucket_vpc_flow_log_destination_type" {
   description = "The type of the destination for VPC Flow Logs"
   value       = module.vpc_with_flow_logs_s3_bucket.vpc_flow_log_destination_type
 }
-
---
examples/vpc-separate-private-route-tables/outputs.tf
@@ -35,4 +35,3 @@ output "nat_public_ips" {
   description = "List of public Elastic IPs created for AWS NAT Gateway"
   value       = module.vpc.nat_public_ips
 }
-
---

---


Choose the best Terraform patch (A/B/C/D) that implements the requested VPC networking change safely. Only respond with a single uppercase letter.

Task Description:
this is new moudle

## Description
<!--- Describe your changes in detail -->

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->

## Breaking Changes
<!-- Does this break backwards compatibility with the current major version? -->
<!-- If so, please provide an explanation why it is necessary. -->

## How Has This Been Tested?
- [ ] I have tested and validated these changes using one or more of the provided `examples/*` projects
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->

---

Choice A:
newmodule
@@ -0,0 +1 @@
+this is module
---
 module
---

---

Choice B:
newmodule
@@ -0,0 +1 @@
+this is new module
---

---

Choice C:
newmodule
@@ -0,0 +1 is is new module
---

---

Choice D:
newmodule
@@ -0,0 +1 @@
+this newmodule
@@ new module
---

---


Choose the best Terraform patch (A/B/C/D) that implements the requested VPC networking change safely. Only respond with a single uppercase letter.

Task Description:
## Description
<!--- Describe your changes in detail -->

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->

## Breaking Changes
<!-- Does this break backwards compatibility with the current major version? -->
<!-- If so, please provide an explanation why it is necessary. -->

## How Has This Been Tested?
- [x] I have tested and validated these changes using one or more of the provided `examples/*` projects
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->

---

Choice A:
newmoudle
@@ -0,0 +1,2 @@
+adding @@
+adding module
+
---

---

Choice B:
newmoudle
@@ -0,0 +1,2 @@
+adding new module
+
---

---

Choice C:
-0,0 -0,0 +1,2 @@
+adding new module
+
---

---

Choice D:
newmoudle
@@ -0,0 newmoudle
@@ @@
+adding new module
+
---

---