-
Notifications
You must be signed in to change notification settings - Fork 5
/
private_routing.tf
171 lines (131 loc) · 5.55 KB
/
private_routing.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# ---------------------------------------------------------------------------------------------------------------------
# CREATE PRIVATE ROUTING AND NAT GATEWAYS IF A PRIVATE SUBNETS IS DEFINED
# ---------------------------------------------------------------------------------------------------------------------
locals {
private_subnets = [for subnet in local.subnets : subnet if subnet.class == "private"]
private_group_azs = try(distinct(local.private_subnets.*.group_az), [])
public_azs = try(distinct(local.public_subnets.*.availability_zone), [])
private_azs = try(distinct(local.private_subnets.*.availability_zone), [])
private_groups = try(distinct(local.private_subnets.*.group), [])
private_subnets_by_group = {
for group in local.private_groups : group => [
for subnet in local.private_subnets : subnet if subnet.group == group
]
}
private_subnets_by_group_az = {
for group_az in local.private_group_azs : group_az => [
for subnet in local.private_subnets : subnet if subnet.group_az == group_az
]
}
public_subnets_by_az = {
for az in local.public_azs : az => [
for subnet in local.public_subnets : subnet if subnet.availability_zone == az
]
}
# hacky assertion
assert_each_private_subnet_has_a_public_in_same_az = {
for az in local.missing_public_subnet_azs[var.nat_gateway_mode] : "Missing public subnet in az" => local.public_subnets_by_az[az]
}
nat_gateway_single_zones = var.nat_gateway_single_mode_zone != null ? ["${local.region}${var.nat_gateway_single_mode_zone}"] : try([local.matching_azs[0]], [])
matching_azs = sort(setintersection(local.public_azs, local.private_azs))
nat_azs = {
one_per_az = local.matching_azs
single = local.nat_gateway_single_zones
none = []
}
nat_azs_set = toset(local.nat_azs[var.nat_gateway_mode])
create_eips = length(keys(var.nat_gateway_eip_allocation_ids)) == 0
missing_public_subnet_azs = {
one_per_az = sort(setsubtract(local.private_azs, local.public_azs))
single = length(local.matching_azs) == 0 ? sort(setsubtract(local.private_azs, local.public_azs)) : []
none = []
}
}
resource "aws_eip" "eip" {
for_each = var.module_enabled && local.create_eips ? local.nat_azs_set : []
vpc = true
tags = merge(
{
Name = "${var.vpc_name}-nat-private-${each.key}"
# special mineiros.io tags that can be used in data sources
"mineiros-io/aws/vpc/vpc-name" = var.vpc_name
"mineiros-io/aws/vpc/natgw-name" = "${var.vpc_name}-${each.key}"
"mineiros-io/aws/vpc/eip-name" = "${var.vpc_name}-nat-private-${each.key}"
},
var.module_tags,
var.eip_tags,
)
depends_on = [var.module_depends_on]
}
locals {
nat_gateway_eip_allocation_ids = { for k, v in var.nat_gateway_eip_allocation_ids : "${local.region}${k}" => v }
eip_allocation_ids = { for k, v in aws_eip.eip : k => v.id }
allocation_ids = local.create_eips ? local.eip_allocation_ids : local.nat_gateway_eip_allocation_ids
}
resource "aws_nat_gateway" "nat_gateway" {
for_each = var.module_enabled ? local.nat_azs_set : []
allocation_id = local.allocation_ids[each.key]
subnet_id = aws_subnet.subnet[local.public_subnets_by_az[each.key][0].cidr_block].id
tags = merge(
{
Name = "${var.vpc_name}-${each.key}"
# special mineiros.io tags that can be used in data sources
"mineiros-io/aws/vpc/vpc-name" = var.vpc_name
"mineiros-io/aws/vpc/natgw-name" = "${var.vpc_name}-${each.key}"
},
var.module_tags,
var.nat_gateway_tags,
)
depends_on = [var.module_depends_on]
}
resource "aws_route_table" "private" {
for_each = var.module_enabled ? local.private_subnets_by_group_az : {}
vpc_id = aws_vpc.vpc[0].id
# propagating_vgws = try(local.subnets[each.key].propagating_vgws, null)
tags = merge(
{
Name = "${var.vpc_name}-private-${each.key}"
# special mineiros.io tags that can be used in data sources
"mineiros-io/aws/vpc/vpc-name" = var.vpc_name
"mineiros-io/aws/vpc/routetable-name" = "${var.vpc_name}-private-${each.key}"
"mineiros-io/aws/vpc/routetable-class" = "private"
},
var.module_tags,
var.route_table_tags,
var.private_route_table_tags,
)
depends_on = [var.module_depends_on]
}
resource "aws_route_table_association" "private" {
for_each = var.module_enabled ? {
for subnet in flatten(values(local.private_subnets_by_group_az)) : subnet.cidr_block => subnet
} : {}
subnet_id = aws_subnet.subnet[each.key].id
route_table_id = aws_route_table.private[each.value.group_az].id
depends_on = [var.module_depends_on]
}
locals {
nat_routes = { for k, v in aws_route_table.private : "${var.nat_gateway_mode}/${k}" => v }
}
resource "aws_route" "nat_gateway" {
for_each = length(local.nat_azs_set) > 0 ? local.nat_routes : {}
route_table_id = each.value.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = try(
aws_nat_gateway.nat_gateway[local.private_subnets_by_group_az[each.key][0].availability_zone].id,
element(values(aws_nat_gateway.nat_gateway)[*].id, 0),
null,
)
# Workaround for https://github.com/terraform-providers/terraform-provider-aws/issues/338
timeouts {
create = "10m"
}
# we depend on nat gateways to be available for setting and updating routes
# the implicit dependency does not work, when changing nat gateway mode as we will
# only depend on the new gateway implictly and not on the one being removed.
# (e.g. when switching nat_gateway_mode)
depends_on = [
var.module_depends_on,
aws_nat_gateway.nat_gateway,
]
}