provider "aws" { region = "us-west-1" } locals { nat_gws_only_if_igw = {for k, v in local.subnets: k => [ for igw in aws_internet_gateway.gw-vpc: v if igw.tags.Name == "gw-${regex("^(.*).$",v.az)[0]}-${v.vpc_name}" // "gw-us-west-1-vpc1" ] } flattened_nat_gws_only_if_igw = {for k, v in local.nat_gws_only_if_igw: k => v[0] if can(v[0]) } vpcs = { vpc0 = { cidr_block = "10.0.0.0/16" }, vpc1 = { cidr_block = "10.1.0.0/16" create_igw = false } } subnets = { 0 = { vpc_name = "vpc0" az = "us-west-1a" name = "1A" public = "10.0.32.0/20" private = "10.0.0.0/19" } 1 = { vpc_name = "vpc0" az = "us-west-1b" name = "1B" public = "10.0.96.0/20" private = "10.0.64.0/19" } 2 = { vpc_name = "vpc1" az = "us-west-1a" name = "1A" public = "10.1.32.0/20" private = "10.1.0.0/19" } 3 = { vpc_name = "vpc1" az = "us-west-1b" name = "1B" public = "10.1.96.0/20" private = "10.1.64.0/19" } } created_private_subnets = { for v in aws_subnet.vpc-private: v.tags.Name => v } created_nat_gws = { for v in aws_nat_gateway.natgw-vpc: v.tags.Name => v } nat_gws = { us-west-1 = {for k, v in local.created_nat_gws: k=>v } } subnet_info = { us-west-1 = {for v in local.subnets: ("${v.vpc_name}-private-${v.name}") => { az = v.az short_name = v.name vpc_name = v.vpc_name } } } } resource aws_vpc the_vpcs { for_each = local.vpcs cidr_block = each.value.cidr_block instance_tenancy = "default" tags = { Name = "us-west-1-${each.key}" } } resource aws_internet_gateway gw-vpc { for_each = {for k, v in aws_vpc.the_vpcs: k=> v if try(local.vpcs[k].create_igw, true)==true} vpc_id = aws_vpc.the_vpcs[each.key].id tags = { Name = "gw-us-west-1-${each.key}" } } resource aws_eip natgw-eip-vpc { for_each = {for k, v in local.subnets: k=>v if try(local.vpcs[v.vpc_name].create_igw, true)==true} vpc = true tags = { Name = "${each.value.vpc_name}-nat-${each.value.az}" } } resource aws_nat_gateway natgw-vpc { for_each = local.flattened_nat_gws_only_if_igw allocation_id = aws_eip.natgw-eip-vpc[each.key].id subnet_id = aws_subnet.vpc-private[each.key].id tags = { Name = "${each.value.vpc_name}-natgw-${each.value.name}" } } resource aws_subnet vpc-private { for_each = local.subnets vpc_id = aws_vpc.the_vpcs[each.value.vpc_name].id availability_zone = local.subnets[each.key].az cidr_block = local.subnets[each.key].private tags = { Name = "${each.value.vpc_name}-private-${each.value.name}" } } resource aws_route_table the_private_route_table { for_each = {for k, v in local.created_private_subnets: k=>v if length(regexall("-private-", k))>0} vpc_id = each.value.vpc_id // default route dynamic route { for_each = {for k, v in local.nat_gws["us-west-1"]: k=>v if try(k == local.nat_gws["us-west-1"]["${local.subnet_info["us-west-1"][each.key].vpc_name}-natgw-${local.subnet_info["us-west-1"][each.key].short_name}"].tags.Name, false)!=false} content { cidr_block = "0.0.0.0/0" nat_gateway_id = local.nat_gws["us-west-1"]["${local.subnet_info["us-west-1"][each.key].vpc_name}-natgw-${local.subnet_info["us-west-1"][each.key].short_name}"].id } } } resource aws_route_table_association src-ra-vpc-private { for_each = {for k, v in aws_route_table.the_private_route_table: k=>v} subnet_id = local.created_private_subnets[each.key].id route_table_id = each.value.id } output test { value = local.nat_gws["us-west-1"] } output test2 { value = { private_subnets = local.created_private_subnets routes = aws_route_table.the_private_route_table subnet_info = local.subnet_info } } output test3 { value = {for key, val in local.created_private_subnets: key=> {for k, v in local.nat_gws["us-west-1"]: k=>v if can(local.nat_gws["us-west-1"]["${local.subnet_info["us-west-1"][key].vpc_name}-natgw-${local.subnet_info["us-west-1"][key].short_name}"].tags) && k == local.nat_gws["us-west-1"]["${local.subnet_info["us-west-1"][key].vpc_name}-natgw-${local.subnet_info["us-west-1"][key].short_name}"].tags.Name } if length(regexall("-private-", key))>0 && try(key==local.nat_gws["us-west-1"]["${local.subnet_info["us-west-1"][key].vpc_name}-natgw-${local.subnet_info["us-west-1"][key].short_name}"].tags.Name, false)!=false } }