Skip to content

Commit

Permalink
Merge pull request #86 from vivgoyal-aws/main
Browse files Browse the repository at this point in the history
Fix: support private only subnets (nat_gateway_configuration == "none" / null)
  • Loading branch information
troy-ameigh authored Sep 13, 2022
2 parents c60216f + a670299 commit 8ec1a1d
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 4 deletions.
11 changes: 7 additions & 4 deletions data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ locals {
# constructed list of <private_subnet_key>/az
private_per_az = flatten([for az in local.azs : [for subnet in local.private_subnet_names : "${subnet}/${az}"]])
# list of private subnet keys with connect_to_public_natgw = true
private_subnets_nat_routed = [for type in local.private_subnet_names : type if can(var.subnets[type].connect_to_public_natgw)]
private_subnets_nat_routed = [for type in local.private_subnet_names : type if try(var.subnets[type].connect_to_public_natgw == true, false)]
# private subnets with cidrs per az if connect_to_public_natgw = true ... "privatetwo/us-east-1a"
private_subnet_names_nat_routed = [for subnet in local.private_per_az : subnet if contains(local.private_subnets_nat_routed, split("/", subnet)[0])]

Expand All @@ -42,16 +42,19 @@ locals {
"single_az" = [local.azs[0]]
"none" = [] # explicit "none" or omitted
}
nat_gateway_configuration = try(length(var.subnets.public.nat_gateway_configuration), 0) != 0 ? var.subnets.public.nat_gateway_configuration : "none"

# if public subnets being built, check how many nats to create
# options defined by `local.nat_options`
# nat_configuration is a list of az names where a nat should be created
nat_configuration = contains(local.subnet_keys, "public") ? local.nat_options[try(var.subnets.public.nat_gateway_configuration, "none")] : local.nat_options["none"]
nat_configuration = contains(local.subnet_keys, "public") ? local.nat_options[local.nat_gateway_configuration] : local.nat_options["none"]

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

Expand Down
83 changes: 83 additions & 0 deletions test/examples_nat_gw_routes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package test

import (
"testing"

"github.com/gruntwork-io/terratest/modules/terraform"
)


func TestExamplesNATGWRoutesNoNATGWNoRoute(t *testing.T) {

terraformOptions := &terraform.Options{
TerraformDir: "./hcl_fixtures/nat_gw_routes",
Vars: map[string]interface{}{
"nat_gateway_configuration" : "none",
"route_to_nw" : false,
},
}

defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
terraform.ApplyAndIdempotent(t, terraformOptions)
}

func TestExamplesNATGWRoutesSingleAZNATGWNoRoute(t *testing.T) {

terraformOptions := &terraform.Options{
TerraformDir: "./hcl_fixtures/nat_gw_routes",
Vars: map[string]interface{}{
"nat_gateway_configuration" : "single_az",
"route_to_nw" : false,
},
}

defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
terraform.ApplyAndIdempotent(t, terraformOptions)
}

func TestExamplesNATGWRoutesAllAZsNATGWNoRoute(t *testing.T) {

terraformOptions := &terraform.Options{
TerraformDir: "./hcl_fixtures/nat_gw_routes",
Vars: map[string]interface{}{
"nat_gateway_configuration" : "all_azs",
"route_to_nw" : false,
},
}

defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
terraform.ApplyAndIdempotent(t, terraformOptions)
}

func TestExamplesNATGWRoutesSingleAZNATGWWithRoute(t *testing.T) {

terraformOptions := &terraform.Options{
TerraformDir: "./hcl_fixtures/nat_gw_routes",
Vars: map[string]interface{}{
"nat_gateway_configuration" : "single_az",
"route_to_nw" : true,
},
}

defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
terraform.ApplyAndIdempotent(t, terraformOptions)
}

func TestExamplesNATGWRoutesAllAZsNATGWWithRoute(t *testing.T) {

terraformOptions := &terraform.Options{
TerraformDir: "./hcl_fixtures/nat_gw_routes",
Vars: map[string]interface{}{
"nat_gateway_configuration" : "all_azs",
"route_to_nw" : true,
},
}

defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
terraform.ApplyAndIdempotent(t, terraformOptions)
}
6 changes: 6 additions & 0 deletions test/hcl_fixtures/nat_gw_routes/.header.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# NAT Gateway Options

This example builds a VPC with public and private subnets in 2 availability zones.
It creates NAT GW in public subnet with either "none", "single_az" or "all_azs" option.
It creates routes from private subnets to NAT GW if `connect_to_public_natgw` is true otherwise no route is created.
It creates an internet gateway and appropriately routes subnet traffic from "0.0.0.0/0" to the IGW.
35 changes: 35 additions & 0 deletions test/hcl_fixtures/nat_gw_routes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!-- BEGIN_TF_DOCS -->
## Requirements

No requirements.

## Providers

No providers.

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_nat_gw_vpc"></a> [nat\_gw\_vpc](#module\_nat\_gw\_vpc) | ../.. | n/a |

## Resources

No resources.

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_nat_gateway_configuration"></a> [nat\_gateway\_configuration](#input\_nat\_gateway\_configuration) | all\_azs, single\_az, or none | `string` | n/a | yes |
| <a name="input_route_to_nw"></a> [route\_to\_nw](#input\_route\_to\_nw) | Should route to NATGW be created? | `bool` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| <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. |
| <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. |
| <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. |
| <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. |
<!-- END_TF_DOCS -->
42 changes: 42 additions & 0 deletions test/hcl_fixtures/nat_gw_routes/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module "nat_gw_vpc" {
source = "../../.."

name = "nat-gw-options-vpc"
cidr_block = "10.51.0.0/16"
az_count = 2

subnets = {

public = {
name_prefix = "public" # omit to prefix with "public"
netmask = 24
nat_gateway_configuration = var.nat_gateway_configuration
tags = {
"tier" = "web"
}
}

app = {
name_prefix = "app"
netmask = 24
connect_to_public_natgw = var.route_to_nw
tags = {
"tier" = "app"
}
}

db = {
name_prefix = "db"
netmask = 24
connect_to_public_natgw = var.route_to_nw
tags = {
"tier" = "database"
}
}

}

tags = {
"app" = "test"
}
}
21 changes: 21 additions & 0 deletions test/hcl_fixtures/nat_gw_routes/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
output "private_subnet_attributes_by_az" {
description = "Map of all private subnets containing their attributes."
value = module.nat_gw_vpc.private_subnet_attributes_by_az

}

output "public_subnet_attributes_by_az" {
description = "Map of all public subnets containing their attributes."
value = module.nat_gw_vpc.public_subnet_attributes_by_az

}

output "rt_attributes_by_type_by_az" {
description = "Map of route tables by type => az => route table attributes."
value = module.nat_gw_vpc.rt_attributes_by_type_by_az
}

output "nat_gateway_attributes_by_az" {
description = "Map of nat gateway resource attributes by AZ."
value = module.nat_gw_vpc.nat_gateway_attributes_by_az
}
9 changes: 9 additions & 0 deletions test/hcl_fixtures/nat_gw_routes/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
variable "nat_gateway_configuration" {
description = "all_azs, single_az, or none"
type = string
}

variable "route_to_nw" {
description = "Should route to NATGW be created?"
type = bool
}

0 comments on commit 8ec1a1d

Please sign in to comment.