Skip to content

Commit cf48c2c

Browse files
sc250024antonbabenko
authored andcommitted
Fix #117 - Add one_nat_gateway_per_az functionality (#129)
* Initial commit for issue #117 * Adding documentation for NAT Gateway creation * Adding `enable_nat_gateway` to the documentation * Updating README.md with `one_nat_gateway_per_az` to be 'true' by default * Reverted changes back to `one_nat_gateway_per_az` as 'false'
1 parent 11f9236 commit cf48c2c

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,49 @@ Note that in the example we allocate 3 IPs because we will be provisioning 3 NAT
7878
If, on the other hand, `single_nat_gateway = true`, then `aws_eip.nat` would only need to allocate 1 IP.
7979
Passing the IPs into the module is done by setting two variables `reuse_nat_ips = true` and `external_nat_ip_ids = ["${aws_eip.nat.*.id}"]`.
8080

81+
## NAT Gateway Scenarios
82+
83+
This module supports three scenarios for creating NAT gateways. Each will be explained in further detail in the corresponding sections.
84+
85+
* One NAT Gateway per subnet (default behavior)
86+
* `enable_nat_gateway = true`
87+
* `single_nat_gateway = false`
88+
* `one_nat_gateway_per_az = false`
89+
* Single NAT Gateway
90+
* `enable_nat_gateway = true`
91+
* `single_nat_gateway = true`
92+
* `one_nat_gateway_per_az = false`
93+
* One NAT Gateway per availability zone
94+
* `enable_nat_gateway = true`
95+
* `single_nat_gateway = false`
96+
* `one_nat_gateway_per_az = true`
97+
98+
If both `single_nat_gateway` and `one_nat_gateway_per_az` are set to `true`, then `single_nat_gateway` takes precedence.
99+
100+
### One NAT Gateway per subnet (default)
101+
102+
By default, the module will determine the number of NAT Gateways to create based on the the `max()` of the private subnet lists (`database_subnets`, `elasticache_subnets`, `private_subnets`, and `redshift_subnets`). For example, if your configuration looks like the following:
103+
104+
```hcl
105+
database_subnets = ["10.0.21.0/24", "10.0.22.0/24"]
106+
elasticache_subnets = ["10.0.31.0/24", "10.0.32.0/24"]
107+
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24", "10.0.5.0/24"]
108+
redshift_subnets = ["10.0.41.0/24", "10.0.42.0/24"]
109+
```
110+
111+
Then `5` NAT Gateways will be created since `5` private subnet CIDR blocks were specified.
112+
113+
### Single NAT Gateway
114+
115+
If `single_nat_gateway = true`, then all private subnets will route their Internet traffic through this single NAT gateway. The NAT gateway will be placed in the first public subnet in your `public_subnets` block.
116+
117+
### One NAT Gateway per availability zone
118+
119+
If `one_nat_gateway_per_az = true` and `single_nat_gateway = false`, then the module will place one NAT gateway in each availability zone you specify in `var.azs`. There are some requirements around using this feature flag:
120+
121+
* The variable `var.azs` **must** be specified.
122+
* The number of public subnet CIDR blocks specified in `public_subnets` **must** be greater than or equal to the number of availability zones specified in `var.azs`. This is to ensure that each NAT Gateway has a dedicated public subnet to deploy to.
123+
81124
## Conditional creation
82125

83126
Sometimes you need to have a way to create VPC resources conditionally but Terraform does not allow to use `count` inside `module` block, so the solution is to specify argument `create_vpc`.
@@ -141,6 +184,7 @@ Terraform version 0.10.3 or newer is required for this module to work.
141184
| manage_default_vpc | Should be true to adopt and manage Default VPC | string | `false` | no |
142185
| map_public_ip_on_launch | Should be false if you do not want to auto-assign public IP on launch | string | `true` | no |
143186
| name | Name to be used on all the resources as identifier | string | `` | no |
187+
| one_nat_gateway_per_az | Should be true if you want only one NAT Gateway per availability zone. Requires the input `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 `azs`. | string | `false` | no |
144188
| private_route_table_tags | Additional tags for the private route tables | string | `<map>` | no |
145189
| private_subnet_tags | Additional tags for the private subnets | string | `<map>` | no |
146190
| private_subnets | A list of private subnets inside the VPC | string | `<list>` | no |
@@ -227,3 +271,4 @@ Module managed by [Anton Babenko](https://github.com/antonbabenko).
227271
## License
228272

229273
Apache 2 Licensed. See LICENSE for full details.
274+

main.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ terraform {
44

55
locals {
66
max_subnet_length = "${max(length(var.private_subnets), length(var.elasticache_subnets), length(var.database_subnets), length(var.redshift_subnets))}"
7-
nat_gateway_count = "${var.single_nat_gateway ? 1 : local.max_subnet_length}"
7+
nat_gateway_count = "${var.single_nat_gateway ? 1 : (var.one_nat_gateway_per_az ? length(var.azs) : local.max_subnet_length)}"
88
}
99

1010
######
@@ -102,7 +102,7 @@ resource "aws_route_table" "private" {
102102
# Public subnet
103103
################
104104
resource "aws_subnet" "public" {
105-
count = "${var.create_vpc && length(var.public_subnets) > 0 ? length(var.public_subnets) : 0}"
105+
count = "${var.create_vpc && length(var.public_subnets) > 0 && (!var.one_nat_gateway_per_az || length(var.public_subnets) >= length(var.azs)) ? length(var.public_subnets) : 0}"
106106

107107
vpc_id = "${aws_vpc.this.id}"
108108
cidr_block = "${var.public_subnets[count.index]}"

variables.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ variable "single_nat_gateway" {
7676
default = false
7777
}
7878

79+
variable "one_nat_gateway_per_az" {
80+
description = "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`."
81+
default = false
82+
}
83+
7984
variable "reuse_nat_ips" {
8085
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"
8186
default = false

0 commit comments

Comments
 (0)