Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix nat_gateway_enabled=false Invalid index error #48

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/complete/fixtures.nat_gw_disabled.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nat_gateway_enabled = "false"
1 change: 1 addition & 0 deletions examples/complete/fixtures.nat_gw_enabled.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nat_gateway_enabled = "true"
2 changes: 1 addition & 1 deletion examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module "public_subnets" {
cidr_block = local.public_cidr_block
type = "public"
igw_id = module.vpc.igw_id
nat_gateway_enabled = true
nat_gateway_enabled = var.nat_gateway_enabled

context = module.this.context
}
Expand Down
4 changes: 4 additions & 0 deletions examples/complete/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ variable "availability_zones" {
type = list(string)
description = "List of Availability Zones (e.g. `['us-east-1a', 'us-east-1b', 'us-east-1c']`)"
}

variable "nat_gateway_enabled" {
description = "Flag to enable/disable NAT Gateways creation in public subnets"
}
13 changes: 9 additions & 4 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
locals {
enabled = module.this.enabled

public_enabled = local.enabled && var.type == "public"
private_enabled = local.enabled && var.type == "private"
availability_zones = local.enabled ? var.availability_zones : []
public_enabled = local.enabled && var.type == "public"
private_enabled = local.enabled && var.type == "private"
availability_zones = local.enabled ? var.availability_zones : []
nat_gateway_enabled = local.enabled && var.nat_gateway_enabled

output_map = { for az in(local.enabled ? var.availability_zones : []) : az => {
subnet_id = local.public_enabled ? aws_subnet.public[az].id : aws_subnet.private[az].id
subnet_arn = local.public_enabled ? aws_subnet.public[az].arn : aws_subnet.private[az].arn
route_table_id = local.public_enabled ? aws_route_table.public[az].id : aws_route_table.private[az].id
ngw_id = local.public_enabled ? aws_nat_gateway.public[az].id : null
}
}
# Only relevant for public subnets. Output is empty map for private subnets or when nat gateway is disabled
output_ngw_id = { for az in(local.public_enabled && local.nat_gateway_enabled ? var.availability_zones : []) : az => {
ngw_id = local.public_enabled ? try(aws_nat_gateway.public[az].id, null) : null
}
}
}
2 changes: 1 addition & 1 deletion outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ output "az_route_table_ids" {

output "az_ngw_ids" {
# No ellipsis needed since this module makes either public or private subnets. See the TF 0.15 one function
value = { for az, m in local.output_map : az => m.ngw_id }
value = { for az, m in local.output_ngw_id : az => m.ngw_id }
description = "Map of AZ names to NAT Gateway IDs (only for public subnets)"
}

Expand Down
5 changes: 3 additions & 2 deletions private.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
locals {
private_azs = local.private_enabled ? { for idx, az in var.availability_zones : az => idx } : {}
az_ngw_ids = local.nat_gateway_enabled ? var.az_ngw_ids : {}
}

module "private_label" {
Expand Down Expand Up @@ -90,10 +91,10 @@ resource "aws_route_table_association" "private" {
}

resource "aws_route" "default" {
for_each = local.private_azs
for_each = local.az_ngw_ids

route_table_id = aws_route_table.private[each.key].id
nat_gateway_id = var.az_ngw_ids[each.key]
nat_gateway_id = each.value
destination_cidr_block = "0.0.0.0/0"
depends_on = [aws_route_table.private]
}
33 changes: 31 additions & 2 deletions test/src/examples_complete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestExamplesComplete(t *testing.T) {
TerraformDir: "../../examples/complete",
Upgrade: true,
// Variables to pass to our Terraform code using -var-file options
VarFiles: []string{"fixtures.us-east-2.tfvars"},
VarFiles: []string{"fixtures.us-east-2.tfvars", "fixtures.nat_gw_enabled.tfvars"},
}

// At the end of the test, run `terraform destroy` to clean up any resources that were created
Expand Down Expand Up @@ -105,7 +105,7 @@ func TestExamplesCompleteDisabledModule(t *testing.T) {
TerraformDir: "../../examples/complete",
Upgrade: true,
// Variables to pass to our Terraform code using -var-file options
VarFiles: []string{"fixtures.us-east-2.tfvars", "fixtures.disabled.tfvars"},
VarFiles: []string{"fixtures.us-east-2.tfvars", "fixtures.nat_gw_enabled.tfvars", "fixtures.disabled.tfvars"},
}

// At the end of the test, run `terraform destroy` to clean up any resources that were created
Expand All @@ -128,3 +128,32 @@ func TestExamplesCompleteDisabledModule(t *testing.T) {
assert.Empty(t, publicSubnetIds)
assert.Empty(t, publicRouteTableIds)
}

func TestExamplesCompleteNoNatGateway(t *testing.T) {
// Init phase module download fails when run in parallel
//t.Parallel()

terraformOptions := &terraform.Options{
// The path to where our Terraform code is located
TerraformDir: "../../examples/complete",
Upgrade: true,
// Variables to pass to our Terraform code using -var-file options
VarFiles: []string{"fixtures.us-east-2.tfvars", "fixtures.nat_gw_disabled.tfvars"},
}

// At the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.Destroy(t, terraformOptions)

// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.InitAndApply(t, terraformOptions)

privateRouteTableIds := terraform.OutputMap(t, terraformOptions, "private_az_route_table_ids")
publicNATGateWayIds := terraform.OutputMap(t, terraformOptions, "public_az_ngw_ids")
privateNATGateWayIds := terraform.OutputMap(t, terraformOptions, "private_az_ngw_ids")

expectedAZs := []string{"us-east-2a", "us-east-2b", "us-east-2c"}
assert.Equal(t, expectedAZs, getKeys(privateRouteTableIds))
assertValueStartsWith(t, privateRouteTableIds, "^rtb-.*")
assert.Empty(t, publicNATGateWayIds)
assert.Empty(t, privateNATGateWayIds)
}