-
Notifications
You must be signed in to change notification settings - Fork 15
/
main.tf
353 lines (326 loc) · 17.8 KB
/
main.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# Managed By : CloudDrove
# Copyright @ CloudDrove. All Right Reserved.
##-----------------------------------------------------------------------------
## Locals declration to determine count of public subnet, private subnet, and nat gateway.
##-----------------------------------------------------------------------------
locals {
public_count = var.enable == true && (var.type == "public" || var.type == "public-private") ? length(var.availability_zones) : 0
private_count = var.enable == true && (var.type == "private" || var.type == "public-private") ? length(var.availability_zones) : 0
nat_gateway_count = var.enable == true && var.single_nat_gateway ? 1 : (var.enable == true && (var.type == "private" || var.type == "public-private") && var.nat_gateway_enabled == true ? length(var.availability_zones) : 0)
}
##-----------------------------------------------------------------------------
## Labels module called that will be used for naming and tags.
##-----------------------------------------------------------------------------
module "private-labels" {
source = "clouddrove/labels/aws"
version = "1.3.0"
name = var.name
repository = var.repository
environment = var.environment
managedby = var.managedby
label_order = var.label_order
attributes = compact(concat(var.attributes, ["private"]))
extra_tags = {
Type = "private"
}
}
module "public-labels" {
source = "clouddrove/labels/aws"
version = "1.3.0"
name = var.name
repository = var.repository
environment = var.environment
managedby = var.managedby
label_order = var.label_order
attributes = compact(concat(var.attributes, ["public"]))
extra_tags = {
Type = "public"
}
}
##-----------------------------------------------------------------------------
## Below resource will deploy public subnets and its related components in aws environment.
##-----------------------------------------------------------------------------
resource "aws_subnet" "public" {
count = local.public_count
vpc_id = var.vpc_id
availability_zone = element(var.availability_zones, count.index)
cidr_block = length(var.ipv4_public_cidrs) == 0 ? cidrsubnet(var.cidr_block, ceil(log(local.public_count * 2, 2)), local.public_count + count.index) : var.ipv4_public_cidrs[count.index]
ipv6_cidr_block = var.enable_ipv6 ? (length(var.public_ipv6_cidrs) == 0 ? cidrsubnet(var.ipv6_cidr_block, 8, count.index + 1) : var.public_ipv6_cidrs[count.index]) : null
map_public_ip_on_launch = var.map_public_ip_on_launch
assign_ipv6_address_on_creation = var.enable_ipv6 && var.public_subnet_ipv6_native ? true : var.public_subnet_assign_ipv6_address_on_creation
private_dns_hostname_type_on_launch = var.public_subnet_private_dns_hostname_type_on_launch
ipv6_native = var.enable_ipv6 && var.public_subnet_ipv6_native
enable_resource_name_dns_aaaa_record_on_launch = var.enable_ipv6 && var.public_subnet_enable_resource_name_dns_aaaa_record_on_launch
enable_resource_name_dns_a_record_on_launch = !var.public_subnet_ipv6_native && var.public_subnet_enable_resource_name_dns_a_record_on_launch
enable_dns64 = var.enable_ipv6 && var.public_subnet_enable_dns64
tags = merge(
module.public-labels.tags, var.extra_public_tags,
{
"Name" = format("%s%s%s", module.public-labels.id, var.delimiter, element(var.availability_zones, count.index))
"AZ" = element(var.availability_zones, count.index)
}
)
lifecycle {
# Ignore tags added by kubernetes
ignore_changes = [
tags["kubernetes.io"],
tags["SubnetType"],
]
}
}
##-----------------------------------------------------------------------------
## Below resource will deploy network acl and its rules that will be attached to public subnets.
##-----------------------------------------------------------------------------
resource "aws_network_acl" "public" {
count = var.enable && local.public_count > 0 && var.enable_public_acl && (var.type == "public" || var.type == "public-private") ? 1 : 0
vpc_id = var.vpc_id
subnet_ids = aws_subnet.public[*].id
tags = module.public-labels.tags
depends_on = [aws_subnet.public]
}
resource "aws_network_acl_rule" "public_inbound" {
count = var.enable && local.public_count > 0 && var.enable_public_acl && (var.type == "public" || var.type == "public-private") ? length(var.public_inbound_acl_rules) : 0
network_acl_id = aws_network_acl.public[0].id
egress = false
rule_number = var.public_inbound_acl_rules[count.index]["rule_number"]
rule_action = var.public_inbound_acl_rules[count.index]["rule_action"]
from_port = lookup(var.public_inbound_acl_rules[count.index], "from_port", null)
to_port = lookup(var.public_inbound_acl_rules[count.index], "to_port", null)
icmp_code = lookup(var.public_inbound_acl_rules[count.index], "icmp_code", null)
icmp_type = lookup(var.public_inbound_acl_rules[count.index], "icmp_type", null)
protocol = var.public_inbound_acl_rules[count.index]["protocol"]
cidr_block = lookup(var.public_inbound_acl_rules[count.index], "cidr_block", null)
ipv6_cidr_block = lookup(var.public_inbound_acl_rules[count.index], "ipv6_cidr_block", null)
}
resource "aws_network_acl_rule" "public_outbound" {
count = var.enable && local.public_count > 0 && var.enable_public_acl && (var.type == "public" || var.type == "public-private") ? length(var.public_outbound_acl_rules) : 0
network_acl_id = aws_network_acl.public[0].id
egress = true
rule_number = var.public_outbound_acl_rules[count.index]["rule_number"]
rule_action = var.public_outbound_acl_rules[count.index]["rule_action"]
from_port = lookup(var.public_outbound_acl_rules[count.index], "from_port", null)
to_port = lookup(var.public_outbound_acl_rules[count.index], "to_port", null)
icmp_code = lookup(var.public_outbound_acl_rules[count.index], "icmp_code", null)
icmp_type = lookup(var.public_outbound_acl_rules[count.index], "icmp_type", null)
protocol = var.public_outbound_acl_rules[count.index]["protocol"]
cidr_block = lookup(var.public_outbound_acl_rules[count.index], "cidr_block", null)
ipv6_cidr_block = lookup(var.public_outbound_acl_rules[count.index], "ipv6_cidr_block", null)
}
##-----------------------------------------------------------------------------
## Below resources will deploy route table and routes for public subnet and will be associated to public subnets.
##-----------------------------------------------------------------------------
resource "aws_route_table" "public" {
count = local.public_count
vpc_id = var.vpc_id
tags = merge(
module.public-labels.tags,
{
"Name" = format("%s%s%s-rt", module.public-labels.id, var.delimiter, element(var.availability_zones, count.index))
"AZ" = element(var.availability_zones, count.index)
}
)
}
resource "aws_route" "public" {
count = local.public_count
route_table_id = element(aws_route_table.public[*].id, count.index)
gateway_id = var.igw_id
destination_cidr_block = var.public_rt_ipv4_destination_cidr
depends_on = [aws_route_table.public]
timeouts {
create = "5m"
}
}
resource "aws_route" "public_ipv6" {
count = local.public_count
route_table_id = element(aws_route_table.public[*].id, count.index)
gateway_id = var.igw_id
destination_ipv6_cidr_block = var.public_rt_ipv6_destination_cidr
depends_on = [aws_route_table.public]
}
resource "aws_route_table_association" "public" {
count = local.public_count
subnet_id = element(aws_subnet.public[*].id, count.index)
route_table_id = element(aws_route_table.public[*].id, count.index)
depends_on = [
aws_subnet.public,
aws_route_table.public,
]
}
##-----------------------------------------------------------------------------
## Below resource will deploy flow logs for public subnet.
##-----------------------------------------------------------------------------
resource "aws_flow_log" "public_subnet_flow_log" {
count = var.enable && var.enable_flow_log && local.public_count > 0 ? 1 : 0
log_destination_type = var.flow_log_destination_type
log_destination = var.flow_log_destination_arn
log_format = var.flow_log_log_format
iam_role_arn = var.flow_log_iam_role_arn
traffic_type = var.flow_log_traffic_type
subnet_id = element(aws_subnet.public[*].id, count.index)
max_aggregation_interval = var.flow_log_max_aggregation_interval
dynamic "destination_options" {
for_each = var.flow_log_destination_type == "s3" ? [true] : []
content {
file_format = var.flow_log_file_format
hive_compatible_partitions = var.flow_log_hive_compatible_partitions
per_hour_partition = var.flow_log_per_hour_partition
}
}
tags = merge(
module.public-labels.tags,
{
"Name" = format("%s-flowlog", module.public-labels.name)
}
)
}
##-----------------------------------------------------------------------------
## Below resource will deploy private subnets and its related components in aws environment.
##-----------------------------------------------------------------------------
resource "aws_subnet" "private" {
count = local.private_count
vpc_id = var.vpc_id
availability_zone = element(var.availability_zones, count.index)
cidr_block = length(var.ipv4_private_cidrs) == 0 ? cidrsubnet(var.cidr_block, local.public_count == 0 ? ceil(log(local.private_count * 2, 2)) : ceil(log(local.public_count * 2, 2)), count.index) : var.ipv4_private_cidrs[count.index]
ipv6_cidr_block = var.enable_ipv6 ? (length(var.private_ipv6_cidrs) == 0 ? cidrsubnet(var.ipv6_cidr_block, 8, local.public_count + count.index + 1) : var.private_ipv6_cidrs[count.index]) : null
assign_ipv6_address_on_creation = var.enable_ipv6 && var.private_subnet_ipv6_native ? true : var.private_subnet_assign_ipv6_address_on_creation
private_dns_hostname_type_on_launch = var.private_subnet_private_dns_hostname_type_on_launch
ipv6_native = var.enable_ipv6 && var.private_subnet_ipv6_native
enable_resource_name_dns_aaaa_record_on_launch = var.enable_ipv6 && var.private_subnet_enable_resource_name_dns_aaaa_record_on_launch
enable_resource_name_dns_a_record_on_launch = !var.private_subnet_ipv6_native && var.private_subnet_enable_resource_name_dns_a_record_on_launch
enable_dns64 = var.enable_ipv6 && var.private_subnet_enable_dns64
tags = merge(
module.private-labels.tags, var.extra_private_tags,
{
"Name" = format("%s%s%s", module.private-labels.id, var.delimiter, element(var.availability_zones, count.index))
"AZ" = element(var.availability_zones, count.index)
}
)
lifecycle {
# Ignore tags added by kubernetes
ignore_changes = [
tags["kubernetes.io"],
tags["SubnetType"],
]
}
}
##-----------------------------------------------------------------------------
## Below resource will deploy network acl and its rules that will be attached to private subnets.
##-----------------------------------------------------------------------------
resource "aws_network_acl" "private" {
count = var.enable && var.enable_private_acl && (var.type == "private" || var.type == "public-private") ? 1 : 0
vpc_id = var.vpc_id
subnet_ids = aws_subnet.private[*].id
tags = module.private-labels.tags
depends_on = [aws_subnet.private]
}
resource "aws_network_acl_rule" "private_inbound" {
count = var.enable && var.enable_private_acl && (var.type == "private" || var.type == "public-private") ? length(var.private_inbound_acl_rules) : 0
network_acl_id = aws_network_acl.private[0].id
egress = false
rule_number = var.private_inbound_acl_rules[count.index]["rule_number"]
rule_action = var.private_inbound_acl_rules[count.index]["rule_action"]
from_port = lookup(var.private_inbound_acl_rules[count.index], "from_port", null)
to_port = lookup(var.private_inbound_acl_rules[count.index], "to_port", null)
icmp_code = lookup(var.private_inbound_acl_rules[count.index], "icmp_code", null)
icmp_type = lookup(var.private_inbound_acl_rules[count.index], "icmp_type", null)
protocol = var.private_inbound_acl_rules[count.index]["protocol"]
cidr_block = lookup(var.private_inbound_acl_rules[count.index], "cidr_block", null)
ipv6_cidr_block = lookup(var.private_inbound_acl_rules[count.index], "ipv6_cidr_block", null)
}
resource "aws_network_acl_rule" "private_outbound" {
count = var.enable && var.enable_private_acl && (var.type == "private" || var.type == "public-private") ? length(var.private_inbound_acl_rules) : 0
network_acl_id = aws_network_acl.private[0].id
egress = true
rule_number = var.private_outbound_acl_rules[count.index]["rule_number"]
rule_action = var.private_outbound_acl_rules[count.index]["rule_action"]
from_port = lookup(var.private_outbound_acl_rules[count.index], "from_port", null)
to_port = lookup(var.private_outbound_acl_rules[count.index], "to_port", null)
icmp_code = lookup(var.private_outbound_acl_rules[count.index], "icmp_code", null)
icmp_type = lookup(var.private_outbound_acl_rules[count.index], "icmp_type", null)
protocol = var.private_outbound_acl_rules[count.index]["protocol"]
cidr_block = lookup(var.private_outbound_acl_rules[count.index], "cidr_block", null)
ipv6_cidr_block = lookup(var.private_outbound_acl_rules[count.index], "ipv6_cidr_block", null)
}
##-----------------------------------------------------------------------------
## Below resources will deploy route table and routes for private subnet and will be associated to private subnets.
##-----------------------------------------------------------------------------
resource "aws_route_table" "private" {
count = local.private_count
vpc_id = var.vpc_id
tags = merge(
module.private-labels.tags,
{
"Name" = format("%s%s%s-rt", module.private-labels.id, var.delimiter, element(var.availability_zones, count.index))
"AZ" = element(var.availability_zones, count.index)
}
)
}
resource "aws_route_table_association" "private" {
count = local.private_count
subnet_id = element(aws_subnet.private[*].id, count.index)
route_table_id = element(aws_route_table.private[*].id, var.single_nat_gateway ? 0 : count.index, )
}
resource "aws_route" "nat_gateway" {
count = local.nat_gateway_count > 0 ? local.nat_gateway_count : 0
route_table_id = element(aws_route_table.private[*].id, count.index)
destination_cidr_block = var.nat_gateway_destination_cidr_block
nat_gateway_id = element(aws_nat_gateway.private[*].id, count.index)
depends_on = [aws_route_table.private]
}
##----------------------------------------------------------------------------------
## Below resource will create Elastic IP (EIP) for nat gateway.
##----------------------------------------------------------------------------------
resource "aws_eip" "private" {
count = local.nat_gateway_count
domain = "vpc"
tags = merge(
module.private-labels.tags,
{
"Name" = format("%s%s%s-eip", module.private-labels.id, var.delimiter, element(var.availability_zones, count.index))
}
)
lifecycle {
create_before_destroy = true
}
}
##----------------------------------------------------------------------------------
## Below resource will deploy nat gateway for private subnets.
##----------------------------------------------------------------------------------
resource "aws_nat_gateway" "private" {
count = local.nat_gateway_count
allocation_id = element(aws_eip.private[*].id, count.index)
subnet_id = length(aws_subnet.public) > 0 ? element(aws_subnet.public[*].id, count.index) : element(var.public_subnet_ids, count.index)
tags = merge(
module.private-labels.tags,
{
"Name" = format("%s%s%s-nat-gateway", module.private-labels.id, var.delimiter, element(var.availability_zones, count.index))
}
)
}
##-----------------------------------------------------------------------------
## Below resource will deploy flow logs for private subnet.
##-----------------------------------------------------------------------------
resource "aws_flow_log" "private_subnet_flow_log" {
count = var.enable && var.enable_flow_log && local.private_count > 0 ? 1 : 0
log_destination_type = var.flow_log_destination_type
log_destination = var.flow_log_destination_arn
log_format = var.flow_log_log_format
iam_role_arn = var.flow_log_iam_role_arn
traffic_type = var.flow_log_traffic_type
subnet_id = element(aws_subnet.private[*].id, count.index)
max_aggregation_interval = var.flow_log_max_aggregation_interval
dynamic "destination_options" {
for_each = var.flow_log_destination_type == "s3" ? [true] : []
content {
file_format = var.flow_log_file_format
hive_compatible_partitions = var.flow_log_hive_compatible_partitions
per_hour_partition = var.flow_log_per_hour_partition
}
}
tags = merge(
module.private-labels.tags,
{
"Name" = format("%s-flowlog", module.private-labels.name)
}
)
}