Skip to content

Commit 8ec1a1d

Browse files
authored
Merge pull request #86 from vivgoyal-aws/main
Fix: support private only subnets (nat_gateway_configuration == "none" / null)
2 parents c60216f + a670299 commit 8ec1a1d

File tree

7 files changed

+203
-4
lines changed

7 files changed

+203
-4
lines changed

data.tf

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ locals {
2525
# constructed list of <private_subnet_key>/az
2626
private_per_az = flatten([for az in local.azs : [for subnet in local.private_subnet_names : "${subnet}/${az}"]])
2727
# list of private subnet keys with connect_to_public_natgw = true
28-
private_subnets_nat_routed = [for type in local.private_subnet_names : type if can(var.subnets[type].connect_to_public_natgw)]
28+
private_subnets_nat_routed = [for type in local.private_subnet_names : type if try(var.subnets[type].connect_to_public_natgw == true, false)]
2929
# private subnets with cidrs per az if connect_to_public_natgw = true ... "privatetwo/us-east-1a"
3030
private_subnet_names_nat_routed = [for subnet in local.private_per_az : subnet if contains(local.private_subnets_nat_routed, split("/", subnet)[0])]
3131

@@ -42,16 +42,19 @@ locals {
4242
"single_az" = [local.azs[0]]
4343
"none" = [] # explicit "none" or omitted
4444
}
45+
nat_gateway_configuration = try(length(var.subnets.public.nat_gateway_configuration), 0) != 0 ? var.subnets.public.nat_gateway_configuration : "none"
46+
4547
# if public subnets being built, check how many nats to create
4648
# options defined by `local.nat_options`
4749
# nat_configuration is a list of az names where a nat should be created
48-
nat_configuration = contains(local.subnet_keys, "public") ? local.nat_options[try(var.subnets.public.nat_gateway_configuration, "none")] : local.nat_options["none"]
50+
nat_configuration = contains(local.subnet_keys, "public") ? local.nat_options[local.nat_gateway_configuration] : local.nat_options["none"]
4951

5052
# used to reference which nat gateway id should be used in route
5153
nat_per_az = (contains(local.subnet_keys, "public") && !var.vpc_secondary_cidr) ? (
5254
# map of az : { id = <nat-id> }, ex: { "us-east-1a" : { "id": "nat-123" }}
53-
{ for az in local.azs : az => { id : try(aws_nat_gateway.main[az].id, aws_nat_gateway.main[local.nat_configuration[0]].id) } }
54-
) : (
55+
{ for az in local.azs : az => {
56+
id : try(aws_nat_gateway.main[az].id, aws_nat_gateway.main[local.nat_configuration[0]].id) } if local.nat_gateway_configuration != "none"
57+
}) : (
5558
var.vpc_secondary_cidr ? var.vpc_secondary_cidr_natgw : {}
5659
)
5760

test/examples_nat_gw_routes_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/gruntwork-io/terratest/modules/terraform"
7+
)
8+
9+
10+
func TestExamplesNATGWRoutesNoNATGWNoRoute(t *testing.T) {
11+
12+
terraformOptions := &terraform.Options{
13+
TerraformDir: "./hcl_fixtures/nat_gw_routes",
14+
Vars: map[string]interface{}{
15+
"nat_gateway_configuration" : "none",
16+
"route_to_nw" : false,
17+
},
18+
}
19+
20+
defer terraform.Destroy(t, terraformOptions)
21+
terraform.InitAndApply(t, terraformOptions)
22+
terraform.ApplyAndIdempotent(t, terraformOptions)
23+
}
24+
25+
func TestExamplesNATGWRoutesSingleAZNATGWNoRoute(t *testing.T) {
26+
27+
terraformOptions := &terraform.Options{
28+
TerraformDir: "./hcl_fixtures/nat_gw_routes",
29+
Vars: map[string]interface{}{
30+
"nat_gateway_configuration" : "single_az",
31+
"route_to_nw" : false,
32+
},
33+
}
34+
35+
defer terraform.Destroy(t, terraformOptions)
36+
terraform.InitAndApply(t, terraformOptions)
37+
terraform.ApplyAndIdempotent(t, terraformOptions)
38+
}
39+
40+
func TestExamplesNATGWRoutesAllAZsNATGWNoRoute(t *testing.T) {
41+
42+
terraformOptions := &terraform.Options{
43+
TerraformDir: "./hcl_fixtures/nat_gw_routes",
44+
Vars: map[string]interface{}{
45+
"nat_gateway_configuration" : "all_azs",
46+
"route_to_nw" : false,
47+
},
48+
}
49+
50+
defer terraform.Destroy(t, terraformOptions)
51+
terraform.InitAndApply(t, terraformOptions)
52+
terraform.ApplyAndIdempotent(t, terraformOptions)
53+
}
54+
55+
func TestExamplesNATGWRoutesSingleAZNATGWWithRoute(t *testing.T) {
56+
57+
terraformOptions := &terraform.Options{
58+
TerraformDir: "./hcl_fixtures/nat_gw_routes",
59+
Vars: map[string]interface{}{
60+
"nat_gateway_configuration" : "single_az",
61+
"route_to_nw" : true,
62+
},
63+
}
64+
65+
defer terraform.Destroy(t, terraformOptions)
66+
terraform.InitAndApply(t, terraformOptions)
67+
terraform.ApplyAndIdempotent(t, terraformOptions)
68+
}
69+
70+
func TestExamplesNATGWRoutesAllAZsNATGWWithRoute(t *testing.T) {
71+
72+
terraformOptions := &terraform.Options{
73+
TerraformDir: "./hcl_fixtures/nat_gw_routes",
74+
Vars: map[string]interface{}{
75+
"nat_gateway_configuration" : "all_azs",
76+
"route_to_nw" : true,
77+
},
78+
}
79+
80+
defer terraform.Destroy(t, terraformOptions)
81+
terraform.InitAndApply(t, terraformOptions)
82+
terraform.ApplyAndIdempotent(t, terraformOptions)
83+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# NAT Gateway Options
2+
3+
This example builds a VPC with public and private subnets in 2 availability zones.
4+
It creates NAT GW in public subnet with either "none", "single_az" or "all_azs" option.
5+
It creates routes from private subnets to NAT GW if `connect_to_public_natgw` is true otherwise no route is created.
6+
It creates an internet gateway and appropriately routes subnet traffic from "0.0.0.0/0" to the IGW.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!-- BEGIN_TF_DOCS -->
2+
## Requirements
3+
4+
No requirements.
5+
6+
## Providers
7+
8+
No providers.
9+
10+
## Modules
11+
12+
| Name | Source | Version |
13+
|------|--------|---------|
14+
| <a name="module_nat_gw_vpc"></a> [nat\_gw\_vpc](#module\_nat\_gw\_vpc) | ../.. | n/a |
15+
16+
## Resources
17+
18+
No resources.
19+
20+
## Inputs
21+
22+
| Name | Description | Type | Default | Required |
23+
|------|-------------|------|---------|:--------:|
24+
| <a name="input_nat_gateway_configuration"></a> [nat\_gateway\_configuration](#input\_nat\_gateway\_configuration) | all\_azs, single\_az, or none | `string` | n/a | yes |
25+
| <a name="input_route_to_nw"></a> [route\_to\_nw](#input\_route\_to\_nw) | Should route to NATGW be created? | `bool` | n/a | yes |
26+
27+
## Outputs
28+
29+
| Name | Description |
30+
|------|-------------|
31+
| <a name="output_nat_gateway_attributes_by_az"></a> [nat\_gateway\_attributes\_by\_az](#output\_nat\_gateway\_attributes\_by\_az) | Map of nat gateway resource attributes by AZ. |
32+
| <a name="output_private_subnet_attributes_by_az"></a> [private\_subnet\_attributes\_by\_az](#output\_private\_subnet\_attributes\_by\_az) | Map of all private subnets containing their attributes. |
33+
| <a name="output_public_subnet_attributes_by_az"></a> [public\_subnet\_attributes\_by\_az](#output\_public\_subnet\_attributes\_by\_az) | Map of all public subnets containing their attributes. |
34+
| <a name="output_rt_attributes_by_type_by_az"></a> [rt\_attributes\_by\_type\_by\_az](#output\_rt\_attributes\_by\_type\_by\_az) | Map of route tables by type => az => route table attributes. |
35+
<!-- END_TF_DOCS -->
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
module "nat_gw_vpc" {
2+
source = "../../.."
3+
4+
name = "nat-gw-options-vpc"
5+
cidr_block = "10.51.0.0/16"
6+
az_count = 2
7+
8+
subnets = {
9+
10+
public = {
11+
name_prefix = "public" # omit to prefix with "public"
12+
netmask = 24
13+
nat_gateway_configuration = var.nat_gateway_configuration
14+
tags = {
15+
"tier" = "web"
16+
}
17+
}
18+
19+
app = {
20+
name_prefix = "app"
21+
netmask = 24
22+
connect_to_public_natgw = var.route_to_nw
23+
tags = {
24+
"tier" = "app"
25+
}
26+
}
27+
28+
db = {
29+
name_prefix = "db"
30+
netmask = 24
31+
connect_to_public_natgw = var.route_to_nw
32+
tags = {
33+
"tier" = "database"
34+
}
35+
}
36+
37+
}
38+
39+
tags = {
40+
"app" = "test"
41+
}
42+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
output "private_subnet_attributes_by_az" {
2+
description = "Map of all private subnets containing their attributes."
3+
value = module.nat_gw_vpc.private_subnet_attributes_by_az
4+
5+
}
6+
7+
output "public_subnet_attributes_by_az" {
8+
description = "Map of all public subnets containing their attributes."
9+
value = module.nat_gw_vpc.public_subnet_attributes_by_az
10+
11+
}
12+
13+
output "rt_attributes_by_type_by_az" {
14+
description = "Map of route tables by type => az => route table attributes."
15+
value = module.nat_gw_vpc.rt_attributes_by_type_by_az
16+
}
17+
18+
output "nat_gateway_attributes_by_az" {
19+
description = "Map of nat gateway resource attributes by AZ."
20+
value = module.nat_gw_vpc.nat_gateway_attributes_by_az
21+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
variable "nat_gateway_configuration" {
2+
description = "all_azs, single_az, or none"
3+
type = string
4+
}
5+
6+
variable "route_to_nw" {
7+
description = "Should route to NATGW be created?"
8+
type = bool
9+
}

0 commit comments

Comments
 (0)